Merge pull request #806 from AxlPr/master
authorZoltan Varga <vargaz@gmail.com>
Thu, 12 Dec 2013 21:51:14 +0000 (13:51 -0800)
committerZoltan Varga <vargaz@gmail.com>
Thu, 12 Dec 2013 21:51:14 +0000 (13:51 -0800)
Fixed  g_win32_getlocale

545 files changed:
LICENSE
Makefile.am
README [deleted file]
README.md [new file with mode: 0644]
autogen.sh
configure.in
data/lock-decoder/LockTracerDecoder.cs
eglib/test/sizes.c
external/ikvm
libgc/darwin_stop_world.c
libgc/include/Makefile.am
libgc/include/libgc-mono-debugger.h [deleted file]
libgc/pthread_stop_world.c
libgc/pthread_support.c
man/mono.1
mcs/class/Facades/Makefile
mcs/class/Facades/System.Dynamic.Runtime/TypeForwarders.cs
mcs/class/Facades/System.Linq.Expressions/TypeForwarders.cs
mcs/class/Facades/System.Reflection.Primitives/TypeForwarders.cs
mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/AssemblyInfo.cs [new file with mode: 0644]
mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/Makefile [new file with mode: 0644]
mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/System.Runtime.InteropServices.WindowsRuntime.dll.sources [new file with mode: 0644]
mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/TypeForwarders.cs [new file with mode: 0644]
mcs/class/Facades/System.Runtime.InteropServices/TypeForwarders.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildItem.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildProperty.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildPropertyGroup.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/BuildTaskPropertyGroup.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ColorResetter.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ColorSetter.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/FileLogger.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/Target.cs
mcs/class/Microsoft.Build.Engine/Microsoft.Build.BuildEngine/WriteHandler.cs
mcs/class/Microsoft.Build.Engine/Test/Microsoft.Build.BuildEngine/TargetTest.cs
mcs/class/Microsoft.Build.Engine/Test/resources/TestReturns.csproj [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework.dll.sources
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEngineResult.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEventArgs.cs
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEventContext.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine3.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine4.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IEventRedirector.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IForwardingLogger.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskFactory.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskFactory2.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/RegisteredTaskObjectLifetime.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/TaskPropertyInfo.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework_test.dll.sources
mcs/class/Microsoft.Build.Framework/Test/Microsoft.Build.Framework/BuildEventContextTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TaskBatchingTest.cs
mcs/class/Microsoft.Build.Tasks/Test/Microsoft.Build.Tasks/TestMessageLogger.cs
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/TaskItem.cs
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs
mcs/class/Microsoft.Build/.gitignore
mcs/class/Microsoft.Build/Makefile
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ElementLocation.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectChooseElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectCommentElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectElementContainer.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectExtensionsElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectImportElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectImportGroupElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectItemDefinitionElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectItemDefinitionGroupElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectItemElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectItemGroupElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectOnErrorElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectOtherwiseElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectOutputElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectPropertyGroupElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectRootElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectTargetElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectTaskElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectUsingTaskBodyElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectUsingTaskElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/ProjectWhenElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Construction/UsingTaskParameterGroupElement.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/Project.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectChangedEventArgs.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollection.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollectionChangedEventArgs.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollectionChangedState.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectItem.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectItemDefinition.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectMetadata.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectProperty.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectXmlChangedEventArgs.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ResolvedImport.cs
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/SubToolset.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/Toolset.cs
mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/BuildAbortedException.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InternalLoggerException.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InvalidProjectFileException.cs
mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InvalidToolsetDefinitionException.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildManager.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildParameters.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildRequestData.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildResult.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildSubmission.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildSubmissionCompleteCallback.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/HostServices.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/NodeEngineShutdownReason.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/OutOfProcNode.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemDefinitionInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskItemInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskMetadataInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectMetadataInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectOnErrorInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyGroupTaskInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyGroupTaskPropertyInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTargetInstance.cs
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTargetInstanceChild.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskInstanceChild.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskOutputItemInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskOutputPropertyInstance.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Execution/TargetResult.cs
mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildEngine4.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildNodeManager.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildTaskDatabase.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildTaskFactory.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionConstructs.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionEvaluator.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/ProjectTaskItem.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Internal/WindowsCompatibilityExtensions.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Logging/ConfigurableForwardingLogger.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Logging/DistributedFileLogger.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Microsoft.Build.Logging/LoggerDescription.cs
mcs/class/Microsoft.Build/Microsoft.Build.dll.sources
mcs/class/Microsoft.Build/Microsoft.Build_test.dll.sources
mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectItemElementTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectRootElementTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectCollectionTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectItemDefinitionTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectItemTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectPropertyTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ResolvedImportTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ToolsetTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildManagerTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildParametersTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildSubmissionTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectInstanceTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectMetadataInstanceTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectTargetInstanceTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/Test/Microsoft.Build.Logging/ConsoleLoggerTest.cs
mcs/class/Microsoft.Build/Test/Microsoft.Build.Logging/LoggerDescriptionTest.cs [new file with mode: 0644]
mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v2.0/RedistList/FrameworkList.xml [new file with mode: 0644]
mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v3.5/RedistList/FrameworkList.xml [new file with mode: 0644]
mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v4.0/RedistList/FrameworkList.xml [new file with mode: 0644]
mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v4.5/RedistList/FrameworkList.xml [new file with mode: 0644]
mcs/class/Mono.CSharp/Test/Evaluator/ExpressionsTest.cs
mcs/class/Mono.Data.Sqlite/Assembly/AssemblyInfo.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/Connection.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/StepEventRequest.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/TypeMirror.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VMDeathEvent.cs
mcs/class/Mono.Debugger.Soft/Mono.Debugger.Soft/VirtualMachine.cs
mcs/class/Mono.Debugger.Soft/Test/dtest-app.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/Mono.Options/Mono.Options/Options.cs
mcs/class/Mono.Options/Test/Mono.Options/OptionSetTest.cs
mcs/class/PEAPI/PEAPI.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/FilterUIHintAttributeTest.cs
mcs/class/System.ComponentModel.DataAnnotations/Test/System.ComponentModel.DataAnnotations/UIHintAttributeTest.cs
mcs/class/System.Configuration/Test/System.Configuration/ConfigurationManagerTest.cs
mcs/class/System.Core/System.Linq.Expressions/DynamicExpressionVisitor.cs [new file with mode: 0644]
mcs/class/System.Core/System.Linq.Expressions/Expression.cs
mcs/class/System.Core/System.Linq/Enumerable.cs
mcs/class/System.Core/System/TimeZoneInfo.Android.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs
mcs/class/System.Core/Test/System.Linq/EnumerableFixture.cs
mcs/class/System.Core/Test/System.Linq/EnumerableMoreTest.cs
mcs/class/System.Core/dynamic_System.Core.dll.sources
mcs/class/System.Core/net_4_5_System.Core.dll.sources
mcs/class/System.Data/System.Data.SqlClient/SqlCommand.cs
mcs/class/System.Drawing/Test/System.Drawing/TestFont.cs
mcs/class/System.Net.Http/System.Net.Http.Headers/HttpHeaders.cs
mcs/class/System.Net.Http/System.Net.Http.Headers/Parser.cs
mcs/class/System.Net.Http/Test/System.Net.Http.Headers/HttpHeadersTest.cs
mcs/class/System.Numerics/System.Numerics/BigInteger.cs
mcs/class/System.Numerics/Test/System.Numerics/BigIntegerTest.cs
mcs/class/System.XML/Test/System.Xml.Serialization/XmlSerializationWriterTests.cs
mcs/class/System/System.Collections.Concurrent/ConcurrentBag.cs
mcs/class/System/System.ComponentModel/Component.cs
mcs/class/System/System.Configuration/SettingValueElement.cs
mcs/class/System/System.Diagnostics/Process.cs
mcs/class/System/System.Net/HttpWebRequest.cs
mcs/class/System/System.Net/ServicePointManager.cs
mcs/class/System/System.Net/TransportContext.cs
mcs/class/System/System.Net/WebConnection.cs
mcs/class/System/System.Timers/Timer.cs
mcs/class/System/Test/System.Collections.Concurrent/ConcurrentBagTests.cs
mcs/class/System/Test/System.Net.Sockets/SocketTest.cs [changed mode: 0644->0755]
mcs/class/System/mobile_System.dll.sources
mcs/class/WindowsBase/System.Windows/PointConverter.cs
mcs/class/corlib/Makefile
mcs/class/corlib/System.Collections.Concurrent/ConcurrentDictionary.cs
mcs/class/corlib/System.Collections.Generic/List.cs
mcs/class/corlib/System.Diagnostics/DebuggerTypeProxyAttribute.cs
mcs/class/corlib/System.Globalization/CultureInfo.cs
mcs/class/corlib/System.Globalization/RegionInfo.cs
mcs/class/corlib/System.Globalization/TextInfo.cs
mcs/class/corlib/System.Reflection/MonoProperty.cs
mcs/class/corlib/System.Runtime.CompilerServices/AsyncTaskMethodBuilder.cs
mcs/class/corlib/System.Runtime.CompilerServices/AsyncTaskMethodBuilder_T.cs
mcs/class/corlib/System.Runtime.CompilerServices/ConfiguredTaskAwaitable.cs
mcs/class/corlib/System.Runtime.CompilerServices/ConfiguredTaskAwaitable_T.cs
mcs/class/corlib/System.Runtime.CompilerServices/TaskAwaiter.cs
mcs/class/corlib/System.Runtime.CompilerServices/TaskAwaiter_T.cs
mcs/class/corlib/System.Runtime.CompilerServices/YieldAwaitable.cs
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/DefaultInterfaceAttribute.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/DesignerNamespaceResolveEventArgs.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/EventRegistrationToken.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/EventRegistrationTokenTable.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/IActivationFactory.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/InterfaceImplementedInVersionAttribute.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/NamespaceResolveEventArgs.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/ReadOnlyArrayAttribute.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/ReturnValueNameAttribute.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMarshal.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMetadata.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WriteOnlyArrayAttribute.cs [new file with mode: 0644]
mcs/class/corlib/System.Runtime.Remoting.Messaging/CallContext.cs
mcs/class/corlib/System.Runtime.Remoting.Proxies/RealProxy.cs
mcs/class/corlib/System.Runtime.Remoting/RemotingServices.cs
mcs/class/corlib/System.Threading.Tasks/Task.cs
mcs/class/corlib/System.Threading.Tasks/TaskCompletionSource.cs
mcs/class/corlib/System.Threading.Tasks/TaskContinuation.cs
mcs/class/corlib/System.Threading.Tasks/TaskFactory.cs
mcs/class/corlib/System.Threading/SemaphoreSlim.cs
mcs/class/corlib/System.Threading/Thread.cs
mcs/class/corlib/System/ArraySegment.cs
mcs/class/corlib/System/Attribute.cs
mcs/class/corlib/System/ConsoleKeyInfo.cs
mcs/class/corlib/System/Delegate.cs
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/System/NumberFormatter.cs
mcs/class/corlib/System/String.cs
mcs/class/corlib/System/TimeZone.cs
mcs/class/corlib/Test/Microsoft.Win32/RegistryKeyTest.cs [changed mode: 0644->0755]
mcs/class/corlib/Test/System.Collections.Generic/ListTest.cs
mcs/class/corlib/Test/System.Diagnostics/DebuggerDisplayAttributeTest.cs
mcs/class/corlib/Test/System.Diagnostics/DebuggerTypeProxyAttribute.cs [new file with mode: 0644]
mcs/class/corlib/Test/System.Diagnostics/StackFrameTest.cs
mcs/class/corlib/Test/System.Globalization/CultureInfoTest.cs
mcs/class/corlib/Test/System.Globalization/NumberFormatInfoTest.cs [new file with mode: 0644]
mcs/class/corlib/Test/System.Globalization/TextInfoTest.cs
mcs/class/corlib/Test/System.Reflection.Emit/TypeBuilderTest.cs
mcs/class/corlib/Test/System.Runtime.CompilerServices/TaskAwaiterTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskFactoryTest_T.cs
mcs/class/corlib/Test/System.Threading.Tasks/TaskTest.cs
mcs/class/corlib/Test/System.Threading/AutoResetEventTest.cs
mcs/class/corlib/Test/System.Threading/ExecutionContextTest.cs
mcs/class/corlib/Test/System/AppDomainTest.cs
mcs/class/corlib/Test/System/ArraySegmentTest.cs
mcs/class/corlib/Test/System/AttributeTest.cs
mcs/class/corlib/Test/System/TimeZoneTest.cs
mcs/class/corlib/Test/System/TypeTest.cs
mcs/class/corlib/corlib.dll.sources
mcs/class/corlib/corlib_test.dll.sources
mcs/class/monodoc/Monodoc/generators/html/Man2Html.cs
mcs/class/monodoc/Resources/ecmaspec.css
mcs/errors/CS0246-29-lib.il [new file with mode: 0644]
mcs/errors/CS0731-1-lib.il [new file with mode: 0644]
mcs/errors/CS0731-2-lib.il [new file with mode: 0644]
mcs/errors/CS1070-lib.il
mcs/errors/Makefile
mcs/errors/cs0035-2.cs [new file with mode: 0644]
mcs/errors/cs0103-12.cs [new file with mode: 0644]
mcs/errors/cs0104-3.cs [new file with mode: 0644]
mcs/errors/cs0104-4.cs [new file with mode: 0644]
mcs/errors/cs0126-2.cs [new file with mode: 0644]
mcs/errors/cs0161-4.cs [deleted file]
mcs/errors/cs0162-17.cs [deleted file]
mcs/errors/cs0162-20.cs [new file with mode: 0644]
mcs/errors/cs0162-7.cs
mcs/errors/cs0163-2.cs [new file with mode: 0644]
mcs/errors/cs0163.cs
mcs/errors/cs0165-22.cs [new file with mode: 0644]
mcs/errors/cs0165-23.cs [new file with mode: 0644]
mcs/errors/cs0165-24.cs [new file with mode: 0644]
mcs/errors/cs0165-25.cs [new file with mode: 0644]
mcs/errors/cs0165-26.cs [new file with mode: 0644]
mcs/errors/cs0165-27.cs [new file with mode: 0644]
mcs/errors/cs0165-28.cs [new file with mode: 0644]
mcs/errors/cs0165-29.cs [new file with mode: 0644]
mcs/errors/cs0165-30.cs [new file with mode: 0644]
mcs/errors/cs0165-31.cs [new file with mode: 0644]
mcs/errors/cs0165-32.cs [new file with mode: 0644]
mcs/errors/cs0165-33.cs [new file with mode: 0644]
mcs/errors/cs0165-34.cs [new file with mode: 0644]
mcs/errors/cs0165-35.cs [new file with mode: 0644]
mcs/errors/cs0165-36.cs [new file with mode: 0644]
mcs/errors/cs0165-37.cs [new file with mode: 0644]
mcs/errors/cs0165-38.cs [new file with mode: 0644]
mcs/errors/cs0165-39.cs [new file with mode: 0644]
mcs/errors/cs0165-40.cs [new file with mode: 0644]
mcs/errors/cs0165-41.cs [new file with mode: 0644]
mcs/errors/cs0165-42.cs [new file with mode: 0644]
mcs/errors/cs0165-43.cs [new file with mode: 0644]
mcs/errors/cs0171-6.cs [new file with mode: 0644]
mcs/errors/cs0177-14.cs [new file with mode: 0644]
mcs/errors/cs0201-10.cs [new file with mode: 0644]
mcs/errors/cs0201-11.cs [new file with mode: 0644]
mcs/errors/cs0246-29.cs [new file with mode: 0644]
mcs/errors/cs0411-15.cs [deleted file]
mcs/errors/cs0411-6.cs [deleted file]
mcs/errors/cs0411-7.cs [deleted file]
mcs/errors/cs0429-4.cs [new file with mode: 0644]
mcs/errors/cs0534-11.cs [new file with mode: 0644]
mcs/errors/cs0540-3.cs [new file with mode: 0644]
mcs/errors/cs0731.cs [new file with mode: 0644]
mcs/errors/cs1061-14.cs [new file with mode: 0644]
mcs/errors/cs1070-2.cs [new file with mode: 0644]
mcs/errors/cs1503-14.cs [new file with mode: 0644]
mcs/errors/cs1503-15.cs [new file with mode: 0644]
mcs/errors/cs1503-16.cs [new file with mode: 0644]
mcs/errors/cs1632-2.cs [new file with mode: 0644]
mcs/errors/cs1632-3.cs [new file with mode: 0644]
mcs/errors/cs1632-4.cs [new file with mode: 0644]
mcs/errors/cs1654-3.cs [new file with mode: 0644]
mcs/errors/cs1654-4.cs [new file with mode: 0644]
mcs/errors/known-issues-net_4_5
mcs/ilasm/codegen/ExternTable.cs
mcs/ilasm/parser/ILParser.jay
mcs/mcs/anonymous.cs
mcs/mcs/argument.cs
mcs/mcs/assign.cs
mcs/mcs/async.cs
mcs/mcs/attribute.cs
mcs/mcs/class.cs
mcs/mcs/codegen.cs
mcs/mcs/complete.cs
mcs/mcs/context.cs
mcs/mcs/cs-parser.jay
mcs/mcs/cs-tokenizer.cs
mcs/mcs/delegate.cs
mcs/mcs/driver.cs
mcs/mcs/dynamic.cs
mcs/mcs/ecore.cs
mcs/mcs/eval.cs
mcs/mcs/expression.cs
mcs/mcs/flowanalysis.cs
mcs/mcs/generic.cs
mcs/mcs/ikvm.cs
mcs/mcs/import.cs
mcs/mcs/iterators.cs
mcs/mcs/linq.cs
mcs/mcs/method.cs
mcs/mcs/namespace.cs
mcs/mcs/nullable.cs
mcs/mcs/statement.cs
mcs/mcs/typespec.cs
mcs/tests/dtest-059.cs [new file with mode: 0644]
mcs/tests/gtest-600.cs [new file with mode: 0644]
mcs/tests/test-154.cs
mcs/tests/test-519.cs
mcs/tests/test-579.cs
mcs/tests/test-872.cs [new file with mode: 0644]
mcs/tests/test-874.cs [new file with mode: 0644]
mcs/tests/test-875-2-lib.il [new file with mode: 0644]
mcs/tests/test-875-lib.cs [new file with mode: 0644]
mcs/tests/test-875.cs [new file with mode: 0644]
mcs/tests/test-876.cs [new file with mode: 0644]
mcs/tests/test-877.cs [new file with mode: 0644]
mcs/tests/test-878.cs [new file with mode: 0644]
mcs/tests/test-879.cs [new file with mode: 0644]
mcs/tests/test-880.cs [new file with mode: 0644]
mcs/tests/test-881.cs [new file with mode: 0644]
mcs/tests/test-882.cs [new file with mode: 0644]
mcs/tests/test-async-40.cs
mcs/tests/test-async-53.cs [new file with mode: 0644]
mcs/tests/test-async-54.cs [new file with mode: 0644]
mcs/tests/test-xml-068-ref.xml [new file with mode: 0644]
mcs/tests/test-xml-068.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_5.xml
mcs/tools/cil-strip/Mono.Cecil.Cil/CodeReader.cs
mcs/tools/cil-strip/cil-strip.csproj [new file with mode: 0644]
mcs/tools/linker/Descriptors/mscorlib.xml
mcs/tools/linker/Mono.Linker.Steps/MarkStep.cs
mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs
mcs/tools/mdoc/Test/en.expected.delete/Mono.DocTest.Generic/GenericBase`1.xml
mcs/tools/mdoc/Test/en.expected.delete/Mono.DocTest/Widget.xml
mcs/tools/mdoc/Test/en.expected.importslashdoc/Mono.DocTest.Generic/GenericBase`1.xml
mcs/tools/mdoc/Test/en.expected.importslashdoc/Mono.DocTest/Widget.xml
mcs/tools/mdoc/Test/en.expected.since/Mono.DocTest.Generic/GenericBase`1.xml
mcs/tools/mdoc/Test/en.expected.since/Mono.DocTest/Widget.xml
mcs/tools/mdoc/Test/en.expected/Mono.DocTest.Generic/GenericBase`1.xml
mcs/tools/mdoc/Test/en.expected/Mono.DocTest/Widget.xml
mcs/tools/mdoc/Test/msxdoc-expected.importslashdoc.xml
mcs/tools/mkbundle/mkbundle.cs
mcs/tools/monop/monop.cs
mcs/tools/tuner/Mono.Tuner/Dispatcher.cs
mcs/tools/tuner/Mono.Tuner/RemoveResources.cs
mcs/tools/xbuild/xbuild/2.0/Microsoft.Common.targets
mcs/tools/xbuild/xbuild/3.5/Microsoft.Common.targets
mcs/tools/xbuild/xbuild/4.0/Microsoft.Common.targets
mono-core.spec.in
mono/arch/amd64/amd64-codegen.h
mono/arch/mips/mips-codegen.h
mono/arch/x86/x86-codegen.h
mono/io-layer/processes.c
mono/io-layer/sockets.c
mono/metadata/Makefile.am.in
mono/metadata/appdomain.c
mono/metadata/assembly.c
mono/metadata/boehm-gc.c
mono/metadata/class.c
mono/metadata/cominterop.c
mono/metadata/culture-info-tables.h
mono/metadata/domain-internals.h
mono/metadata/gc-memfuncs.c [new file with mode: 0644]
mono/metadata/gc.c
mono/metadata/icall-def.h
mono/metadata/icall.c
mono/metadata/image.c
mono/metadata/loader.c
mono/metadata/locales.c
mono/metadata/locales.h
mono/metadata/lock-tracer.c
mono/metadata/lock-tracer.h
mono/metadata/marshal.c
mono/metadata/metadata-internals.h
mono/metadata/metadata.c
mono/metadata/method-builder.c
mono/metadata/mono-debug-debugger.c
mono/metadata/mono-debug-debugger.h
mono/metadata/mono-debug.c
mono/metadata/mono-debug.h
mono/metadata/object.c
mono/metadata/reflection.c
mono/metadata/sgen-alloc.c
mono/metadata/sgen-archdep.h
mono/metadata/sgen-bridge.c
mono/metadata/sgen-debug.c
mono/metadata/sgen-descriptor.h
mono/metadata/sgen-gc.c
mono/metadata/sgen-gc.h
mono/metadata/sgen-los.c
mono/metadata/sgen-marksweep.c
mono/metadata/sgen-memory-governor.c
mono/metadata/sgen-nursery-allocator.c
mono/metadata/sgen-os-mach.c
mono/metadata/sgen-os-win32.c
mono/metadata/sgen-protocol.c
mono/metadata/sgen-qsort.c [new file with mode: 0644]
mono/metadata/sgen-stw.c
mono/metadata/socket-io.c
mono/metadata/test-gc-memfuncs.c [new file with mode: 0644]
mono/metadata/test-sgen-qsort.c [new file with mode: 0644]
mono/metadata/threads.c
mono/mini/.gitignore
mono/mini/Makefile.am.in
mono/mini/abcremoval.c
mono/mini/alias-analysis.c [new file with mode: 0644]
mono/mini/aot-compiler.c
mono/mini/aot-runtime.c
mono/mini/arrays.cs
mono/mini/basic-float.cs
mono/mini/cpu-amd64.md
mono/mini/cpu-mips.md
mono/mini/cpu-x86.md
mono/mini/debug-debugger.c [deleted file]
mono/mini/debug-debugger.h [deleted file]
mono/mini/debug-mini.c
mono/mini/debug-mini.h [deleted file]
mono/mini/debugger-agent.c
mono/mini/decompose.c
mono/mini/driver.c
mono/mini/dwarfwriter.c
mono/mini/exceptions-amd64.c
mono/mini/exceptions-arm.c
mono/mini/exceptions-x86.c
mono/mini/exceptions.cs
mono/mini/graph.c
mono/mini/iltests.il.in
mono/mini/image-writer.c
mono/mini/ir-emit.h
mono/mini/liveness.c
mono/mini/mdb-debug-info32-darwin.s [deleted file]
mono/mini/mdb-debug-info32.s [deleted file]
mono/mini/mdb-debug-info64.s [deleted file]
mono/mini/method-to-ir.c
mono/mini/mini-amd64.c
mono/mini/mini-amd64.h
mono/mini/mini-arm.c
mono/mini/mini-arm.h
mono/mini/mini-codegen.c
mono/mini/mini-exceptions.c
mono/mini/mini-ia64.c
mono/mini/mini-llvm-cpp.cpp
mono/mini/mini-llvm.c
mono/mini/mini-mips.c
mono/mini/mini-ops.h
mono/mini/mini-ppc.c
mono/mini/mini-ppc.h
mono/mini/mini-s390x.c
mono/mini/mini-sparc.c
mono/mini/mini-trampolines.c
mono/mini/mini-unwind.h
mono/mini/mini-x86.c
mono/mini/mini-x86.h
mono/mini/mini.c
mono/mini/mini.h
mono/mini/optflags-def.h
mono/mini/patch-info.h
mono/mini/ssa.c
mono/mini/tasklets.c
mono/mini/trace.c
mono/mini/tramp-amd64.c
mono/mini/tramp-arm.c
mono/mini/tramp-ppc.c
mono/mini/tramp-s390x.c
mono/mini/unwind.c
mono/monograph/Makefile.am
mono/tests/finalizer-exception.cs
mono/utils/Makefile.am
mono/utils/mach-support-arm.c
mono/utils/mono-hwcap-arm.c
mono/utils/mono-hwcap-arm.h
mono/utils/mono-proclib.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h
mono/utils/mono-tls.c
msvc/libmono.vcxproj
msvc/libmonoruntime.vcxproj
msvc/libmonoutils.vcxproj
tools/locale-builder/CultureInfoEntry.cs
tools/locale-builder/Driver.cs
tools/locale-builder/Patterns.cs
tools/sgen/sgen-grep-binprot.c
winconfig.h

diff --git a/LICENSE b/LICENSE
index 19ed03acc968af23c3286bfdfc912c29babce367..be4be30323b480b0c553d3c4b5d91adecd2411cd 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -64,13 +64,6 @@ For comments, corrections and updates, please contact mono@xamarin.com
        the terms of the MIT X11, this means that this code can be
        used for any purposes by anyone.
 
-** mono/metadata/sgen*: Mono's Copying Collector
-
-       This new garbage collector is licensed under the terms of
-       the MIT X11 license, in hopes that the GC could be reused
-       by third party projects, follows the same spirit than the
-       Boehm GC.
-
 ** mono/arch/*/XXX-codegen.h
 
        This are C macros that are useful when generating native
index de43007b1ca8e5160f1e9b5ac76db26e8fe7e875..a4a959d1c48b94c3eaecdcb78bc8b6d937f7fdc6 100644 (file)
@@ -27,6 +27,7 @@ update_submodules:
 .PHONY: update_submodules
 
 EXTRA_DIST= \
+        README.md \
            LICENSE \
            autogen.sh \
            build-mingw32.sh \
diff --git a/README b/README
deleted file mode 100644 (file)
index 7af5440..0000000
--- a/README
+++ /dev/null
@@ -1,607 +0,0 @@
-This is Mono.
-
-       1. Installation
-       2. Using Mono
-       3. Directory Roadmap
-       4. git submodules maintenance
-       5. Reporting bugs
-
-1. Compilation and Installation
-===============================
-
-   a. Build Requirements
-   ---------------------
-
-       On Itanium, you must obtain libunwind:
-
-               http://www.hpl.hp.com/research/linux/libunwind/download.php4
-
-       On Solaris, make sure that you used GNU tar to unpack this package, as
-       Solaris tar will not unpack this correctly, and you will get strange errors.
-
-       On Solaris, make sure that you use the GNU toolchain to build the software.
-
-       Optional dependencies:
-
-               * libgdiplus
-
-                 If you want to get support for System.Drawing, you will need to get
-                 Libgdiplus.    This library in turn requires glib and pkg-config:
-
-                       * pkg-config
-
-                         Available from: http://www.freedesktop.org/Software/pkgconfig
-
-                       * glib 2.4
-
-                         Available from: http://www.gtk.org/
-
-               * libzlib
-
-                 This library and the development headers are required for compression
-                 file support in the 2.0 profile.
-
-    b. Building the Software
-    ------------------------
-       
-       If you obtained this package as an officially released tarball,
-       this is very simple, use configure and make:
-
-               ./configure --prefix=/usr/local
-               make
-               make install
-
-       Mono supports a JIT engine on x86, SPARC, SPARCv9, S/390,
-       S/390x, AMD64, ARM and PowerPC systems.   
-
-       If you obtained this as a snapshot, you will need an existing
-       Mono installation.  To upgrade your installation, unpack both
-       mono and mcs:
-
-               tar xzf mcs-XXXX.tar.gz
-               tar xzf mono-XXXX.tar.gz
-               mv mono-XXX mono
-               mv mcs-XXX mcs
-               cd mono
-               ./autogen.sh --prefix=/usr/local
-               make
-
-       The Mono build system is silent for most compilation commands.
-       To enable a more verbose compile (for example, to pinpoint
-       problems in your makefiles or your system) pass the V=1 flag to make, like this:
-
-                make V=1
-
-
-    c. Building the software from GIT
-    ---------------------------------
-
-       If you are building the software from GIT, make sure that you
-       have up-to-date mcs and mono sources:
-
-          If you are an anonymous user:
-               git clone git://github.com/mono/mono.git
-
-           If you are a Mono contributors with read/write privileges:
-               git clone git@github.com:mono/mono.git
-
-
-       Then, go into the mono directory, and configure:
-
-               cd mono
-               ./autogen.sh --prefix=/usr/local
-               make
-
-       For people with non-standard installations of the auto* utils and of
-       pkg-config (common on misconfigured OSX and windows boxes), you could get
-       an error like this:
-
-       ./configure: line 19176: syntax error near unexpected token `PKG_CHECK_MODULES(BASE_DEPENDENCIES,' ...
-
-       This means that you need to set the ACLOCAL_FLAGS environment var
-       when invoking autogen.sh, like this:
-
-               ACLOCAL_FLAGS="-I $acprefix/share/aclocal" ./autogen.sh --prefix=/usr/loca
-       
-       where $acprefix is the prefix where aclocal has been installed.
-
-       This will automatically go into the mcs/ tree and build the
-       binaries there.
-
-       This assumes that you have a working mono installation, and that
-       there's a C# compiler named 'mcs', and a corresponding IL
-       runtime called 'mono'.  You can use two make variables
-       EXTERNAL_MCS and EXTERNAL_RUNTIME to override these.  e.g., you
-       can say
-
-         make EXTERNAL_MCS=/foo/bar/mcs EXTERNAL_RUNTIME=/somewhere/else/mono
-       
-       If you don't have a working Mono installation
-       ---------------------------------------------
-
-       If you don't have a working Mono installation, an obvious choice
-       is to install the latest released packages of 'mono' for your
-       distribution and running autogen.sh; make; make install in the
-       mono module directory.
-
-       You can also try a slightly more risky approach: this may not work,
-       so start from the released tarball as detailed above.
-
-       This works by first getting the latest version of the 'monolite'
-       distribution, which contains just enough to run the 'mcs'
-       compiler.  You do this with:
-
-               # Run the following line after ./autogen.sh
-               make get-monolite-latest
-
-       This will download and automatically gunzip and untar the
-       tarball, and place the files appropriately so that you can then
-       just run:
-
-               make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/gmcs.exe
-
-       And that will use the files downloaded by 'make get-monolite-latest.
-
-       Testing and Installation
-       ------------------------
-
-       You can run (part of) the mono and mcs testsuites with the command:
-
-               make check
-
-       All tests should pass.  
-
-       If you want more extensive tests, including those that test the
-       class libraries, you need to re-run 'configure' with the
-       '--enable-nunit-tests' flag, and try
-
-               make -k check
-
-       Expect to find a few testsuite failures.  As a sanity check, you
-       can compare the failures you got with
-
-               https://wrench.mono-project.com/Wrench/
-
-       You can now install mono with:
-
-               make install
-
-       You can verify your installation by using the mono-test-install
-       script, it can diagnose some common problems with Mono's install.
-
-       Failure to follow these steps may result in a broken installation. 
-
-    d. Configuration Options
-    ------------------------
-
-       The following are the configuration options that someone
-       building Mono might want to use:
-       
-       --with-sgen=yes,no
-
-               Generational GC support: Used to enable or disable the
-               compilation of a Mono runtime with the SGen garbage collector.
-
-               On platforms that support it, after building Mono, you
-               will have both a mono binary and a mono-sgen binary.
-               Mono uses Boehm, while mono-sgen uses the Simple
-               Generational GC.
-
-       --with-gc=[boehm, included, sgen, none]
-
-               Selects the default Boehm garbage collector engine to
-               use, the default is the "included" value.
-       
-               included: 
-                       This is the default value, and its
-                       the most feature complete, it will allow Mono
-                       to use typed allocations and support the
-                       debugger.
-
-                       It is essentially a slightly modified Boehm GC
-
-               boehm:
-                       This is used to use a system-install Boehm GC,
-                       it is useful to test new features available in
-                       Boehm GC, but we do not recommend that people
-                       use this, as it disables a few features.
-
-               none:
-                       Disables the inclusion of a garbage
-                       collector.  
-
-       --with-tls=__thread,pthread
-
-               Controls how Mono should access thread local storage,
-               pthread forces Mono to use the pthread APIs, while
-               __thread uses compiler-optimized access to it.
-
-               Although __thread is faster, it requires support from
-               the compiler, kernel and libc.   Old Linux systems do
-               not support with __thread.
-
-               This value is typically pre-configured and there is no
-               need to set it, unless you are trying to debug a
-               problem.
-
-       --with-sigaltstack=yes,no
-
-               Experimental: Use at your own risk, it is known to
-               cause problems with garbage collection and is hard to
-               reproduce those bugs.
-
-               This controls whether Mono will install a special
-               signal handler to handle stack overflows.   If set to
-               "yes", it will turn stack overflows into the
-               StackOverflowException.  Otherwise when a stack
-               overflow happens, your program will receive a
-               segmentation fault.
-
-               The configure script will try to detect if your
-               operating system supports this.   Some older Linux
-               systems do not support this feature, or you might want
-               to override the auto-detection.
-
-       --with-static_mono=yes,no
-
-               This controls whether `mono' should link against a
-               static library (libmono.a) or a shared library
-               (libmono.so). 
-
-               This defaults to yes, and will improve the performance
-               of the `mono' program. 
-
-               This only affects the `mono' binary, the shared
-               library libmono.so will always be produced for
-               developers that want to embed the runtime in their
-               application.
-
-       --with-xen-opt=yes,no
-
-               The default value for this is `yes', and it makes Mono
-               generate code which might be slightly slower on
-               average systems, but the resulting executable will run
-               faster under the Xen virtualization system.
-
-       --with-large-heap=yes,no
-
-               Enable support for GC heaps larger than 3GB.
-
-               This value is set to `no' by default.
-
-       --enable-small-config=yes,no
-
-               Enable some tweaks to reduce memory usage and disk footprint at
-               the expense of some capabilities. Typically this means that the
-               number of threads that can be created is limited (256), that the
-               maxmimum heap size is also reduced (256 MB) and other such limitations
-               that still make mono useful, but more suitable to embedded devices
-               (like mobile phones).
-
-               This value is set to `no' by default.
-
-       --with-ikvm-native=yes,no
-
-               Controls whether the IKVM JNI interface library is
-               built or not.  This is used if you are planning on
-               using the IKVM Java Virtual machine with Mono.
-
-               This defaults to `yes'.
-
-       --with-profile4=yes,no
-
-               Whether you want to build the 4.x profile libraries
-               and runtime.
-
-               It defaults to `yes'.
-
-       --with-moonlight=yes,no
-
-               Whether you want to generate the Silverlight/Moonlight
-               libraries and toolchain in addition to the default
-               (1.1 and 2.0 APIs).
-
-               This will produce the `smcs' compiler which will reference
-               the Silverlight modified assemblies (mscorlib.dll,
-               System.dll, System.Code.dll and System.Xml.Core.dll) and turn
-               on the LINQ extensions for the compiler.
-
-       --with-moon-gc=boehm,sgen
-
-               Select the GC to use for Moonlight.
-
-               boehm:
-                       Selects the Boehm Garbage Collector, with the same flags
-                       as the regular Mono build. This is the default.
-
-               sgen:
-                       Selects the new SGen Garbage Collector, which provides
-                       Generational GC support, using the same flags as the
-                       mono-sgen build.
-
-               This defaults to `boehm'.
-
-       --with-libgdiplus=installed,sibling,<path>
-
-               This is used to configure where should Mono look for
-               libgdiplus when running the System.Drawing tests.
-
-               It defaults to `installed', which means that the
-               library is available to Mono through the regular
-               system setup.
-
-               `sibling' can be used to specify that a libgdiplus
-               that resides as a sibling of this directory (mono)
-               should be used.
-
-               Or you can specify a path to a libgdiplus.
-
-       --disable-shared-memory 
-
-               Use this option to disable the use of shared memory in
-               Mono (this is equivalent to setting the MONO_DISABLE_SHM
-               environment variable, although this removes the feature
-               completely).
-
-               Disabling the shared memory support will disable certain
-               features like cross-process named mutexes.
-
-       --enable-minimal=LIST
-
-               Use this feature to specify optional runtime
-               components that you might not want to include.  This
-               is only useful for developers embedding Mono that
-               require a subset of Mono functionality.
-
-               The list is a comma-separated list of components that
-               should be removed, these are:
-
-               aot:
-                       Disables support for the Ahead of Time
-                       compilation.
-
-               attach:
-                       Support for the Mono.Management assembly and the
-                       VMAttach API (allowing code to be injected into
-                       a target VM)
-
-               com:
-                       Disables COM support.
-
-               debug:
-                       Drop debugging support.
-
-               decimal:
-                       Disables support for System.Decimal.
-
-               full_messages:
-                       By default Mono comes with a full table
-                       of messages for error codes.   This feature
-                       turns off uncommon error messages and reduces
-                       the runtime size.
-
-               generics:
-                       Generics support.  Disabling this will not
-                       allow Mono to run any 2.0 libraries or
-                       code that contains generics.
-
-               jit:
-                       Removes the JIT engine from the build, this reduces
-                       the executable size, and requires that all code
-                       executed by the virtual machine be compiled with
-                       Full AOT before execution.
-
-               large_code:
-                       Disables support for large assemblies.
-
-               logging:
-                       Disables support for debug logging.
-
-               pinvoke:
-                       Support for Platform Invocation services,
-                       disabling this will drop support for any
-                       libraries using DllImport.
-
-               portability:
-                       Removes support for MONO_IOMAP, the environment
-                       variables for simplifying porting applications that 
-                       are case-insensitive and that mix the Unix and Windows path separators.
-
-               profiler:
-                       Disables support for the default profiler.
-
-               reflection_emit:
-                       Drop System.Reflection.Emit support
-
-               reflection_emit_save:
-                       Drop support for saving dynamically created
-                       assemblies (AssemblyBuilderAccess.Save) in
-                       System.Reflection.Emit.
-
-               shadow_copy:
-                       Disables support for AppDomain's shadow copies
-                       (you can disable this if you do not plan on 
-                       using appdomains).
-
-               simd:
-                       Disables support for the Mono.SIMD intrinsics
-                       library.
-
-               ssa:
-                       Disables compilation for the SSA optimization
-                       framework, and the various SSA-based
-                       optimizations.
-
-       --enable-llvm
-       --enable-loadedllvm
-
-               This enables the use of LLVM as a code generation engine
-               for Mono.  The LLVM code generator and optimizer will be 
-               used instead of Mono's built-in code generator for both
-               Just in Time and Ahead of Time compilations.
-
-               See the http://www.mono-project.com/Mono_LLVM for the 
-               full details and up-to-date information on this feature.
-
-               You will need to have an LLVM built that Mono can link
-               against,
-
-               The --enable-loadedllvm variant will make the llvm backend
-               into a runtime-loadable module instead of linking it directly
-               into the main mono binary.
-
-       --enable-big-arrays
-
-               This enables the use arrays whose indexes are larger
-               than Int32.MaxValue.   
-
-               By default Mono has the same limitation as .NET on
-               Win32 and Win64 and limits array indexes to 32-bit
-               values (even on 64-bit systems).
-
-               In certain scenarios where large arrays are required,
-               you can pass this flag and Mono will be built to
-               support 64-bit arrays.
-
-               This is not the default as it breaks the C embedding
-               ABI that we have exposed through the Mono development
-               cycle.
-
-       --enable-parallel-mark
-
-               Use this option to enable the garbage collector to use
-               multiple CPUs to do its work.  This helps performance
-               on multi-CPU machines as the work is divided across CPUS.
-
-               This option is not currently the default as we have
-               not done much testing with Mono.
-
-       --enable-dtrace
-
-               On Solaris and MacOS X builds a version of the Mono
-               runtime that contains DTrace probes and can
-               participate in the system profiling using DTrace.
-
-
-       --disable-dev-random
-
-               Mono uses /dev/random to obtain good random data for
-               any source that requires random numbers.   If your
-               system does not support this, you might want to
-               disable it.
-
-               There are a number of runtime options to control this
-               also, see the man page.
-
-       --enable-nacl
-
-               This configures the Mono compiler to generate code
-               suitable to be used by Google's Native Client:
-
-                        http://code.google.com/p/nativeclient/
-
-               Currently this is used with Mono's AOT engine as
-               Native Client does not support JIT engines yet.
-
-2. Using Mono
-=============
-
-       Once you have installed the software, you can run a few programs:
-
-       * runtime engine
-
-               mono program.exe
-
-       * C# compiler
-
-               mcs program.cs
-
-       * CIL Disassembler
-
-               monodis program.exe
-
-       See the man pages for mono(1), mint(1), monodis(1) and mcs(2)
-       for further details.
-
-3. Directory Roadmap
-====================
-
-       docs/
-               Technical documents about the Mono runtime.
-
-       data/
-               Configuration files installed as part of the Mono runtime.
-
-       mono/
-               The core of the Mono Runtime.
-
-               metadata/
-                       The object system and metadata reader.
-
-               mini/
-                       The Just in Time Compiler.
-
-               dis/
-                       CIL executable Disassembler
-
-               cli/
-                       Common code for the JIT and the interpreter.
-
-               io-layer/
-                       The I/O layer and system abstraction for 
-                       emulating the .NET IO model.
-
-               cil/
-                       Common Intermediate Representation, XML
-                       definition of the CIL bytecodes.
-
-               interp/
-                       Interpreter for CLI executables (obsolete).
-
-               arch/
-                       Architecture specific portions.
-
-       man/
-
-               Manual pages for the various Mono commands and programs.
-
-       samples/
-
-               Some simple sample programs on uses of the Mono
-               runtime as an embedded library.   
-
-       scripts/
-
-               Scripts used to invoke Mono and the corresponding program.
-
-       runtime/
-
-               A directory that contains the Makefiles that link the
-               mono/ and mcs/ build systems.
-
-       ../olive/
-
-               If the directory ../olive is present (as an
-               independent checkout) from the Mono module, that
-               directory is automatically configured to share the
-               same prefix than this module gets.
-
-
-4. Git submodules maintenance
-=============================
-
-Read documentation at http://mono-project.com/Git_Submodule_Maintenance
-
-
-5. Reporting bugs
-=================
-
-To submit bug reports, please use Xamarin's Bugzilla:
-
-    https://bugzilla.xamarin.com/
-
-Please use the search facility to ensure the same bug hasn't already
-been submitted and follow our guidelines on how to make a good bug
-report:
-
-    http://mono-project.com/Bugs#How_to_make_a_good_bug_report
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..5ffe56a
--- /dev/null
+++ b/README.md
@@ -0,0 +1,539 @@
+Mono is a software platform designed to allow developers to easily create cross platform applications.
+Mono is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime.
+
+1. [Installation](#compilation-and-installation)
+2. [Using Mono](#using-mono)
+3. [Directory Roadmap](#directory-roadmap)
+4. [Git submodules maintenance](#git-submodules-maintenance)
+5. [Reporting bugs](#reporting-bugs)
+
+Compilation and Installation
+============================
+
+a. Build Requirements
+---------------------
+
+* On Itanium, you must obtain libunwind: http://www.hpl.hp.com/research/linux/libunwind/download.php4
+
+* On Solaris
+
+ 1. Make sure that you used GNU tar to unpack this package, as
+ Solaris tar will not unpack this correctly, and you will get strange errors.
+
+ 2. Make sure that you use the GNU toolchain to build the software.
+
+ 3. Optional dependencies
+
+  * libgdiplus - Required for System.Drawing. This library in turn requires glib and pkg-config
+
+  * pkg-config - Available at: http://www.freedesktop.org/Software/pkgconfig
+
+  * glib 2.4 - Available at: http://www.gtk.org/
+
+  * libzlib - This library and the development headers are required for compression
+file support in the 2.0 profile.
+
+b. Building the Software
+------------------------
+
+If you obtained this package as an officially released tarball,
+this is very simple, use configure and make:
+
+`./configure --prefix=/usr/local ; make ; make install`
+
+Mono supports a JIT engine on x86, SPARC, SPARCv9, S/390,
+S/390x, AMD64, ARM and PowerPC systems.   
+
+If you obtained this as a snapshot, you will need an existing
+Mono installation.  To upgrade your installation, unpack both
+mono and mcs:
+
+       tar xzf mcs-XXXX.tar.gz
+       tar xzf mono-XXXX.tar.gz
+       mv mono-XXX mono
+       mv mcs-XXX mcs
+       cd mono
+       ./autogen.sh --prefix=/usr/local
+       make
+
+The Mono build system is silent for most compilation commands.
+To enable a more verbose compile (for example, to pinpoint
+problems in your makefiles or your system) pass the V=1 flag to make, like this:
+
+` make V=1`
+
+
+c. Building the software from GIT
+---------------------------------
+
+If you are building the software from GIT, make sure that you
+have up-to-date mcs and mono sources:
+
+ * If you are an anonymous user: `git clone git://github.com/mono/mono.git`
+
+ * If you are a Mono contributor with read/write privileges: `git clone git@github.com:mono/mono.git`
+
+Then, go into the mono directory, and configure:
+
+       cd mono
+       ./autogen.sh --prefix=/usr/local
+       make
+
+For people with non-standard installations of the auto* utils and of
+pkg-config (common on misconfigured OSX and windows boxes), you could get
+an error like this:
+
+`./configure: line 19176: syntax error near unexpected token 'PKG_CHECK_MODULES(BASE_DEPENDENCIES,' ...`
+
+This means that you need to set the ACLOCAL_FLAGS environment variable
+when invoking autogen.sh, like this: `ACLOCAL_FLAGS="-I $acprefix/share/aclocal" ./autogen.sh --prefix=/usr/local`
+where $acprefix is the prefix where aclocal has been installed.
+This will automatically go into the mcs/ tree and build the
+binaries there.
+
+This assumes that you have a working mono installation, and that
+there's a C# compiler named 'mcs', and a corresponding IL
+runtime called 'mono'.  You can use two make variables
+EXTERNAL_MCS and EXTERNAL_RUNTIME to override these.  e.g., you
+can say:
+
+`make EXTERNAL_MCS=/foo/bar/mcs EXTERNAL_RUNTIME=/somewhere/else/mono`
+
+If you don't have a working Mono installation
+---------------------------------------------
+
+If you don't have a working Mono installation, an obvious choice
+is to install the latest released packages of 'mono' for your
+distribution and running `autogen.sh; make; make install` in the
+mono module directory.
+
+You can also try a slightly more risky approach: this may not work,
+so start from the released tarball as detailed above.
+
+This works by first getting the latest version of the 'monolite'
+distribution, which contains just enough to run the 'mcs'
+compiler. You do this with:
+
+       # Run the following line after ./autogen.sh
+       make get-monolite-latest
+
+This will download and automatically gunzip and untar the
+tarball, and place the files appropriately so that you can then
+just run: `make EXTERNAL_MCS=${PWD}/mcs/class/lib/monolite/gmcs.exe`
+
+That will use the files downloaded by 'make get-monolite-latest.
+
+Testing and Installation
+------------------------
+
+You can run *(part of)* the mono and mcs test suites with the command: `make check`.
+All tests should pass.  
+
+If you want more *extensive* tests, including those that test the
+class libraries, you need to re-run 'configure' with the
+'--enable-nunit-tests' flag, and try: `make -k check`
+
+Expect to find a few test suite failures. As a sanity check, you
+can compare the failures you got with
+
+`https://wrench.mono-project.com/Wrench/`
+
+You can now install mono with: `make install`
+
+You can verify your installation by using the mono-test-install
+script, it can diagnose some common problems with Mono's install.
+Failure to follow these steps may result in a broken installation. 
+
+d. Configuration Options
+------------------------
+
+The following are the configuration options that someone
+building Mono might want to use:
+
+* `--with-sgen=yes,no` - Generational GC support: Used to enable or disable the
+compilation of a Mono runtime with the SGen garbage collector.
+
+  * On platforms that support it, after building Mono, you
+will have both a mono binary and a mono-sgen binary.
+Mono uses Boehm, while mono-sgen uses the Simple
+Generational GC.
+
+* `--with-gc=[boehm, included, sgen, none]` - Selects the default Boehm garbage
+collector engine to use.
+
+  * *included*: (*slighty modified Boehm GC*)
+This is the default value, and its
+the most feature complete, it will allow Mono
+to use typed allocations and support the
+debugger.
+
+  * *boehm*:
+This is used to use a system-install Boehm GC,
+it is useful to test new features available in
+Boehm GC, but we do not recommend that people
+use this, as it disables a few features.
+
+  * *none*:
+Disables the inclusion of a garbage collector.
+
+  * This defaults to `included`.
+
+* `--with-tls=__thread,pthread`
+
+  * Controls how Mono should access thread local storage,
+pthread forces Mono to use the pthread APIs, while
+__thread uses compiler-optimized access to it.
+
+  * Although __thread is faster, it requires support from
+the compiler, kernel and libc. Old Linux systems do
+not support with __thread.
+
+  * This value is typically pre-configured and there is no
+need to set it, unless you are trying to debug a problem.
+
+* `--with-sigaltstack=yes,no`
+
+  * **Experimental**: Use at your own risk, it is known to
+cause problems with garbage collection and is hard to
+reproduce those bugs.
+
+  * This controls whether Mono will install a special
+signal handler to handle stack overflows. If set to
+`yes`, it will turn stack overflows into the
+StackOverflowException. Otherwise when a stack
+overflow happens, your program will receive a
+segmentation fault.
+
+  * The configure script will try to detect if your
+operating system supports this. Some older Linux
+systems do not support this feature, or you might want
+to override the auto-detection.
+
+* `--with-static_mono=yes,no`
+
+  * This controls whether `mono` should link against a
+static library (libmono.a) or a shared library
+(libmono.so). 
+
+  * This defaults to `yes`, and will improve the performance
+of the `mono` program. 
+
+  * This only affects the `mono' binary, the shared
+library libmono.so will always be produced for
+developers that want to embed the runtime in their
+application.
+
+* `--with-xen-opt=yes,no` - Optimize code for Xen virtualization.
+
+  * It makes Mono generate code which might be slightly
+slower on average systems, but the resulting executable will run
+faster under the Xen virtualization system.
+
+  * This defaults to `yes`.
+
+* `--with-large-heap=yes,no` - Enable support for GC heaps larger than 3GB.
+
+  * This defaults to `no`.
+
+* `--enable-small-config=yes,no` - Enable some tweaks to reduce memory usage
+and disk footprint at the expense of some capabilities.
+
+  * Typically this means that the number of threads that can be created
+is limited (256), that the maximum heap size is also reduced (256 MB)
+and other such limitations that still make mono useful, but more suitable
+to embedded devices (like mobile phones).
+
+  * This defaults to `no`.
+
+* `--with-ikvm-native=yes,no` - Controls whether the IKVM JNI interface library is
+built or not.
+
+  * This is used if you are planning on
+using the IKVM Java Virtual machine with Mono.
+
+  * This defaults to `yes`.
+
+* `--with-profile4=yes,no` - Whether you want to build the 4.x profile libraries
+and runtime.
+
+  * This defaults to `yes`.
+
+* `--with-moonlight=yes,no`
+
+  * Whether you want to generate the Silverlight/Moonlight
+libraries and toolchain in addition to the default
+(1.1 and 2.0 APIs).
+
+  * This will produce the `smcs` compiler which will reference
+the Silverlight modified assemblies (mscorlib.dll,
+System.dll, System.Code.dll and System.Xml.Core.dll) and turn
+on the LINQ extensions for the compiler.
+
+* `--with-moon-gc=boehm,sgen` - Select the GC to use for Moonlight.
+
+  * *boehm*:
+Selects the Boehm Garbage Collector, with the same flags
+as the regular Mono build. This is the default.
+
+  * *sgen*:
+Selects the new SGen Garbage Collector, which provides
+Generational GC support, using the same flags as the
+mono-sgen build.
+
+  * This defaults to `boehm`.
+
+* `--with-libgdiplus=installed,sibling,<path>` - Configure where Mono
+searches for libgdiplus when running System.Drawing tests.
+
+  * It defaults to `installed`, which means that the
+library is available to Mono through the regular
+system setup.
+
+  * `sibling' can be used to specify that a libgdiplus
+that resides as a sibling of this directory (mono)
+should be used.
+
+ * Or you can specify a path to a libgdiplus.
+
+* `--disable-shared-memory`
+
+  * Use this option to disable the use of shared memory in
+Mono (this is equivalent to setting the MONO_DISABLE_SHM
+environment variable, although this removes the feature
+completely).
+
+  * Disabling the shared memory support will disable certain
+features like cross-process named mutexes.
+
+* `--enable-minimal=LIST`
+
+  * Use this feature to specify optional runtime
+components that you might not want to include.  This
+is only useful for developers embedding Mono that
+require a subset of Mono functionality.
+  * The list is a comma-separated list of components that
+should be removed, these are:
+
+    * `aot`:
+Disables support for the Ahead of Time compilation.
+
+    * `attach`:
+Support for the Mono.Management assembly and the
+VMAttach API (allowing code to be injected into
+a target VM)
+
+    * `com`:
+Disables COM support.
+
+    * `debug`:
+Drop debugging support.
+
+    * `decimal`:
+Disables support for System.Decimal.
+
+    * `full_messages`:
+By default Mono comes with a full table
+of messages for error codes. This feature
+turns off uncommon error messages and reduces
+the runtime size.
+
+    * `generics`:
+Generics support.  Disabling this will not
+allow Mono to run any 2.0 libraries or
+code that contains generics.
+
+    * `jit`:
+Removes the JIT engine from the build, this reduces
+the executable size, and requires that all code
+executed by the virtual machine be compiled with
+Full AOT before execution.
+
+    * `large_code`:
+Disables support for large assemblies.
+
+    * `logging`:
+Disables support for debug logging.
+
+    * `pinvoke`:
+Support for Platform Invocation services,
+disabling this will drop support for any
+libraries using DllImport.
+
+    * `portability`:
+Removes support for MONO_IOMAP, the environment
+variables for simplifying porting applications that 
+are case-insensitive and that mix the Unix and Windows path separators.
+
+    * `profiler`:
+Disables support for the default profiler.
+
+    * `reflection_emit`:
+Drop System.Reflection.Emit support
+
+    * `reflection_emit_save`:
+Drop support for saving dynamically created
+assemblies (AssemblyBuilderAccess.Save) in
+System.Reflection.Emit.
+
+    * `shadow_copy`:
+Disables support for AppDomain's shadow copies
+(you can disable this if you do not plan on 
+using appdomains).
+
+    * `simd`:
+Disables support for the Mono.SIMD intrinsics
+library.
+
+    * `ssa`:
+Disables compilation for the SSA optimization
+framework, and the various SSA-based optimizations.
+
+* `--enable-llvm`
+* `--enable-loadedllvm`
+
+  * This enables the use of LLVM as a code generation engine
+for Mono.  The LLVM code generator and optimizer will be 
+used instead of Mono's built-in code generator for both
+Just in Time and Ahead of Time compilations.
+
+  * See the http://www.mono-project.com/Mono_LLVM for the 
+full details and up-to-date information on this feature.
+
+  * You will need to have an LLVM built that Mono can link
+against.
+
+  * The --enable-loadedllvm variant will make the LLVM backend
+into a runtime-loadable module instead of linking it directly
+into the main mono binary.
+
+* `--enable-big-arrays` - Enable use of arrays with indexes larger
+than Int32.MaxValue.
+
+  * By default Mono has the same limitation as .NET on
+Win32 and Win64 and limits array indexes to 32-bit
+values (even on 64-bit systems).
+
+  * In certain scenarios where large arrays are required,
+you can pass this flag and Mono will be built to
+support 64-bit arrays.
+
+  * This is not the default as it breaks the C embedding
+ABI that we have exposed through the Mono development
+cycle.
+
+* `--enable-parallel-mark`
+
+  * Use this option to enable the garbage collector to use
+multiple CPUs to do its work.  This helps performance
+on multi-CPU machines as the work is divided across CPUS.
+
+  * This option is not currently the default as we have
+not done much testing with Mono.
+
+* `--enable-dtrace`
+
+  * On Solaris and MacOS X builds a version of the Mono
+runtime that contains DTrace probes and can
+participate in the system profiling using DTrace.
+
+
+* `--disable-dev-random`
+
+  * Mono uses /dev/random to obtain good random data for
+any source that requires random numbers.   If your
+system does not support this, you might want to
+disable it.
+
+  * There are a number of runtime options to control this
+also, see the man page.
+
+* `--enable-nacl`
+
+  * This configures the Mono compiler to generate code
+suitable to be used by Google's Native Client:
+http://code.google.com/p/nativeclient/
+
+  * Currently this is used with Mono's AOT engine as
+Native Client does not support JIT engines yet.
+
+Using Mono
+==========
+
+Once you have installed the software, you can run a few programs:
+
+* `mono program.exe` runtime engine
+
+* `mcs program.cs` C# compiler 
+
+* `monodis program.exe` CIL Disassembler
+
+See the man pages for mono(1), mint(1), monodis(1) and mcs(2)
+for further details.
+
+Directory Roadmap
+=================
+
+* `docs/` - Technical documents about the Mono runtime.
+
+* `data/` - Configuration files installed as part of the Mono runtime.
+
+* `mono/` - The core of the Mono Runtime.
+
+  * `metadata/` - The object system and metadata reader.
+
+  * `mini/` - The Just in Time Compiler.
+
+  * `dis/` - CIL executable Disassembler
+
+  * `cli/` - Common code for the JIT and the interpreter.
+
+  * `io-layer/` - The I/O layer and system abstraction for 
+emulating the .NET IO model.
+
+  * `cil/` - Common Intermediate Representation, XML
+definition of the CIL bytecodes.
+
+ * `interp/` - Interpreter for CLI executables (obsolete).
+
+ * `arch/` - Architecture specific portions.
+
+* `man/` - Manual pages for the various Mono commands and programs.
+
+* `samples/` -Some simple sample programs on uses of the Mono
+runtime as an embedded library.   
+
+* `scripts/` - Scripts used to invoke Mono and the corresponding program.
+
+* `runtime/` - A directory that contains the Makefiles that link the
+mono/ and mcs/ build systems.
+
+* `../olive/`
+
+  * If the directory ../olive is present (as an
+independent checkout) from the Mono module, that
+directory is automatically configured to share the
+same prefix than this module gets.
+
+
+Git submodules maintenance
+==========================
+
+Read documentation at http://mono-project.com/Git_Submodule_Maintenance
+
+Maintainer
+==========
+
+Mono is maintained by miguel@xamarin.com
+
+Reporting bugs
+==============
+
+To submit bug reports, please use Xamarin's Bugzilla:
+
+https://bugzilla.xamarin.com/
+
+Please use the search facility to ensure the same bug hasn't already
+been submitted and follow our guidelines on how to make a good bug
+report:
+
+http://mono-project.com/Bugs#How_to_make_a_good_bug_report
index 8fc51d24df070776c14a3ba73fd310cba639610a..a576ed6672afab5a9697e610ce8b6a9e0265b208 100755 (executable)
@@ -107,15 +107,19 @@ fi
 # Plug in the extension module
 #
 has_ext_mod=false
+ext_mod_args=''
 for PARAM; do
-    if test "$PARAM" = "--enable-extension-module" ; then
-               has_ext_mod=true
-       fi
+    if [[ $PARAM =~ "--enable-extension-module" ]] ; then
+        has_ext_mod=true
+        if [[ $PARAM =~ "=" ]] ; then
+            ext_mod_args=`echo $PARAM | cut -d= -f2`
+        fi
+    fi
 done
 
 if test x$has_ext_mod = xtrue; then
        pushd ../mono-extensions/scripts
-       sh ./prepare-repo.sh || exit 1
+       sh ./prepare-repo.sh $ext_mod_args || exit 1
        popd
 else
        cat mono/mini/Makefile.am.in > mono/mini/Makefile.am
index 2d557e11bdaf9d9d168847a327391206bc5679bb..d62e6a3f6beded6eb70ca239e8890952a0ecb759 100644 (file)
@@ -1,10 +1,10 @@
 # Process this file with autoconf to produce a configure script.
 #AC_PREREQ([2.62])
 
-AC_INIT(mono, [3.2.5],
+AC_INIT(mono, [3.2.7],
         [http://bugzilla.xamarin.com/enter_bug.cgi?classification=Mono])
 
-AC_CONFIG_SRCDIR([README])
+AC_CONFIG_SRCDIR([README.md])
 AC_CONFIG_MACRO_DIR([m4])
 AC_CANONICAL_SYSTEM
 AC_CANONICAL_HOST
@@ -315,10 +315,8 @@ case "$host" in
                                CFLAGS_FOR_LIBGC="$CFLAGS_FOR_LIBGC $BROKEN_DARWIN_FLAGS"
                                CPPFLAGS_FOR_EGLIB="$CPPFLAGS_FOR_EGLIB $BROKEN_DARWIN_CPPFLAGS"
                                CFLAGS_FOR_EGLIB="$CFLAGS_FOR_EGLIB $BROKEN_DARWIN_FLAGS"
-                               extra_runtime_ldflags="-stack_size,0x800000"
                                ;;
                        x*64-*-darwin*)
-                               extra_runtime_ldflags="-stack_size,0x800000"
                                ;;
                        arm*-darwin*)
                                has_dtrace=no
@@ -931,7 +929,19 @@ fi
 AC_ARG_ENABLE(executables, [  --disable-executables disable the build of the runtime executables], enable_executables=$enableval, enable_executables=yes)
 AM_CONDITIONAL(DISABLE_EXECUTABLES, test x$enable_executables = xno)
 
-AC_ARG_ENABLE(extension-module, [  --enable-extension-module enables usage of the extension module], has_extension_module=$enableval, has_extension_module=no)
+has_extension_module=no
+AC_ARG_ENABLE(extension-module, [  --enable-extension-module=LIST enable the core-extensions from LIST],
+[
+       for extension in `echo "$enable_extension_module" | sed -e "s/,/ /g"`; do
+               if test x$extension = xdefault ; then
+                       has_extension_module=yes;
+               fi
+       done
+       if test x$enable_extension_module = xyes; then
+               has_extension_module=yes;
+       fi
+], [])
+
 AM_CONDITIONAL([HAS_EXTENSION_MODULE], [test x$has_extension_module != xno])
 
 if test x$has_extension_module != xno ; then
@@ -1826,9 +1836,9 @@ if test x$target_win32 = xno; then
        fi
 
        havekqueue=no
-        AC_CHECK_FUNCS(kqueue, , AC_MSG_CHECKING(for kqueue in sys/event.h)
-                AC_TRY_LINK([#include <sys/event.h>], 
-                [ kqueue(); ],[havekqueue=yes],[]))
+
+       AC_CHECK_HEADERS(sys/event.h)
+       AC_CHECK_FUNCS(kqueue, [havekqueue=yes], )
 
        dnl **************************************
        dnl * Darwin has a race that prevents us from using reliably:
@@ -1837,7 +1847,7 @@ if test x$target_win32 = xno; then
        dnl * and very few folks run Mono on large web servers on OSX, falling
        dnl * back 
        dnl **************************************
-       if test x$havekqueue = xyes; then
+       if test "x$havekqueue" = "xyes" -a "x$ac_cv_header_sys_event_h" = "xyes"; then
                if x$platform_darwin = xno; then
                        AC_DEFINE(USE_KQUEUE_FOR_THREADPOOL, 1, [Use kqueue for the threadpool])
                fi
@@ -1996,6 +2006,7 @@ if test x$target_win32 = xno; then
        AC_CHECK_FUNCS(futimens utimensat)
        AC_CHECK_FUNCS(fstatat mknodat readlinkat)
        AC_CHECK_FUNCS(readv writev preadv pwritev)
+       AC_CHECK_FUNCS(setpgid)
        AC_CHECK_SIZEOF(size_t)
        AC_CHECK_TYPES([blksize_t], [AC_DEFINE(HAVE_BLKSIZE_T)], , 
                [#include <sys/types.h>
@@ -2133,9 +2144,11 @@ else
        AC_CHECK_FUNCS(GetProcessId)
        AC_CHECK_DECLS(InterlockedExchange64, [], [], [[#include <windows.h>]])
        AC_CHECK_DECLS(InterlockedCompareExchange64, [], [], [[#include <windows.h>]])
+       AC_CHECK_DECLS(InterlockedDecrement64, [], [], [[#include <windows.h>]])
        AC_CHECK_DECLS(InterlockedIncrement64, [], [], [[#include <windows.h>]])
        AC_CHECK_DECLS(InterlockedAdd, [], [], [[#include <windows.h>]])
        AC_CHECK_DECLS(InterlockedAdd64, [], [], [[#include <windows.h>]])
+       AC_CHECK_DECLS(__readfsdword, [], [], [[#include <windows.h>]])
 fi
 
 dnl socklen_t check
@@ -2416,7 +2429,7 @@ if test "x$enable_llvm" = "xyes"; then
    fi
    LLVM_LIBS="$LLVM_LDFLAGS $LLVM_LIBS -lstdc++"
 
-   expected_llvm_version="3.3svn-mono/2c9642d"
+   expected_llvm_version="3.4svn-mono-mono/e656cac"
 
    # Should be something like '2.6' or '2.7svn'
    llvm_version=`$LLVM_CONFIG --version`
@@ -2962,39 +2975,6 @@ if test "x$TARGET" = "xAMD64" -o "x$TARGET" = "xX86"; then
        fi
 fi
 
-mono_debugger_supported=no
-AC_ARG_ENABLE(mono-debugger, [  --disable-mono-debugger disable support for the mdb debugger], try_mono_debugger=$enableval, try_mono_debugger=yes)
-if test "x$try_mono_debugger" = "xyes"; then
-       if test "x$TARGET" = "xAMD64" -o "x$TARGET" = "xX86" -o "x$TARGET" = "xS390x"; then
-               if test x$use_included_gc = xyes; then
-                       case "$host" in
-                       *-*-*linux*)
-                               mono_debugger_supported=yes
-                               ;;
-                       *86-apple-darwin*)
-                               mono_debugger_supported=yes
-                               ;;              
-                       esac
-               fi
-       fi
-fi
-
-# disable the debugger entirely when building with moonlight
-if test "x$with_moonlight" != "xno"; then
-       mono_debugger_supported=no
-fi
-
-# mdb support for sgen is broken, disable it until further notice.
-mono_debugger_supported=no
-
-AC_MSG_CHECKING(if the Mono Debugger is supported on this platform)
-if test "x$mono_debugger_supported" = "xyes"; then
-       BOEHM_DEFINES="$BOEHM_DEFINES -DMONO_DEBUGGER_SUPPORTED"
-       CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DMONO_DEBUGGER_SUPPORTED"
-fi
-AM_CONDITIONAL(MONO_DEBUGGER_SUPPORTED, test x$mono_debugger_supported = xyes)
-AC_MSG_RESULT($mono_debugger_supported)
-
 AC_ARG_ENABLE(icall-symbol-map,[  --enable-icall-symbol-map Generate tables which map icall functions to their C symbols], icall_symbol_map=$enableval, icall_symbol_map=no)
 if test "x$icall_symbol_map" = "xyes"; then
    AC_DEFINE(ENABLE_ICALL_SYMBOL_MAP, 1, [Icall symbol map enabled])
@@ -3098,6 +3078,8 @@ if test ${TARGET} = ARM; then
                return 0;
        ], [
                arm_v5=yes
+
+               arm_ver=ARMv5
        ], [])
 
        AC_TRY_COMPILE([], [
@@ -3108,6 +3090,8 @@ if test ${TARGET} = ARM; then
        ], [
                arm_v5=yes
                arm_v6=yes
+
+               arm_ver=ARMv6
        ], [])
 
        AC_TRY_COMPILE([], [
@@ -3119,8 +3103,12 @@ if test ${TARGET} = ARM; then
                arm_v5=yes
                arm_v6=yes
                arm_v7=yes
+
+               arm_ver=ARMv7
        ], [])
 
+       AC_MSG_RESULT($arm_ver)
+
        if test x$arm_v5 = xyes; then
                AC_DEFINE(HAVE_ARMV5, 1, [ARM v5])
                CPPFLAGS_FOR_LIBGC="$CPPFLAGS_FOR_LIBGC -DHAVE_ARMV5=1"
index b5a3f755ea569ee32b7b4c830573dbbd97ba89b4..f838c5b21f9299b70a9b0b9d22e6b8d1e38a2e22 100644 (file)
@@ -102,15 +102,35 @@ Global locks:
        Adding global locks is not to be taken lightly.
 
 The current lock hierarchy:
-loader lock
-       domain lock
-               domain jit lock
+loader lock (global)
+       domain lock (complex)
+               domain jit lock (complex)
+               marshal lock
                        simple locks
 
 Examples:
        You can take the loader lock without holding a domain lock.
-       You cannot take a domain lock if the loader lock is held.
+       You can take the domain load while holding the loader lock
+       You cannot take the loader lock if only the domain lock is held.
        You cannot take a domain lock while holding the lock to another domain.
+
+
+TODO:
+
+We have a few known ok violation. We need a way to whitelist them.
+
+Known ok issues:
+
+ERROR: tried to acquire lock DomainLock at mono_domain_code_reserve_align while holding DomainLock at mono_class_create_runtime_vtable: Hierarchy violation.
+       This is triggered when building the vtable of a non-root domain and fetching a vtable trampoline for an offset that has not been built. We'll take the root
+       domain lock while holding the other one.
+       This is ok since we never allow locking to have in the other direction, IOW, the root-domain lock is one level down from the other domain-locks.
+
+WARNING: tried to acquire lock ImageDataLock at mono_image_init_name_cache while holding ImageDataLock at mono_class_from_name
+WARNING: tried to acquire lock ImageDataLock at mono_image_init_name_cache while holding ImageDataLock at mono_image_add_to_name_cache
+       Both of those happen when filling up the name_cache, as it needs to alloc image memory.
+       This one is fixable by spliting mono_image_init_name_cache into a locked and an unlocked variants and calling them appropriatedly.
+
 */
 
 public enum Lock {
@@ -120,6 +140,9 @@ public enum Lock {
        DomainLock,
        DomainAssembliesLock,
        DomainJitCodeHashLock,
+       IcallLock,
+       AssemblyBindingLock,
+       MarshalLock,
 }
 
 public class SimLock
@@ -139,6 +162,7 @@ public class SimLock
                        case Lock.DomainLock:
                                return 1;
                        case Lock.DomainJitCodeHashLock:
+                       case Lock.MarshalLock:
                                return 2;
                        default:
                                return 3;
@@ -157,6 +181,10 @@ public class SimLock
                get { return kind == Lock.LoaderLock; }
        }
 
+       public bool IsResursiveLock {
+               get { return kind == Lock.LoaderLock || kind == Lock.DomainLock; }
+       }
+
        /*locked is already owned by the thread, 'this' is the new one*/
        bool Compare (SimThread thread, SimLock locked, out bool isWarning, out string msg)
        {
@@ -276,6 +304,11 @@ public class Trace {
                "mono_loader_unlock",
                "mono_image_lock",
                "mono_image_unlock",
+               "mono_icall_lock",
+               "mono_icall_unlock",
+               "add_record",
+               "mono_locks_lock_acquired",
+               "mono_locks_lock_released",
        };
 
        public Trace (string[] fields) {
@@ -326,6 +359,10 @@ public class Symbol : IComparable<Symbol>
        public int CompareTo(Symbol other) {
                return offset - other.offset;
        }
+
+       public void AdjustSize (Symbol next) {
+               size = next.offset - this.offset;
+       }
 }
 
 public interface SymbolTable {
@@ -352,21 +389,26 @@ public class OsxSymbolTable : SymbolTable
                string line;
                while ((line = proc.StandardOutput.ReadLine ()) != null) {
                        string[] fields = line.Split(new char[] {' ', '\t'}, StringSplitOptions.RemoveEmptyEntries);
-                       if (fields.Length < 4)
-                               continue;
-                       if (!(fields [1].Equals ("g") || fields [1].Equals ("d")))
+                       if (fields.Length < 7)
                                continue;
-                       if (!fields [2].Equals ("*UND*"))
+
+                       if (!fields [3].Equals ("FUN"))
                                continue;
 
                        int offset = fields [0].ParseHex ();
-                       string name = fields [3];
+                       string name = fields [6];
+                       if (name.StartsWith ("_"))
+                               name = name.Substring (1);
+
                        if (offset != 0)
                                list.Add (new Symbol (offset, 0, name));
                }
                table = new Symbol [list.Count];
                list.CopyTo (table, 0);
                Array.Sort (table);
+               for (int i = 1; i < table.Length; ++i) {
+                       table [i - 1].AdjustSize (table [i]);
+               }
        }
 
        public string Translate (int offset) {
index 585cc113779009048e775123a80643319e6c3cd0..06ed8a5af2bf14830e95f61a5f4dea23f42034c0 100644 (file)
@@ -60,22 +60,22 @@ test_ptrconv ()
                return FAILED ("int to pointer and back conversions fail %d != %d", iv, iv2);
 
        uv = 0;
-       ptr = GUINT_TO_POINTER (iv);
+       ptr = GUINT_TO_POINTER (uv);
        uv2 = GPOINTER_TO_UINT (ptr);
-       if (iv != iv2)
-               return FAILED ("uint to pointer and back conversions fail %u != %d", iv, iv2);
+       if (uv != uv2)
+               return FAILED ("uint to pointer and back conversions fail %u != %d", uv, uv2);
        
        uv = 1;
-       ptr = GUINT_TO_POINTER (iv);
+       ptr = GUINT_TO_POINTER (uv);
        uv2 = GPOINTER_TO_UINT (ptr);
-       if (iv != iv2)
-               return FAILED ("uint to pointer and back conversions fail %u != %d", iv, iv2);
+       if (uv != uv2)
+               return FAILED ("uint to pointer and back conversions fail %u != %d", uv, uv2);
 
        uv = UINT32_MAX;
-       ptr = GUINT_TO_POINTER (iv);
+       ptr = GUINT_TO_POINTER (uv);
        uv2 = GPOINTER_TO_UINT (ptr);
-       if (iv != iv2)
-               return FAILED ("uint to pointer and back conversions fail %u != %d", iv, iv2);
+       if (uv != uv2)
+               return FAILED ("uint to pointer and back conversions fail %u != %d", uv, uv2);
 
        return NULL;
        
index c02349ea22f33a8658170b89796bd70ba81563b2..92df59f033ef81a9b5a9cc6b09d44ed18d244517 160000 (submodule)
@@ -1 +1 @@
-Subproject commit c02349ea22f33a8658170b89796bd70ba81563b2
+Subproject commit 92df59f033ef81a9b5a9cc6b09d44ed18d244517
index a53cda354a63aa9e1740fb355aede651a6d68095..ee7b1a9d37f9c6838fac05a6597748c3ee16888e 100644 (file)
@@ -5,10 +5,6 @@
 #include <AvailabilityMacros.h>
 #include "mono/utils/mono-compiler.h"
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-#include "include/libgc-mono-debugger.h"
-#endif
-
 /* From "Inside Mac OS X - Mach-O Runtime Architecture" published by Apple
    Page 49:
    "The space beneath the stack pointer, where a new stack frame would normally
@@ -736,17 +732,4 @@ void GC_darwin_register_mach_handler_thread(mach_port_t thread) {
   GC_use_mach_handler_thread = 1;
 }
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-GCThreadFunctions *gc_thread_vtable = NULL;
-
-void *
-GC_mono_debugger_get_stack_ptr (void)
-{
-       GC_thread me;
-
-       me = GC_lookup_thread (pthread_self ());
-       return &me->stop_info.stack_ptr;
-}
-#endif
-
 #endif
index a0acefddb72d9aff36ce3e6990812ae77ed3cd98..cadba4dddc4b6c68cb1c7390b471fd499d95e097 100644 (file)
@@ -1,5 +1,3 @@
-noinst_HEADERS = libgc-mono-debugger.h
-
 EXTRA_DIST = $(srcdir)/*.h
 
 SUBDIRS = private
diff --git a/libgc/include/libgc-mono-debugger.h b/libgc/include/libgc-mono-debugger.h
deleted file mode 100644 (file)
index bbf4439..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-#ifndef LIBGC_MONO_DEBUGGER_H
-#define LIBGC_MONO_DEBUGGER_H
-
-#if defined(_IN_LIBGC) || defined(_IN_THE_MONO_DEBUGGER)
-
-typedef struct
-{
-       void (* initialize) (void);
-
-       void (* thread_created) (pthread_t tid, void *stack_ptr);
-       void (* thread_exited) (pthread_t tid, void *stack_ptr);
-
-       void (* stop_world) (void);
-       void (* start_world) (void);
-} GCThreadFunctions;
-
-extern GCThreadFunctions *gc_thread_vtable;
-
-extern void *
-GC_mono_debugger_get_stack_ptr (void);
-
-#else
-#error "This header is only intended to be used by the Mono Debugger"
-#endif
-
-#endif
-
index 334ff1de219a3dc0c9af66d4271706fd52f806fd..c5016416ad16e79ca137702db8e7ce4bc1e8528d 100644 (file)
 #undef PACKAGE_VERSION
 #include "mono/utils/mono-compiler.h"
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-#include "include/libgc-mono-debugger.h"
-#endif
-
 #ifdef NACL
 volatile int __nacl_thread_suspension_needed = 0;
 pthread_t nacl_thread_parker = -1;
@@ -625,11 +621,6 @@ void GC_stop_world()
       /* We should have previously waited for it to become zero. */
 #   endif /* PARALLEL_MARK */
     ++GC_stop_count;
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->stop_world)
-       gc_thread_vtable->stop_world ();
-    else
-#endif
        pthread_stop_world ();
 #   ifdef PARALLEL_MARK
       GC_release_mark_lock();
@@ -717,11 +708,6 @@ static void pthread_start_world()
 
 void GC_start_world()
 {
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->start_world)
-       gc_thread_vtable->start_world();
-    else
-#endif
        pthread_start_world ();
 }
 
@@ -773,27 +759,7 @@ static void pthread_stop_init() {
 /* We hold the allocation lock.        */
 void GC_stop_init()
 {
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->initialize)
-       gc_thread_vtable->initialize ();
-    else
-#endif
        pthread_stop_init ();
 }
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-
-GCThreadFunctions *gc_thread_vtable = NULL;
-
-void *
-GC_mono_debugger_get_stack_ptr (void)
-{
-       GC_thread me;
-
-       me = GC_lookup_thread (pthread_self ());
-       return &me->stop_info.stack_ptr;
-}
-
-#endif
-
 #endif
index b302688a76e589fc603da7c0ce126696f842579e..a8c8b330a36d3f81462b2933ffaad2262ff412ea 100644 (file)
@@ -222,10 +222,6 @@ static int GC_setspecific (GC_key_t key, void *value) {
 
 static GC_bool keys_initialized;
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-#include "include/libgc-mono-debugger.h"
-#endif
-
 /* Recover the contents of the freelist array fl into the global one gfl.*/
 /* Note that the indexing scheme differs, in that gfl has finer size   */
 /* resolution, even if not all entries are used.                       */
@@ -804,10 +800,6 @@ void GC_delete_thread(pthread_t id)
     } else {
         prev -> next = p -> next;
     }
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->thread_exited)
-       gc_thread_vtable->thread_exited (id, &p->stop_info.stack_ptr);
-#endif
        
 #ifdef GC_DARWIN_THREADS
        mach_port_deallocate(mach_task_self(), p->stop_info.mach_thread);
@@ -1124,14 +1116,6 @@ void GC_thr_init()
          t -> stop_info.stack_ptr = (ptr_t)(&dummy);
 #     endif
       t -> flags = DETACHED | MAIN_THREAD;
-#ifdef MONO_DEBUGGER_SUPPORTED
-      if (gc_thread_vtable && gc_thread_vtable->thread_created)
-#     ifdef GC_DARWIN_THREADS
-        gc_thread_vtable->thread_created (mach_thread_self (), &t->stop_info.stack_ptr);
-#     else
-         gc_thread_vtable->thread_created (pthread_self (), &t->stop_info.stack_ptr);
-#     endif
-#endif
                 if (pthread_self () == main_pthread_self) {
                         t->stack = main_stack;
                         t->stack_size = main_stack_size;
@@ -1461,14 +1445,6 @@ void * GC_start_routine_head(void * arg, void *base_addr,
       /* This is also < 100% convincing.  We should also read this     */
       /* from /proc, but the hook to do so isn't there yet.            */
 #   endif /* IA64 */
-#ifdef MONO_DEBUGGER_SUPPORTED
-    if (gc_thread_vtable && gc_thread_vtable->thread_created)
-#      ifdef GC_DARWIN_THREADS
-       gc_thread_vtable->thread_created (mach_thread_self(), &me->stop_info.stack_ptr);
-#      else
-       gc_thread_vtable->thread_created (my_pthread, &me->stop_info.stack_ptr);
-#      endif
-#endif
     UNLOCK();
 
     if (start) *start = si -> start_routine;
index dc1f2ceb2acb8e750e2da65b749070d9580df079..0b0e4235a7aabd2f0cd4e8b1b1af368122103e56 100644 (file)
@@ -265,6 +265,12 @@ instructs the Mono runtime to start debugging in server mode, where Mono
 actively waits for the debugger front end to connect to the Mono process.  
 Mono will print out to stdout the IP address and port where it is listening.
 .TP
+.I setpgid=[y/n]
+If set to yes, Mono will call \fBsetpgid(0, 0)\fB on startup, if that function
+is available on the system. This is useful for ensuring that signals delivered
+to a process that is executing the debuggee are not propagated to the debuggee,
+e.g. when Ctrl-C sends \fBSIGINT\fB to the \fBsdb\fB tool.
+.TP
 .I suspend=[y/n]
 Defaults to yes, with the default option Mono will suspend the vm on startup 
 until it connects successfully to a debugger front end.  If you set it to 'n', in 
index c1a09f59f57d0992922644eb7675307bd25c1445..e8e8363b5ffe9fb9ffe46835aa84161666d83a09 100644 (file)
@@ -2,12 +2,23 @@ MCS_BUILD_DIR = ../../build
 
 thisdir = class/Facades
 
-monotouch_SUBDIRS = System.Collections.Concurrent System.Collections System.ComponentModel.Annotations System.ComponentModel.EventBasedAsync System.ComponentModel System.Diagnostics.Contracts System.Diagnostics.Debug System.Diagnostics.Tools System.Globalization System.IO System.Linq.Expressions System.Linq.Parallel System.Linq.Queryable System.Linq System.Net.NetworkInformation System.Net.Primitives System.Net.Requests System.ObjectModel System.Reflection.Extensions System.Reflection.Primitives System.Reflection System.Resources.ResourceManager System.Runtime.Extensions System.Runtime.InteropServices System.Runtime.Numerics System.Runtime.Serialization.Json System.Runtime.Serialization.Primitives System.Runtime.Serialization.Xml System.Runtime System.Security.Principal System.ServiceModel.Http System.ServiceModel.Primitives System.Text.Encoding.Extensions System.Text.Encoding System.Text.RegularExpressions System.Threading.Tasks.Parallel System.Threading.Tasks System.Threading System.Xml.ReaderWriter System.Xml.XDocument System.Xml.XmlSerializer
+monotouch_SUBDIRS = System.Collections.Concurrent System.Collections System.ComponentModel.Annotations System.ComponentModel.EventBasedAsync System.ComponentModel \
+       System.Diagnostics.Contracts System.Diagnostics.Debug System.Diagnostics.Tools System.Dynamic.Runtime System.Globalization System.IO System.Linq.Expressions \
+       System.Linq.Parallel System.Linq.Queryable System.Linq System.Net.NetworkInformation System.Net.Primitives System.Net.Requests System.ObjectModel \
+       System.Reflection.Extensions System.Reflection.Primitives System.Reflection System.Resources.ResourceManager System.Runtime.Extensions \
+       System.Runtime.InteropServices System.Runtime.InteropServices.WindowsRuntime System.Runtime.Numerics System.Runtime.Serialization.Json \
+       System.Runtime.Serialization.Primitives System.Runtime.Serialization.Xml System.Runtime System.Security.Principal System.ServiceModel.Http \
+       System.ServiceModel.Primitives System.Text.Encoding.Extensions System.Text.Encoding System.Text.RegularExpressions System.Threading.Tasks.Parallel \
+       System.Threading.Tasks System.Threading System.Xml.ReaderWriter System.Xml.XDocument System.Xml.XmlSerializer
 
-net_4_5_SUBDIRS = $(monotouch_SUBDIRS) System.Dynamic.Runtime System.Reflection.Emit.ILGeneration System.Reflection.Emit.Lightweight System.Reflection.Emit
+mobile_static_SUBDIRS = $(monotouch_SUBDIRS)
+
+net_4_5_SUBDIRS = $(monotouch_SUBDIRS) System.Reflection.Emit.ILGeneration System.Reflection.Emit.Lightweight System.Reflection.Emit
 
 monodroid_SUBDIRS = $(net_4_5_SUBDIRS)
 
+SUBDIRS = $(net_4_5_SUBDIRS)
+
 include $(MCS_BUILD_DIR)/rules.make
 
 dist-local: dist-default
index b579d020c120a10cf55dc528c6bf55b36784a914..ff800e52ef470a2d682b96e8a28c53c3c1394e3c 100644 (file)
@@ -19,7 +19,7 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 // THE SOFTWARE.
 // 
-
+#if !FULL_AOT_RUNTIME
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Dynamic.BinaryOperationBinder))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Dynamic.BindingRestrictions))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Dynamic.CallInfo))]
@@ -46,4 +46,6 @@
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.CallSiteBinder))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.CallSiteHelpers))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.DynamicAttribute))]
+#endif
 
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.CompilerServices.ConditionalWeakTable<,>))]
index ca35ff1a1b24a92862addaf84c86b25565818dc5..438486c963fdfdb43c72f7357417367fe1824328 100644 (file)
@@ -20,7 +20,7 @@
 // THE SOFTWARE.
 // 
 
-#if !MONOTOUCH
+#if !FULL_AOT_RUNTIME
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Linq.Expressions.BlockExpression))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Linq.Expressions.CatchBlock))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Linq.Expressions.DebugInfoExpression))]
index d19ab64febc11b05c64c1faae970e4bed2829469..cfa70ce24a5c460f9ae8f1c8efef1cff5afe3b63 100644 (file)
@@ -20,7 +20,7 @@
 // THE SOFTWARE.
 // 
 
-#if !MONOTOUCH
+#if !FULL_AOT_RUNTIME
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.FlowControl))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OpCode))]
 [assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Reflection.Emit.OpCodes))]
diff --git a/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/AssemblyInfo.cs b/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/AssemblyInfo.cs
new file mode 100644 (file)
index 0000000..f63a705
--- /dev/null
@@ -0,0 +1,41 @@
+// 
+// Copyright (c) 2013 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.Runtime.InteropServices.WindowsRuntime.dll")]
+[assembly: AssemblyDescription ("System.Runtime.InteropServices.WindowsRuntime.dll")]
+[assembly: AssemblyDefaultAlias ("System.Runtime.InteropServices.WindowsRuntime.dll")]
+[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: AssemblyInformationalVersion ("4.0.0.0")]
+[assembly: AssemblyFileVersion ("4.0.0.0")]
+[assembly: AssemblyDelaySign (true)]
+[assembly: AssemblyKeyFile ("../../msfinal.pub")]
+
+[assembly: ReferenceAssembly]
+
+
diff --git a/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/Makefile b/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/Makefile
new file mode 100644 (file)
index 0000000..bb8dbee
--- /dev/null
@@ -0,0 +1,22 @@
+MCS_BUILD_DIR = ../../../build
+
+thisdir = class/Facades/System.Runtime.InteropServices.WindowsRuntime
+SUBDIRS = 
+include $(MCS_BUILD_DIR)/rules.make
+
+LIBRARY_SUBDIR = Facades
+LIBRARY_INSTALL_DIR = $(mono_libdir)/mono/$(FRAMEWORK_VERSION)/Facades
+
+LIBRARY = System.Runtime.InteropServices.WindowsRuntime.dll
+
+KEY_FILE = ../../msfinal.pub
+SIGN_FLAGS = /delaysign /keyfile:$(KEY_FILE) /nowarn:1616,1699
+LIB_MCS_FLAGS = $(SIGN_FLAGS) /r:mscorlib
+
+PLATFORM_DEBUG_FLAGS =
+
+NO_TEST = yes
+
+include $(MCS_BUILD_DIR)/library.make
+
+
diff --git a/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/System.Runtime.InteropServices.WindowsRuntime.dll.sources b/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/System.Runtime.InteropServices.WindowsRuntime.dll.sources
new file mode 100644 (file)
index 0000000..8e33d4d
--- /dev/null
@@ -0,0 +1,3 @@
+TypeForwarders.cs
+AssemblyInfo.cs
+
diff --git a/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/TypeForwarders.cs b/mcs/class/Facades/System.Runtime.InteropServices.WindowsRuntime/TypeForwarders.cs
new file mode 100644 (file)
index 0000000..efc9d91
--- /dev/null
@@ -0,0 +1,30 @@
+// 
+// Copyright (c) 2013 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.WindowsRuntime.DefaultInterfaceAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationToken))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.EventRegistrationTokenTable<>))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.IActivationFactory))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.InterfaceImplementedInVersionAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.ReadOnlyArrayAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.ReturnValueNameAttribute))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeMarshal))]
+[assembly: System.Runtime.CompilerServices.TypeForwardedToAttribute(typeof(System.Runtime.InteropServices.WindowsRuntime.WriteOnlyArrayAttribute))]
index 0c7e63a212e1b1006a613d33d1d4a84f4b7ea6b8..599fff8e80a945bd9daac95d9375d7d9eef23a7b 100644 (file)
@@ -20,7 +20,7 @@
 // THE SOFTWARE.
 // 
 
-#if !MONOTOUCH
+#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))]
index 8d67fec080c800d076f0e2559be92896493a2f6c..fc22d1f56310b44b63bc5a3cf9858ef33f08be98 100644 (file)
@@ -269,9 +269,12 @@ namespace Microsoft.Build.BuildEngine {
 
                void AddMetadata (string name, string value)
                {
+                       var options = IsDynamic ?
+                                     ParseOptions.AllowItemsMetadataAndSplit : ParseOptions.AllowItemsNoMetadataAndSplit;
+
                        if (parent_item_group != null) {
                                Expression e = new Expression ();
-                               e.Parse (value, ParseOptions.AllowItemsNoMetadataAndSplit);
+                               e.Parse (value, options);
                                evaluatedMetadata [name] = (string) e.ConvertTo (parent_item_group.ParentProject,
                                                typeof (string), ExpressionOptions.ExpandItemRefs);
                        } else
index 006fe2b3fa2ec2c44ff4703d567edf0ca283f14f..9c827f0953652ab5bb8bc25b71e14454f50954d3 100644 (file)
@@ -30,6 +30,7 @@
 using System;
 using System.Text;
 using System.Xml;
+using System.Collections.Generic;
 
 using Microsoft.Build.Framework;
 using Microsoft.Build.Utilities;
@@ -241,6 +242,14 @@ namespace Microsoft.Build.BuildEngine {
                internal XmlElement XmlElement {
                        get { return propertyElement; }
                }
+
+               internal IEnumerable<string> GetAttributes ()
+               {
+                       if (!FromXml)
+                               yield break;
+                       foreach (XmlAttribute attr in propertyElement.Attributes)
+                               yield return attr.Value;
+               }
        }
 
        internal enum PropertyType {
index fc6b02447c5e48c4057560c64591d89c49cb3e51..9800c6883f57527042e4bc6cbf9ca3be2dd3e921 100644 (file)
@@ -43,6 +43,7 @@ namespace Microsoft.Build.BuildEngine {
                List <BuildProperty>    properties;
                Dictionary <string, BuildProperty>      propertiesByName;
                bool evaluated;
+               bool isDynamic;
 
                public BuildPropertyGroup ()
                        : this (null, null, null, false)
@@ -50,12 +51,18 @@ namespace Microsoft.Build.BuildEngine {
                }
 
                internal BuildPropertyGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
+                       : this (xmlElement, project, importedProject, readOnly, false)
+               {
+               }
+
+               internal BuildPropertyGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly, bool isDynamic)
                {
                        this.importedProject = importedProject;
                        this.parentCollection = null;
                        this.parentProject = project;
                        this.propertyGroup = xmlElement;
                        this.read_only = readOnly;
+                       this.isDynamic = isDynamic;
 
                        if (FromXml) {
                                this.properties = new List <BuildProperty> ();
@@ -223,7 +230,7 @@ namespace Microsoft.Build.BuildEngine {
                
                internal void Evaluate ()
                {
-                       if (evaluated)
+                       if (!isDynamic && evaluated)
                                return;
 
                        foreach (BuildProperty bp in properties)
@@ -299,5 +306,16 @@ namespace Microsoft.Build.BuildEngine {
                internal XmlElement XmlElement {
                        get { return propertyGroup; }
                }
+
+               internal IEnumerable<string> GetAttributes ()
+               {
+                       foreach (XmlAttribute attrib in XmlElement.Attributes)
+                               yield return attrib.Value;
+
+                       foreach (BuildProperty bp in properties) {
+                               foreach (string attr in bp.GetAttributes ())
+                                       yield return attr;
+                       }
+               }
        }
 }
index 4df2f780a9022f9fb63595aae29c6d1828850d25..b5482ae16624f4ae2fc3bbc7f009a94756c09f65 100644 (file)
@@ -38,7 +38,7 @@ namespace Microsoft.Build.BuildEngine {
                }
                
                internal BuildTaskPropertyGroup (XmlElement element, Target target)
-                       : base (element, target.Project, null, false)
+                       : base (element, target.Project, null, false, true)
                {
                }
                
@@ -48,10 +48,9 @@ namespace Microsoft.Build.BuildEngine {
                        return true;
                }
 
-               public IEnumerable<string> GetAttributes ()
+               IEnumerable<string> IBuildTask.GetAttributes ()
                {
-                       foreach (XmlAttribute attrib in XmlElement.Attributes)
-                               yield return attrib.Value;
+                       return GetAttributes ();
                }
                
        }
index abe0ec9d8e84ca9ced8ab53464799241edba65b6..357f9d26adc3f1f6db4a2e808187b9a2f06e70a3 100644 (file)
 
 using System;
 
-namespace Microsoft.Build.BuildEngine {
+#if MICROSOFT_BUILD_DLL
+namespace Microsoft.Build.Logging
+#else
+namespace Microsoft.Build.BuildEngine
+#endif
+{
        public delegate void ColorResetter ();
 }
index 85091186ea0010e039f5b01a44f2580253a5b49a..d38f551e67ce46b4489d44fcaeb58e4bdafb19bb 100644 (file)
 
 using System;
 
-namespace Microsoft.Build.BuildEngine {
+#if MICROSOFT_BUILD_DLL
+namespace Microsoft.Build.Logging
+#else
+namespace Microsoft.Build.BuildEngine
+#endif
+{
        public delegate void ColorSetter (ConsoleColor color);
 }
index 2a62f4b388c2caee9b4635338a637442eafe33d8..5fb7d21899cb771de2ce7d34dfded611aebfc06e 100644 (file)
@@ -35,33 +35,24 @@ using System.Security;
 using System.Text;
 using Microsoft.Build.Framework;
 
-namespace Microsoft.Build.BuildEngine {
+#if MICROSOFT_BUILD_DLL
+namespace Microsoft.Build.Logging
+#else
+namespace Microsoft.Build.BuildEngine
+#endif
+{
        public class ConsoleLogger : ILogger {
        
                string          parameters;
-               int             indent;
                LoggerVerbosity verbosity;
                WriteHandler    writeHandler;
-               int             errorCount;
-               int             warningCount;
-               DateTime                buildStart;
-               bool            performanceSummary;
-               bool            showSummary;
                bool            skipProjectStartedText;
-               List<string> errors, warnings;
-               bool            projectFailed;
                ConsoleColor errorColor, warningColor, eventColor, messageColor, highMessageColor;
                ColorSetter colorSet;
                ColorResetter colorReset;
                IEventSource eventSource;
                bool no_message_color, use_colors;
-               bool noItemAndPropertyList;
-
-               List<BuildEvent> events;
-               Dictionary<string, List<string>> errorsTable;
-               Dictionary<string, List<string>> warningsTable;
-               SortedDictionary<string, PerfInfo> targetPerfTable, tasksPerfTable;
-               string current_events_string;
+               ConsoleLoggerParameter config = new ConsoleLoggerParameter ();          
                
                public ConsoleLogger ()
                        : this (LoggerVerbosity.Normal, null, null, null)
@@ -69,7 +60,7 @@ namespace Microsoft.Build.BuildEngine {
                }
 
                public ConsoleLogger (LoggerVerbosity verbosity)
-                       : this (LoggerVerbosity.Normal, null, null, null)
+                       : this (verbosity, null, null, null)
                {
                }
                
@@ -79,27 +70,14 @@ namespace Microsoft.Build.BuildEngine {
                                      ColorResetter colorReset)
                {
                        this.verbosity = verbosity;
-                       this.indent = 0;
-                       this.errorCount = 0;
-                       this.warningCount = 0;
                        if (write == null)
                                this.writeHandler += new WriteHandler (WriteHandlerFunction);
                        else
                                this.writeHandler += write;
-                       this.performanceSummary = false;
-                       this.showSummary = true;
                        this.skipProjectStartedText = false;
-                       errors = new List<string> ();
-                       warnings = new List<string> ();
                        this.colorSet = colorSet;
                        this.colorReset = colorReset;
 
-                       events = new List<BuildEvent> ();
-                       errorsTable = new Dictionary<string, List<string>> ();
-                       warningsTable = new Dictionary<string, List<string>> ();
-                       targetPerfTable = new SortedDictionary<string, PerfInfo> ();
-                       tasksPerfTable = new SortedDictionary<string, PerfInfo> ();
-
                        //defaults
                        errorColor = ConsoleColor.DarkRed;
                        warningColor = ConsoleColor.DarkYellow;
@@ -146,6 +124,11 @@ namespace Microsoft.Build.BuildEngine {
                                }
                        }
                }
+               
+               private void WriteHandlerFunction (string message)
+               {
+                       Console.WriteLine (message);
+               }
 
                bool TryParseConsoleColor (string color_str, ref ConsoleColor color)
                {
@@ -192,21 +175,32 @@ namespace Microsoft.Build.BuildEngine {
                        }
                }
                
+               class ConsoleLoggerParameter
+               {
+                       public ConsoleLoggerParameter ()
+                       {
+                               ShowSummary = true;
+                       }
+                       public bool PerformanceSummary { get; set; }
+                       public bool ShowSummary { get; set; }
+                       public bool NoItemAndPropertyList { get; set; }
+               }
+               
                public void ApplyParameter (string parameterName,
                                            string parameterValue)
                {
                        switch (parameterName) {
                                case "PerformanceSummary":
-                                       this.performanceSummary = true;
+                                       config.PerformanceSummary = true;
                                        break;
                                case "Summary":
-                                       this.showSummary = true;
+                                       config.ShowSummary = true;
                                        break;
                                case "NoSummary":
-                                       this.showSummary = false;
+                                       config.ShowSummary = false;
                                        break;
                                case "NoItemAndPropertyList":
-                                       this.noItemAndPropertyList = true;
+                                       config.NoItemAndPropertyList = true;
                                        break;
                                default:
                                        if (parameterName.StartsWith ("Verbosity="))
@@ -282,375 +276,93 @@ namespace Microsoft.Build.BuildEngine {
                        if (!String.IsNullOrEmpty (parameters))
                                ParseParameters ();
                }
-
-               public void BuildStartedHandler (object sender, BuildStartedEventArgs args)
+               
+               Dictionary<object,BuildRecord> build_records = new Dictionary<object, BuildRecord> ();
+               
+               object dummy_key = new object ();
+               
+               BuildRecord GetBuildRecord (object sender)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
-                               WriteLine (String.Empty);
-                               WriteLine (String.Format ("Build started {0}.", args.Timestamp));
-                               WriteLine ("__________________________________________________");
+                       BuildRecord r;
+                       // FIXME: our Microsoft.Build.Engine shouldn't give different "sender" object for each event
+                       // during the same build run. But it actually does.
+                       // It is problematic for parallel build because it is impossible to determine right "ongoing build"
+                       // record for the event without correct sender object.
+                       // Hence we expect sender as a valid object only if it is IBuildEngine4 -
+                       // only Microsoft.Build.Internal.BuildEngine4 implements it so far. 
+                       // (Used IBuildEngine3 because it needs to build for NET_4_0).
+#if NET_4_0
+                       var key = sender as IBuildEngine3 ?? dummy_key;
+#else
+                       var key = dummy_key;
+#endif
+                       if (!build_records.TryGetValue (key, out r)) {
+                               r = new BuildRecord (this);
+                               build_records.Add (key, r);
                        }
-                       buildStart = args.Timestamp;
+                       return r;
+               }
 
-                       PushEvent (args);
+               public void BuildStartedHandler (object sender, BuildStartedEventArgs args)
+               {
+                       GetBuildRecord (sender).BuildStartedHandler (sender, args);
                }
                
                public void BuildFinishedHandler (object sender, BuildFinishedEventArgs args)
                {
-                       BuildFinishedHandlerActual (args);
-
-                       // Reset
-                       events.Clear ();
-                       errorsTable.Clear ();
-                       warningsTable.Clear ();
-                       targetPerfTable.Clear ();
-                       tasksPerfTable.Clear ();
-                       errors.Clear ();
-                       warnings.Clear ();
-
-                       indent = 0;
-                       errorCount = 0;
-                       warningCount = 0;
-                       projectFailed = false;
+                       GetBuildRecord (sender).BuildFinishedHandler (args);
+                       build_records.Remove (sender);
                }
-
-               void BuildFinishedHandlerActual (BuildFinishedEventArgs args)
+               
+               void PushEvent<T> (object sender, T args) where T: BuildStatusEventArgs
                {
-                       if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
-                               PopEvent (args);
-                               return;
-                       }
-
-                       TimeSpan timeElapsed = args.Timestamp - buildStart;
-                       if (performanceSummary || verbosity == LoggerVerbosity.Diagnostic)
-                               DumpPerformanceSummary ();
-
-                       if (args.Succeeded == true && !projectFailed) {
-                               WriteLine ("Build succeeded.");
-                       } else {
-                               WriteLine ("Build FAILED.");
-                       }
-                       if (warnings.Count > 0) {
-                               WriteLine (Environment.NewLine + "Warnings:");
-                               SetColor (warningColor);
-
-                               WriteLine (String.Empty);
-                               foreach (KeyValuePair<string, List<string>> pair in warningsTable) {
-                                       if (!String.IsNullOrEmpty (pair.Key))
-                                               WriteLine (pair.Key);
-
-                                       string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
-                                       foreach (string msg in pair.Value)
-                                               WriteLine (String.Format ("{0}{1}", indent_str, msg));
-
-                                       WriteLine (String.Empty);
-                               }
-
-                               ResetColor ();
-                       }
-
-                       if (errors.Count > 0) {
-                               WriteLine ("Errors:");
-                               SetColor (errorColor);
-
-                               WriteLine (String.Empty);
-                               foreach (KeyValuePair<string, List<string>> pair in errorsTable) {
-                                       if (!String.IsNullOrEmpty (pair.Key))
-                                               WriteLine (pair.Key);
-
-                                       string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
-                                       foreach (string msg in pair.Value)
-                                               WriteLine (String.Format ("{0}{1}", indent_str, msg));
-
-                                       WriteLine (String.Empty);
-                               }
-                               ResetColor ();
-                       }
-
-                       if (showSummary == true){
-                               WriteLine (String.Format ("\t {0} Warning(s)", warningCount));
-                               WriteLine (String.Format ("\t {0} Error(s)", errorCount));
-                               WriteLine (String.Empty);
-                               WriteLine (String.Format ("Time Elapsed {0}", timeElapsed));
-                       }
-
-                       PopEvent (args);
+                       GetBuildRecord (sender).PushEvent (sender, args);
+               }
+               void PopEvent<T> (object sender, T args) where T: BuildStatusEventArgs
+               {
+                       GetBuildRecord (sender).PopEvent (args);
                }
-
                public void ProjectStartedHandler (object sender, ProjectStartedEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
-                               SetColor (eventColor);
-                               WriteLine (String.Format ("Project \"{0}\" ({1} target(s)):", args.ProjectFile,
-                                                       String.IsNullOrEmpty (args.TargetNames) ? "default" : args.TargetNames));
-                               ResetColor ();
-                               DumpProperties (args.Properties);
-                               DumpItems (args.Items);
-                       }
+                       GetBuildRecord (sender).ProjectStartedHandler (args);
                }
-               
                public void ProjectFinishedHandler (object sender, ProjectFinishedEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
-                               if (indent == 1)
-                                       indent --;
-                               SetColor (eventColor);
-                               WriteLine (String.Format ("Done building project \"{0}\".{1}", args.ProjectFile,
-                                                       args.Succeeded ? String.Empty : "-- FAILED"));
-                               ResetColor ();
-                               WriteLine (String.Empty);
-                       }
-                       if (!projectFailed)
-                               // no project has failed yet, so update the flag
-                               projectFailed = !args.Succeeded;
-               }
-               
+                       GetBuildRecord (sender).ProjectFinishedHandler (args);
+               }               
                public void TargetStartedHandler (object sender, TargetStartedEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
-                               indent++;
-                               SetColor (eventColor);
-                               WriteLine (String.Empty);
-                               WriteLine (String.Format ("Target {0}:",args.TargetName));
-                               ResetColor ();
-                       }
+                       GetBuildRecord (sender).TargetStartedHandler (args);
                }
-               
                public void TargetFinishedHandler (object sender, TargetFinishedEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) ||
-                                       (!args.Succeeded && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal))) {
-                               SetColor (eventColor);
-                               WriteLine (String.Format ("Done building target \"{0}\" in project \"{1}\".{2}",
-                                       args.TargetName, args.ProjectFile,
-                                       args.Succeeded ? String.Empty : "-- FAILED"));
-                               ResetColor ();
-                               WriteLine (String.Empty);
-                       }
-                       indent--;
+                       GetBuildRecord (sender).TargetFinishedHandler (args);
                }
-               
                public void TaskStartedHandler (object sender, TaskStartedEventArgs args)
                {
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed)) {
-                               SetColor (eventColor);
-                               WriteLine (String.Format ("Task \"{0}\"",args.TaskName));
-                               ResetColor ();
-                       }
-                       indent++;
+                       GetBuildRecord (sender).TaskStartedHandler (args);
                }
-               
                public void TaskFinishedHandler (object sender, TaskFinishedEventArgs args)
                {
-                       indent--;
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) ||
-                                       (!args.Succeeded && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal))) {
-                               SetColor (eventColor);
-                               if (args.Succeeded)
-                                       WriteLine (String.Format ("Done executing task \"{0}\"", args.TaskName));
-                               else
-                                       WriteLine (String.Format ("Task \"{0}\" execution -- FAILED", args.TaskName));
-                               ResetColor ();
-                       }
+                       GetBuildRecord (sender).TaskFinishedHandler (args);
                }
-               
                public void MessageHandler (object sender, BuildMessageEventArgs args)
                {
-                       if (IsMessageOk (args)) {
-                               if (no_message_color) {
-                                       ExecutePendingEventHandlers ();
-                                       WriteLine (args.Message);
-                               } else {
-                                       ExecutePendingEventHandlers ();
-                                       SetColor (args.Importance == MessageImportance.High ? highMessageColor : messageColor);
-                                       WriteLine (args.Message);
-                                       ResetColor ();
-                               }
-                       }
+                       GetBuildRecord (sender).MessageHandler (args);
                }
-               
                public void WarningHandler (object sender, BuildWarningEventArgs args)
                {
-                       string msg = FormatWarningEvent (args);
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Quiet)) {
-                               ExecutePendingEventHandlers ();
-                               SetColor (warningColor);
-                               WriteLineWithoutIndent (msg);
-                               ResetColor ();
-                       }
-                       warnings.Add (msg);
-
-                       List<string> list = null;
-                       if (!warningsTable.TryGetValue (EventsAsString, out list))
-                               warningsTable [EventsAsString] = list = new List<string> ();
-                       list.Add (msg);
-
-                       warningCount++;
+                       GetBuildRecord (sender).WarningHandler (args);
                }
-               
                public void ErrorHandler (object sender, BuildErrorEventArgs args)
                {
-                       string msg = FormatErrorEvent (args);
-                       if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Quiet)) {
-                               ExecutePendingEventHandlers ();
-                               SetColor (errorColor);
-                               WriteLineWithoutIndent (msg);
-                               ResetColor ();
-                       }
-                       errors.Add (msg);
-
-                       List<string> list = null;
-                       if (!errorsTable.TryGetValue (EventsAsString, out list))
-                               errorsTable [EventsAsString] = list = new List<string> ();
-                       list.Add (msg);
-                       errorCount++;
+                       GetBuildRecord (sender).ErrorHandler (args);
                }
                
                [MonoTODO]
                public void CustomEventHandler (object sender, CustomBuildEventArgs args)
                {
-               }
-
-               private void WriteLine (string message)
-               {
-                       if (indent > 0) {
-                               StringBuilder sb = new StringBuilder ();
-                               for (int i = 0; i < indent; i++)
-                                       sb.Append ('\t');
-
-                               string indent_str = sb.ToString ();
-
-                               foreach (string line in message.Split (new string[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries))
-                                       writeHandler (indent_str + line);
-                       } else {
-                               writeHandler (message);
-                       }
-               }
-
-               void PushEvent<T> (object sender, T args) where T: BuildStatusEventArgs
-               {
-                       PushEvent (args);
-               }
-
-               void PushEvent<T> (T args) where T: BuildStatusEventArgs
-               {
-                       BuildEvent be = new BuildEvent {
-                               EventArgs = args,
-                               StartHandlerHasExecuted = false,
-                               ConsoleLogger = this
-                       };
-
-                       events.Add (be);
-                       current_events_string = null;
-               }
-
-               void PopEvent<T> (object sender, T finished_args) where T: BuildStatusEventArgs
-               {
-                       PopEvent (finished_args);
-               }
-
-               void PopEvent<T> (T finished_args) where T: BuildStatusEventArgs
-               {
-                       if (events.Count == 0)
-                               throw new InvalidOperationException ("INTERNAL ERROR: Trying to pop from an empty events stack");
-
-                       BuildEvent be = events [events.Count - 1];
-                       if (performanceSummary || verbosity == LoggerVerbosity.Diagnostic) {
-                               var args = be.EventArgs;
-                               TargetStartedEventArgs tgt_args = args as TargetStartedEventArgs;
-                               if (tgt_args != null) {
-                                       AddPerfInfo (tgt_args.TargetName, args.Timestamp, targetPerfTable);
-                               } else {
-                                       TaskStartedEventArgs tsk_args = args as TaskStartedEventArgs;
-                                       if (tsk_args != null)
-                                               AddPerfInfo (tsk_args.TaskName, args.Timestamp, tasksPerfTable);
-                               }
-                       }
-
-                       be.ExecuteFinishedHandler (finished_args);
-                       events.RemoveAt (events.Count - 1);
-                       current_events_string = null;
-               }
-
-               void ExecutePendingEventHandlers ()
-               {
-                       foreach (var be in events)
-                               be.ExecuteStartedHandler ();
-               }
-
-               string EventsToString ()
-               {
-                       StringBuilder sb = new StringBuilder ();
-
-                       string last_imported_target_file = String.Empty;
-                       for (int i = 0; i < events.Count; i ++) {
-                               var args = events [i].EventArgs;
-                               ProjectStartedEventArgs pargs = args as ProjectStartedEventArgs;
-                               if (pargs != null) {
-                                       sb.AppendFormat ("{0} ({1}) ->\n", pargs.ProjectFile,
-                                                       String.IsNullOrEmpty (pargs.TargetNames) ?
-                                                               "default targets" :
-                                                               pargs.TargetNames);
-                                       last_imported_target_file = String.Empty;
-                                       continue;
-                               }
-
-                               TargetStartedEventArgs targs = args as TargetStartedEventArgs;
-                               if (targs != null) {
-                                       if (targs.TargetFile != targs.ProjectFile && targs.TargetFile != last_imported_target_file)
-                                               // target from an imported file,
-                                               // and it hasn't been mentioned as yet
-                                               sb.AppendFormat ("{0} ", targs.TargetFile);
-
-                                       last_imported_target_file = targs.TargetFile;
-                                       sb.AppendFormat ("({0} target) ->\n", targs.TargetName);
-                               }
-                       }
-
-                       return sb.ToString ();
-               }
-
-               void AddPerfInfo (string name, DateTime start, IDictionary<string, PerfInfo> perf_table)
-               {
-                       PerfInfo pi;
-                       if (!perf_table.TryGetValue (name, out pi)) {
-                               pi = new PerfInfo ();
-                               perf_table [name] = pi;
-                       }
-
-                       pi.Time += DateTime.Now - start;
-                       pi.NumberOfCalls ++;
-               }
-
-               void DumpPerformanceSummary ()
-               {
-                       SetColor (eventColor);
-                       WriteLine ("Target perfomance summary:");
-                       ResetColor ();
-
-                       foreach (var pi in targetPerfTable.OrderBy (pair => pair.Value.Time))
-                               WriteLine (String.Format ("{0,10:0.000} ms  {1,-50}  {2,5} calls", pi.Value.Time.TotalMilliseconds, pi.Key, pi.Value.NumberOfCalls));
-
-                       WriteLine (String.Empty);
-
-                       SetColor (eventColor);
-                       WriteLine ("Tasks perfomance summary:");
-                       ResetColor ();
-
-                       foreach (var pi in tasksPerfTable.OrderBy (pair => pair.Value.Time))
-                               WriteLine (String.Format ("{0,10:0.000} ms  {1,-50}  {2,5} calls", pi.Value.Time.TotalMilliseconds, pi.Key, pi.Value.NumberOfCalls));
-
-                       WriteLine (String.Empty);
-               }
-               
-               private void WriteLineWithoutIndent (string message)
-               {
-                       writeHandler (message);
-               }
-               
-               private void WriteHandlerFunction (string message)
-               {
-                       Console.WriteLine (message);
+                       build_records [sender].CustomHandler (args);
                }
 
                void SetColor (ConsoleColor color)
@@ -694,131 +406,6 @@ namespace Microsoft.Build.BuildEngine {
                        eventSource.ErrorRaised -= ErrorHandler;
                }
 
-               static bool InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
-               
-               private string FormatErrorEvent (BuildErrorEventArgs args)
-               {
-                       // For some reason we get an 1-char empty string as Subcategory somtimes.
-                       string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
-                       string subcat = subprefix == "" ? "" : args.Subcategory;
-                               
-                       if (args.LineNumber != 0){
-                               if (args.ColumnNumber != 0 && !InEmacs) 
-                                       return String.Format ("{0}({1},{2}): {3}{4}error {5}: {6}",
-                                                             args.File, args.LineNumber, args.ColumnNumber,
-                                                             subprefix, subcat, args.Code, args.Message);
-
-                               return String.Format ("{0}({1}): {2}{3}error {4}: {5}",
-                                                     args.File, args.LineNumber,
-                                                     subprefix, subcat, args.Code, args.Message);
-                       } else {
-                               return String.Format ("{0}: {1}{2}error {3}: {4}", args.File, subprefix, subcat, args.Code,
-                                       args.Message);
-                       }
-               }
-
-               private string FormatWarningEvent (BuildWarningEventArgs args)
-               {
-                       // For some reason we get an 1-char empty string as Subcategory somtimes.
-                       string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
-                       string subcat = subprefix == "" ? "" : args.Subcategory;
-
-                       // FIXME: show more complicated args
-                       if (args.LineNumber != 0){
-
-                               if (args.ColumnNumber != 0 && !InEmacs) {
-                                       return String.Format ("{0}({1},{2}): {3}{4}warning {5}: {6}",
-                                                             args.File, args.LineNumber, args.ColumnNumber,
-                                                             subprefix, subcat, args.Code, args.Message);
-                               }
-                               return String.Format ("{0}({1}): {2}{3}warning {4}: {5}",
-                                                     args.File, args.LineNumber,
-                                                     subprefix, subcat, args.Code, args.Message);
-                       } else {
-                               return String.Format ("{0}: {1} warning {2}: {3}", args.File, args.Subcategory, args.Code,
-                                       args.Message);
-                       }
-               }
-               
-               private bool IsMessageOk (BuildMessageEventArgs bsea)
-               {
-                       if (bsea.Importance == MessageImportance.High && IsVerbosityGreaterOrEqual (LoggerVerbosity.Minimal)) {
-                               return true;
-                       } else if (bsea.Importance == MessageImportance.Normal && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
-                               return true;
-                       } else if (bsea.Importance == MessageImportance.Low && IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed)) {
-                               return true;
-                       } else
-                               return false;
-               }
-               
-                private bool IsVerbosityGreaterOrEqual (LoggerVerbosity v)
-                {
-                               if (v == LoggerVerbosity.Diagnostic) {
-                                       return LoggerVerbosity.Diagnostic <= verbosity;
-                               } else if (v == LoggerVerbosity.Detailed) {
-                                       return LoggerVerbosity.Detailed <= verbosity;
-                               } else if (v == LoggerVerbosity.Normal) {
-                                       return LoggerVerbosity.Normal <= verbosity;
-                               } else if (v == LoggerVerbosity.Minimal) {
-                                       return LoggerVerbosity.Minimal <= verbosity;
-                               } else if (v == LoggerVerbosity.Quiet) {
-                                       return true;
-                               } else
-                                       return false;
-                }
-
-               void DumpProperties (IEnumerable properties)
-               {
-                       if (noItemAndPropertyList || !IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic))
-                               return;
-
-                       SetColor (eventColor);
-                       WriteLine (String.Empty);
-                       WriteLine ("Initial Properties:");
-                       ResetColor ();
-
-                       if (properties == null)
-                               return;
-
-                       var dict = new SortedDictionary<string, string> ();
-                       foreach (DictionaryEntry de in properties)
-                               dict [(string)de.Key] = (string)de.Value;
-
-                       foreach (KeyValuePair<string, string> pair in dict)
-                               WriteLine (String.Format ("{0} = {1}", pair.Key, pair.Value));
-               }
-
-               void DumpItems (IEnumerable items)
-               {
-                       if (noItemAndPropertyList || !IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic) || items == null)
-                               return;
-
-                       SetColor (eventColor);
-                       WriteLine (String.Empty);
-                       WriteLine ("Initial Items:");
-                       ResetColor ();
-                       if (items == null)
-                               return;
-
-                       var items_table = new SortedDictionary<string, List<ITaskItem>> ();
-                       foreach (DictionaryEntry de in items) {
-                               string key = (string)de.Key;
-                               if (!items_table.ContainsKey (key))
-                                       items_table [key] = new List<ITaskItem> ();
-
-                               items_table [key].Add ((ITaskItem) de.Value);
-                       }
-
-                       foreach (string name in items_table.Keys) {
-                               WriteLine (name);
-                               indent ++;
-                               foreach (ITaskItem item in items_table [name])
-                                       WriteLine (item.ItemSpec);
-                               indent--;
-                       }
-               }
-
                public string Parameters {
                        get {
                                return parameters;
@@ -827,20 +414,13 @@ namespace Microsoft.Build.BuildEngine {
                                if (value == null)
                                        throw new ArgumentNullException ();
                                parameters = value;
-                       }
-               }
-
-               string EventsAsString {
-                       get {
-                               if (current_events_string == null)
-                                       current_events_string = EventsToString ();
-                               return current_events_string;
+                               ParseParameters ();
                        }
                }
                
                public bool ShowSummary {
-                       get { return showSummary; }
-                       set { showSummary = value; }
+                       get { return config.ShowSummary; }
+                       set { config.ShowSummary = value; }
                }
                
                public bool SkipProjectStartedText {
@@ -857,9 +437,561 @@ namespace Microsoft.Build.BuildEngine {
                        get { return writeHandler; }
                        set { writeHandler = value; }
                }
+               
+               class BuildRecord
+               {
+                       readonly ConsoleLogger parent;
+                       
+                       readonly List<BuildEvent> events;
+                       readonly Dictionary<string, List<string>> errorsTable;
+                       readonly Dictionary<string, List<string>> warningsTable;
+                       readonly SortedDictionary<string, PerfInfo> targetPerfTable, tasksPerfTable;
+                       List<string> errors, warnings;
+                       int             indent;
+                       int             errorCount;
+                       int             warningCount;
+                       bool            projectFailed;
+                       DateTime                buildStart;
+       
+                       string current_events_string;
+                       
+                       ConsoleColor eventColor {
+                               get { return parent.eventColor; }
+                       }
+                       LoggerVerbosity verbosity {
+                               get { return parent.Verbosity; }
+                       }
+                       
+                       public BuildRecord (ConsoleLogger parent)
+                       {
+                               this.parent = parent;
+                               
+                               this.indent = 0;
+                               this.errorCount = 0;
+                               this.warningCount = 0;
+                               errors = new List<string> ();
+                               warnings = new List<string> ();
+                               events = new List<BuildEvent> ();
+                               errorsTable = new Dictionary<string, List<string>> ();
+                               warningsTable = new Dictionary<string, List<string>> ();
+                               targetPerfTable = new SortedDictionary<string, PerfInfo> ();
+                               tasksPerfTable = new SortedDictionary<string, PerfInfo> ();
+                       }
+       
+                       internal void PushEvent<T> (object sender, T args) where T: BuildStatusEventArgs
+                       {
+                               BuildEvent be = new BuildEvent {
+                                       Sender = sender,
+                                       EventArgs = args,
+                                       StartHandlerHasExecuted = false,
+                                       ConsoleLogger = this.parent
+                               };
+       
+                               events.Add (be);
+                               current_events_string = null;
+                       }
+       
+                       void PopEvent<T> (object sender, T finished_args) where T: BuildStatusEventArgs
+                       {
+                               PopEvent (finished_args);
+                       }
+       
+                       internal void PopEvent<T> (T finished_args) where T: BuildStatusEventArgs
+                       {
+                               if (events.Count == 0)
+                                       throw new InvalidOperationException ("INTERNAL ERROR: Trying to pop from an empty events stack");
+       
+                               BuildEvent be = events [events.Count - 1];
+                               if (parent.config.PerformanceSummary || verbosity == LoggerVerbosity.Diagnostic) {
+                                       var args = be.EventArgs;
+                                       TargetStartedEventArgs tgt_args = args as TargetStartedEventArgs;
+                                       if (tgt_args != null) {
+                                               AddPerfInfo (tgt_args.TargetName, args.Timestamp, targetPerfTable);
+                                       } else {
+                                               TaskStartedEventArgs tsk_args = args as TaskStartedEventArgs;
+                                               if (tsk_args != null)
+                                                       AddPerfInfo (tsk_args.TaskName, args.Timestamp, tasksPerfTable);
+                                       }
+                               }
+       
+                               be.ExecuteFinishedHandler (finished_args);
+                               events.RemoveAt (events.Count - 1);
+                               current_events_string = null;
+                       }
+       
+                       public void ResetBuildState ()
+                       {
+                               // Reset
+                               events.Clear ();
+                               errorsTable.Clear ();
+                               warningsTable.Clear ();
+                               targetPerfTable.Clear ();
+                               tasksPerfTable.Clear ();
+                               errors.Clear ();
+                               warnings.Clear ();
+       
+                               indent = 0;
+                               errorCount = 0;
+                               warningCount = 0;
+                               projectFailed = false;
+                       }
+       
+                       void AddPerfInfo (string name, DateTime start, IDictionary<string, PerfInfo> perf_table)
+                       {
+                               PerfInfo pi;
+                               if (!perf_table.TryGetValue (name, out pi)) {
+                                       pi = new PerfInfo ();
+                                       perf_table [name] = pi;
+                               }
+       
+                               pi.Time += DateTime.Now - start;
+                               pi.NumberOfCalls ++;
+                       }
+       
+                       public void BuildStartedHandler (object sender, BuildStartedEventArgs args)
+                       {
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                                       WriteLine (String.Empty);
+                                       WriteLine (String.Format ("Build started {0}.", args.Timestamp));
+                                       WriteLine ("__________________________________________________");
+                               }
+                               buildStart = args.Timestamp;
+       
+                               PushEvent (sender, args);
+                       }
+                       
+                       public void BuildFinishedHandler (BuildFinishedEventArgs args)
+                       {
+                               BuildFinishedHandlerActual (args);
+                               
+                               ResetBuildState ();
+                       }
+       
+                       void BuildFinishedHandlerActual (BuildFinishedEventArgs args)
+                       {
+                               if (!IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                                       PopEvent (args);
+                                       return;
+                               }
+       
+                               TimeSpan timeElapsed = args.Timestamp - buildStart;
+                               if (parent.config.PerformanceSummary || verbosity == LoggerVerbosity.Diagnostic)
+                                       DumpPerformanceSummary ();
+       
+                               if (args.Succeeded == true && !projectFailed) {
+                                       WriteLine ("Build succeeded.");
+                               } else {
+                                       WriteLine ("Build FAILED.");
+                               }
+                               if (warnings.Count > 0) {
+                                       WriteLine (Environment.NewLine + "Warnings:");
+                                       SetColor (parent.warningColor);
+       
+                                       WriteLine (String.Empty);
+                                       foreach (KeyValuePair<string, List<string>> pair in warningsTable) {
+                                               if (!String.IsNullOrEmpty (pair.Key))
+                                                       WriteLine (pair.Key);
+       
+                                               string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
+                                               foreach (string msg in pair.Value)
+                                                       WriteLine (String.Format ("{0}{1}", indent_str, msg));
+       
+                                               WriteLine (String.Empty);
+                                       }
+       
+                                       ResetColor ();
+                               }
+       
+                               if (errors.Count > 0) {
+                                       WriteLine ("Errors:");
+                                       SetColor (parent.errorColor);
+       
+                                       WriteLine (String.Empty);
+                                       foreach (KeyValuePair<string, List<string>> pair in errorsTable) {
+                                               if (!String.IsNullOrEmpty (pair.Key))
+                                                       WriteLine (pair.Key);
+       
+                                               string indent_str = String.IsNullOrEmpty (pair.Key) ? String.Empty : "\t";
+                                               foreach (string msg in pair.Value)
+                                                       WriteLine (String.Format ("{0}{1}", indent_str, msg));
+       
+                                               WriteLine (String.Empty);
+                                       }
+                                       ResetColor ();
+                               }
+       
+                               if (parent.ShowSummary == true){
+                                       WriteLine (String.Format ("\t {0} Warning(s)", warningCount));
+                                       WriteLine (String.Format ("\t {0} Error(s)", errorCount));
+                                       WriteLine (String.Empty);
+                                       WriteLine (String.Format ("Time Elapsed {0}", timeElapsed));
+                               }
+       
+                               PopEvent (args);
+                       }
+       
+                       public void ProjectStartedHandler (ProjectStartedEventArgs args)
+                       {
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                                       SetColor (eventColor);
+                                       WriteLine (String.Format ("Project \"{0}\" ({1} target(s)):", args.ProjectFile,
+                                                               String.IsNullOrEmpty (args.TargetNames) ? "default" : args.TargetNames));
+                                       ResetColor ();
+                                       DumpProperties (args.Properties);
+                                       DumpItems (args.Items);
+                               }
+                       }
+                       
+                       public void ProjectFinishedHandler (ProjectFinishedEventArgs args)
+                       {
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                                       if (indent == 1)
+                                               indent --;
+                                       SetColor (eventColor);
+                                       WriteLine (String.Format ("Done building project \"{0}\".{1}", args.ProjectFile,
+                                                               args.Succeeded ? String.Empty : "-- FAILED"));
+                                       ResetColor ();
+                                       WriteLine (String.Empty);
+                               }
+                               if (!projectFailed)
+                                       // no project has failed yet, so update the flag
+                                       projectFailed = !args.Succeeded;
+                       }
+                       
+                       public void TargetStartedHandler (TargetStartedEventArgs args)
+                       {
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                                       indent++;
+                                       SetColor (eventColor);
+                                       WriteLine (String.Empty);
+                                       WriteLine (String.Format ("Target {0}:",args.TargetName));
+                                       ResetColor ();
+                               }
+                       }
+                       
+                       public void TargetFinishedHandler (TargetFinishedEventArgs args)
+                       {
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) ||
+                                               (!args.Succeeded && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal))) {
+                                       SetColor (eventColor);
+                                       WriteLine (String.Format ("Done building target \"{0}\" in project \"{1}\".{2}",
+                                               args.TargetName, args.ProjectFile,
+                                               args.Succeeded ? String.Empty : "-- FAILED"));
+                                       ResetColor ();
+                                       WriteLine (String.Empty);
+                               }
+                               indent--;
+                       }
+                       
+                       public void TaskStartedHandler (TaskStartedEventArgs args)
+                       {
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed)) {
+                                       SetColor (eventColor);
+                                       WriteLine (String.Format ("Task \"{0}\"",args.TaskName));
+                                       ResetColor ();
+                               }
+                               indent++;
+                       }
+                       
+                       public void TaskFinishedHandler (TaskFinishedEventArgs args)
+                       {
+                               indent--;
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed) ||
+                                               (!args.Succeeded && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal))) {
+                                       SetColor (eventColor);
+                                       if (args.Succeeded)
+                                               WriteLine (String.Format ("Done executing task \"{0}\"", args.TaskName));
+                                       else
+                                               WriteLine (String.Format ("Task \"{0}\" execution -- FAILED", args.TaskName));
+                                       ResetColor ();
+                               }
+                       }
+                       
+                       public void MessageHandler (BuildMessageEventArgs args)
+                       {
+                               if (IsMessageOk (args)) {
+                                       if (parent.no_message_color) {
+                                               ExecutePendingEventHandlers ();
+                                               WriteLine (args.Message);
+                                       } else {
+                                               ExecutePendingEventHandlers ();
+                                               SetColor (args.Importance == MessageImportance.High ? parent.highMessageColor : parent.messageColor);
+                                               WriteLine (args.Message);
+                                               ResetColor ();
+                                       }
+                               }
+                       }
+                       
+                       public void WarningHandler (BuildWarningEventArgs args)
+                       {
+                               string msg = FormatWarningEvent (args);
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Quiet)) {
+                                       ExecutePendingEventHandlers ();
+                                       SetColor (parent.warningColor);
+                                       WriteLineWithoutIndent (msg);
+                                       ResetColor ();
+                               }
+                               warnings.Add (msg);
+       
+                               List<string> list = null;
+                               if (!warningsTable.TryGetValue (EventsAsString, out list))
+                                       warningsTable [EventsAsString] = list = new List<string> ();
+                               list.Add (msg);
+       
+                               warningCount++;
+                       }
+                       
+                       public void ErrorHandler (BuildErrorEventArgs args)
+                       {
+                               string msg = FormatErrorEvent (args);
+                               if (IsVerbosityGreaterOrEqual (LoggerVerbosity.Quiet)) {
+                                       ExecutePendingEventHandlers ();
+                                       SetColor (parent.errorColor);
+                                       WriteLineWithoutIndent (msg);
+                                       ResetColor ();
+                               }
+                               errors.Add (msg);
+       
+                               List<string> list = null;
+                               if (!errorsTable.TryGetValue (EventsAsString, out list))
+                                       errorsTable [EventsAsString] = list = new List<string> ();
+                               list.Add (msg);
+                               errorCount++;
+                       }
+                       
+                       public void CustomHandler (CustomBuildEventArgs args)
+                       {
+                       }
+                       
+                       private bool IsVerbosityGreaterOrEqual (LoggerVerbosity v)
+                       {
+                               if (v == LoggerVerbosity.Diagnostic) {
+                                       return LoggerVerbosity.Diagnostic <= verbosity;
+                               } else if (v == LoggerVerbosity.Detailed) {
+                                       return LoggerVerbosity.Detailed <= verbosity;
+                               } else if (v == LoggerVerbosity.Normal) {
+                                       return LoggerVerbosity.Normal <= verbosity;
+                               } else if (v == LoggerVerbosity.Minimal) {
+                                       return LoggerVerbosity.Minimal <= verbosity;
+                               } else if (v == LoggerVerbosity.Quiet) {
+                                       return true;
+                               } else
+                                       return false;
+                       }
+       
+                       void DumpItems (IEnumerable items)
+                       {
+                               if (parent.config.NoItemAndPropertyList || !IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic) || items == null)
+                                       return;
+       
+                               SetColor (eventColor);
+                               WriteLine (String.Empty);
+                               WriteLine ("Initial Items:");
+                               ResetColor ();
+                               if (items == null)
+                                       return;
+       
+                               var items_table = new SortedDictionary<string, List<ITaskItem>> ();
+                               foreach (DictionaryEntry de in items) {
+                                       string key = (string)de.Key;
+                                       if (!items_table.ContainsKey (key))
+                                               items_table [key] = new List<ITaskItem> ();
+       
+                                       items_table [key].Add ((ITaskItem) de.Value);
+                               }
+       
+                               foreach (string name in items_table.Keys) {
+                                       WriteLine (name);
+                                       indent ++;
+                                       foreach (ITaskItem item in items_table [name])
+                                               WriteLine (item.ItemSpec);
+                                       indent--;
+                               }
+                       }
+       
+                       string EventsAsString {
+                               get {
+                                       if (current_events_string == null)
+                                               current_events_string = EventsToString ();
+                                       return current_events_string;
+                               }
+                       }
+                       
+                       private bool IsMessageOk (BuildMessageEventArgs bsea)
+                       {
+                               if (bsea.Importance == MessageImportance.High && IsVerbosityGreaterOrEqual (LoggerVerbosity.Minimal)) {
+                                       return true;
+                               } else if (bsea.Importance == MessageImportance.Normal && IsVerbosityGreaterOrEqual (LoggerVerbosity.Normal)) {
+                                       return true;
+                               } else if (bsea.Importance == MessageImportance.Low && IsVerbosityGreaterOrEqual (LoggerVerbosity.Detailed)) {
+                                       return true;
+                               } else
+                                       return false;
+                       }
+       
+                       void DumpProperties (IEnumerable properties)
+                       {
+                               if (parent.config.NoItemAndPropertyList || !IsVerbosityGreaterOrEqual (LoggerVerbosity.Diagnostic))
+                                       return;
+       
+                               SetColor (eventColor);
+                               WriteLine (String.Empty);
+                               WriteLine ("Initial Properties:");
+                               ResetColor ();
+       
+                               if (properties == null)
+                                       return;
+       
+                               var dict = new SortedDictionary<string, string> ();
+                               foreach (DictionaryEntry de in properties)
+                                       dict [(string)de.Key] = (string)de.Value;
+       
+                               foreach (KeyValuePair<string, string> pair in dict)
+                                       WriteLine (String.Format ("{0} = {1}", pair.Key, pair.Value));
+                       }
+       
+                       private void WriteLine (string message)
+                       {
+                               if (indent > 0) {
+                                       StringBuilder sb = new StringBuilder ();
+                                       for (int i = 0; i < indent; i++)
+                                               sb.Append ('\t');
+       
+                                       string indent_str = sb.ToString ();
+       
+                                       foreach (string line in message.Split (new string[] {Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries))
+                                               parent.writeHandler (indent_str + line);
+                               } else {
+                                       parent.writeHandler (message);
+                               }
+                       }
+       
+                       void ExecutePendingEventHandlers ()
+                       {
+                               foreach (var be in events)
+                                       be.ExecuteStartedHandler ();
+                       }
+       
+                       string EventsToString ()
+                       {
+                               StringBuilder sb = new StringBuilder ();
+       
+                               string last_imported_target_file = String.Empty;
+                               for (int i = 0; i < events.Count; i ++) {
+                                       var args = events [i].EventArgs;
+                                       ProjectStartedEventArgs pargs = args as ProjectStartedEventArgs;
+                                       if (pargs != null) {
+                                               sb.AppendFormat ("{0} ({1}) ->\n", pargs.ProjectFile,
+                                                               String.IsNullOrEmpty (pargs.TargetNames) ?
+                                                                       "default targets" :
+                                                                       pargs.TargetNames);
+                                               last_imported_target_file = String.Empty;
+                                               continue;
+                                       }
+       
+                                       TargetStartedEventArgs targs = args as TargetStartedEventArgs;
+                                       if (targs != null) {
+                                               if (targs.TargetFile != targs.ProjectFile && targs.TargetFile != last_imported_target_file)
+                                                       // target from an imported file,
+                                                       // and it hasn't been mentioned as yet
+                                                       sb.AppendFormat ("{0} ", targs.TargetFile);
+       
+                                               last_imported_target_file = targs.TargetFile;
+                                               sb.AppendFormat ("({0} target) ->\n", targs.TargetName);
+                                       }
+                               }
+       
+                               return sb.ToString ();
+                       }
+       
+                       void DumpPerformanceSummary ()
+                       {
+                               SetColor (eventColor);
+                               WriteLine ("Target perfomance summary:");
+                               ResetColor ();
+       
+                               foreach (var pi in targetPerfTable.OrderBy (pair => pair.Value.Time))
+                                       WriteLine (String.Format ("{0,10:0.000} ms  {1,-50}  {2,5} calls", pi.Value.Time.TotalMilliseconds, pi.Key, pi.Value.NumberOfCalls));
+       
+                               WriteLine (String.Empty);
+       
+                               SetColor (eventColor);
+                               WriteLine ("Tasks perfomance summary:");
+                               ResetColor ();
+       
+                               foreach (var pi in tasksPerfTable.OrderBy (pair => pair.Value.Time))
+                                       WriteLine (String.Format ("{0,10:0.000} ms  {1,-50}  {2,5} calls", pi.Value.Time.TotalMilliseconds, pi.Key, pi.Value.NumberOfCalls));
+       
+                               WriteLine (String.Empty);
+                       }
+                       
+                       private string FormatErrorEvent (BuildErrorEventArgs args)
+                       {
+                               // For some reason we get an 1-char empty string as Subcategory somtimes.
+                               string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
+                               string subcat = subprefix == "" ? "" : args.Subcategory;
+                                       
+                               if (args.LineNumber != 0){
+                                       if (args.ColumnNumber != 0 && !InEmacs) 
+                                               return String.Format ("{0}({1},{2}): {3}{4}error {5}: {6}",
+                                                                     args.File, args.LineNumber, args.ColumnNumber,
+                                                                     subprefix, subcat, args.Code, args.Message);
+       
+                                       return String.Format ("{0}({1}): {2}{3}error {4}: {5}",
+                                                             args.File, args.LineNumber,
+                                                             subprefix, subcat, args.Code, args.Message);
+                               } else {
+                                       return String.Format ("{0}: {1}{2}error {3}: {4}", args.File, subprefix, subcat, args.Code,
+                                               args.Message);
+                               }
+                       }
+       
+                       static bool InEmacs = Environment.GetEnvironmentVariable ("EMACS") == "t";
+       
+                       private string FormatWarningEvent (BuildWarningEventArgs args)
+                       {
+                               // For some reason we get an 1-char empty string as Subcategory somtimes.
+                               string subprefix = args.Subcategory == null || args.Subcategory == "" || args.Subcategory == " " ? "" : " ";
+                               string subcat = subprefix == "" ? "" : args.Subcategory;
+       
+                               // FIXME: show more complicated args
+                               if (args.LineNumber != 0){
+       
+                                       if (args.ColumnNumber != 0 && !InEmacs) {
+                                               return String.Format ("{0}({1},{2}): {3}{4}warning {5}: {6}",
+                                                                     args.File, args.LineNumber, args.ColumnNumber,
+                                                                     subprefix, subcat, args.Code, args.Message);
+                                       }
+                                       return String.Format ("{0}({1}): {2}{3}warning {4}: {5}",
+                                                             args.File, args.LineNumber,
+                                                             subprefix, subcat, args.Code, args.Message);
+                               } else {
+                                       return String.Format ("{0}: {1} warning {2}: {3}", args.File, args.Subcategory, args.Code,
+                                               args.Message);
+                               }
+                       }
+       
+                       void SetColor (ConsoleColor color)
+                       {
+                               if (parent.use_colors)
+                                       parent.colorSet (color);
+                       }
+       
+                       void ResetColor ()
+                       {
+                               if (parent.use_colors)
+                                       parent.colorReset ();
+                       }
+                       
+                       private void WriteLineWithoutIndent (string message)
+                       {
+                               parent.writeHandler (message);
+                       }
+               }
        }
 
        class BuildEvent {
+               public object Sender; 
                public BuildStatusEventArgs EventArgs;
                public bool StartHandlerHasExecuted;
                public ConsoleLogger ConsoleLogger;
@@ -870,11 +1002,11 @@ namespace Microsoft.Build.BuildEngine {
                                return;
 
                        if (EventArgs is ProjectStartedEventArgs)
-                               ConsoleLogger.ProjectStartedHandler (null, (ProjectStartedEventArgs)EventArgs);
+                               ConsoleLogger.ProjectStartedHandler (Sender, (ProjectStartedEventArgs)EventArgs);
                        else if (EventArgs is TargetStartedEventArgs)
-                               ConsoleLogger.TargetStartedHandler (null, (TargetStartedEventArgs)EventArgs);
+                               ConsoleLogger.TargetStartedHandler (Sender, (TargetStartedEventArgs)EventArgs);
                        else if (EventArgs is TaskStartedEventArgs)
-                               ConsoleLogger.TaskStartedHandler (null, (TaskStartedEventArgs)EventArgs);
+                               ConsoleLogger.TaskStartedHandler (Sender, (TaskStartedEventArgs)EventArgs);
                        else if (!(EventArgs is BuildStartedEventArgs))
                                throw new InvalidOperationException ("Unexpected event on the stack, type: " + EventArgs.GetType ());
 
@@ -887,11 +1019,11 @@ namespace Microsoft.Build.BuildEngine {
                                return;
 
                        if (EventArgs is ProjectStartedEventArgs)
-                               ConsoleLogger.ProjectFinishedHandler (null, finished_args as ProjectFinishedEventArgs);
+                               ConsoleLogger.ProjectFinishedHandler (Sender, finished_args as ProjectFinishedEventArgs);
                        else if (EventArgs is TargetStartedEventArgs)
-                               ConsoleLogger.TargetFinishedHandler (null, finished_args as TargetFinishedEventArgs);
+                               ConsoleLogger.TargetFinishedHandler (Sender, finished_args as TargetFinishedEventArgs);
                        else if (EventArgs is TaskStartedEventArgs)
-                               ConsoleLogger.TaskFinishedHandler (null, finished_args as TaskFinishedEventArgs);
+                               ConsoleLogger.TaskFinishedHandler (Sender, finished_args as TaskFinishedEventArgs);
                        else if (!(EventArgs is BuildStartedEventArgs))
                                throw new InvalidOperationException ("Unexpected event on the stack, type: " + EventArgs.GetType ());
                }
index 9e0f90703ae17c83bf2810d4d34a30b8a151f8e6..3a970f3013050184c1c880ac4b9546bb149944c3 100644 (file)
@@ -32,7 +32,12 @@ using System.IO;
 using System.Text;
 using Microsoft.Build.Framework;
 
-namespace Microsoft.Build.BuildEngine {
+#if MICROSOFT_BUILD_DLL
+namespace Microsoft.Build.Logging
+#else
+namespace Microsoft.Build.BuildEngine
+#endif
+{
        public class FileLogger : ConsoleLogger {
                StreamWriter sw;
                string logfile;
index 250c7942bd1abfc0d448cfca22495f57c8815092..630cb4a46e17d3041591275fc7f4b78c67cfda71 100644 (file)
@@ -128,15 +128,23 @@ namespace Microsoft.Build.BuildEngine {
                internal bool Build (string built_targets_key)
                {
                        bool executeOnErrors;
-                       return Build (built_targets_key, out executeOnErrors);
+                       return Build (built_targets_key, null, out executeOnErrors);
                }
 
-               bool Build (string built_targets_key, out bool executeOnErrors)
+               bool Build (string built_targets_key, string parentTarget, out bool executeOnErrors)
                {
+                       string message;
+                       if (parentTarget != null)
+                               message = string.Format ("\"{0}\" in project \"{1}\" (\"{2}\"); \"{3}\" depends on it", Name, project.FullFileName, TargetFile, parentTarget);
+                       else
+                               message = string.Format ("\"{0}\" in project \"{1}\" (\"{2}\")", Name, project.FullFileName, TargetFile);
+
                        project.PushThisFileProperty (TargetFile);
                        try {
+                               LogMessage (MessageImportance.Low, "Building target {0}.", message);
                                return BuildActual (built_targets_key, out executeOnErrors);
                        } finally {
+                               LogMessage (MessageImportance.Low, "Done building target {0}.", message);
                                project.PopThisFileProperty ();
                        }
                }
@@ -256,7 +264,7 @@ namespace Microsoft.Build.BuildEngine {
                                }
 
                                if (t.BuildState == BuildState.NotStarted)
-                                       if (!t.Build (null, out executeOnErrors))
+                                       if (!t.Build (null, Name, out executeOnErrors))
                                                return false;
 
                                if (t.BuildState == BuildState.Started)
@@ -403,9 +411,12 @@ namespace Microsoft.Build.BuildEngine {
 
                ITaskItem [] OutputsAsITaskItems {
                        get {
-                               string outputs = targetElement.GetAttribute ("Outputs");
-                               if (outputs == String.Empty)
-                                       return new ITaskItem [0];
+                               var outputs = targetElement.GetAttribute ("Returns");
+                               if (string.IsNullOrEmpty (outputs)) {
+                                       outputs = targetElement.GetAttribute ("Outputs");
+                                       if (string.IsNullOrEmpty (outputs))
+                                               return new ITaskItem [0];
+                               }
 
                                Expression e = new Expression ();
                                e.Parse (outputs, ParseOptions.AllowItemsNoMetadataAndSplit);
index d60bd5be68f3ac3b4b1f1065b26d1aa7642660ba..a7575519ca28f31c697d526340b9441f6623a07d 100644 (file)
 // 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 Microsoft.Build.BuildEngine {
+#if MICROSOFT_BUILD_DLL
+namespace Microsoft.Build.Logging
+#else
+namespace Microsoft.Build.BuildEngine
+#endif
+{
        public delegate void WriteHandler (string message);
 }
index 2cced758f0500df01a85ad1a717b5bb81b709a68..738cd2a25878de66ac2f3684e2702e655cb8ef88 100644 (file)
@@ -402,6 +402,11 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                }
 
                void ItemGroupInsideTarget (string xml, params string[] messages)
+               {
+                       ItemGroupInsideTarget (xml, 1, messages);
+               }
+
+               void ItemGroupInsideTarget (string xml, int expectedTargetCount, params string[] messages)
                {
                        var logger = CreateLogger (xml);
                        
@@ -411,9 +416,10 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                for (int i = 0; i < messages.Length; i++)
                                        logger.CheckLoggedMessageHead (messages [i], i.ToString ());
                                Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+                               Assert.AreEqual(0, logger.WarningMessageCount, "Extra warningmessages found");
                                
-                               Assert.AreEqual(1, logger.TargetStarted, "TargetStarted count");
-                               Assert.AreEqual(1, logger.TargetFinished, "TargetFinished count");
+                               Assert.AreEqual(expectedTargetCount, logger.TargetStarted, "TargetStarted count");
+                               Assert.AreEqual(expectedTargetCount, logger.TargetFinished, "TargetFinished count");
                                Assert.AreEqual(messages.Length, logger.TaskStarted, "TaskStarted count");
                                Assert.AreEqual(messages.Length, logger.TaskFinished, "TaskFinished count");
                        }
@@ -727,6 +733,59 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                                        </Target>
                                </Project>", "Sun", "Rain");
                }
+
+               [Test]
+               public void PropertyGroupInsideTarget_Condition ()
+               {
+                       ItemGroupInsideTarget (
+                               @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+                                       <ItemGroup>
+                                               <Shells Include=""/bin/sh;/bin/bash;/bin/false"" />
+                                       </ItemGroup>
+
+                                       <Target Name='Main'>
+                                               <PropertyGroup>
+                                                       <HasBash Condition=""'%(Shells.Filename)' == 'bash'"">true</HasBash>
+                                               </PropertyGroup>
+
+                                               <ItemGroup Condition=""'$(HasBash)' == 'true'"">
+                                                       <Weather Include='Rain' />
+                                               </ItemGroup>
+                                               <Message Text='%(Weather.Identity)' />
+                                       </Target>
+                               </Project>", "Rain");
+               }
+
+               [Test]
+               // Bug #14661
+               public void ItemGroupInsideTarget_Expression_in_Metadata ()
+               {
+                       ItemGroupInsideTarget (
+                       @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+                               <ItemGroup>
+                                       <Foo Include='output1'>
+                                               <Inputs>input1a;input1b</Inputs>
+                                       </Foo>
+                                       <Foo Include='output2'>
+                                               <Inputs>input2a;input2b</Inputs>
+                                       </Foo>
+                               </ItemGroup>
+
+                               <Target Name='Main' DependsOnTargets='_PrepareItems' Inputs='@(_Foo)' Outputs='%(Result)'>
+                                       <Message Text='COMPILE: @(_Foo) - %(_Foo.Result)' />
+                               </Target>
+
+                               <Target Name='_PrepareItems'>
+                                       <ItemGroup>
+                                               <_Foo Include='%(Foo.Inputs)'>
+                                                       <Result>%(Foo.Identity)</Result>
+                                               </_Foo>
+                                       </ItemGroup>
+                               </Target>
+                       </Project>",
+                       3, "COMPILE: input1a;input1b - output1", "COMPILE: input2a;input2b - output2");
+               }
+
                #endif
 
                [Test]
@@ -905,5 +964,26 @@ namespace MonoTests.Microsoft.Build.BuildEngine {
                }
 #endif
 
+               [Test]
+               public void TestTargetReturns ()
+               {
+                       engine = new Engine (Consts.BinPath);
+                       project = engine.CreateNewProject ();
+                       project.Load (Path.Combine ("Test", Path.Combine ("resources", "TestReturns.csproj")));
+
+                       var logger = new TestMessageLogger ();
+                       engine.RegisterLogger (logger);
+
+                       bool result = project.Build ("Main");
+                       if (!result) {
+                               logger.DumpMessages ();
+                               Assert.Fail ("Build failed");
+                       }
+
+                       logger.CheckLoggedMessageHead ("Result: Bar", "A1");
+
+                       Assert.AreEqual (0, logger.NormalMessageCount, "Unexpected extra messages found");
+               }
+
        }
 }
diff --git a/mcs/class/Microsoft.Build.Engine/Test/resources/TestReturns.csproj b/mcs/class/Microsoft.Build.Engine/Test/resources/TestReturns.csproj
new file mode 100644 (file)
index 0000000..a71ea5d
--- /dev/null
@@ -0,0 +1,13 @@
+<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
+
+       <Target Name="GetFoo" Outputs="Out" Returns="Bar" />
+
+       <Target Name="Main">
+               <MSBuild Projects="TestReturns.csproj" Targets="GetFoo">
+                       <Output TaskParameter="TargetOutputs" ItemName="FooResult"/>
+               </MSBuild>
+               
+               <Message Text="Result: %(FooResult.Identity)" />
+       </Target>
+
+</Project>
index 255a6855403b77f4c94844f0b41bde24ea9826f7..d24bf602ad312d6d77f7dc9feef2a67b290f7c2e 100644 (file)
@@ -2,9 +2,11 @@
 ../../build/common/MonoTODOAttribute.cs
 Assembly/AssemblyInfo.cs
 Microsoft.Build.Framework/AnyEventHandler.cs
+Microsoft.Build.Framework/BuildEngineResult.cs
 Microsoft.Build.Framework/BuildErrorEventArgs.cs
 Microsoft.Build.Framework/BuildErrorEventHandler.cs
 Microsoft.Build.Framework/BuildEventArgs.cs
+Microsoft.Build.Framework/BuildEventContext.cs
 Microsoft.Build.Framework/BuildFinishedEventArgs.cs
 Microsoft.Build.Framework/BuildFinishedEventHandler.cs
 Microsoft.Build.Framework/BuildMessageEventArgs.cs
@@ -21,11 +23,17 @@ Microsoft.Build.Framework/ExternalProjectFinishedEventArgs.cs
 Microsoft.Build.Framework/ExternalProjectStartedEventArgs.cs
 Microsoft.Build.Framework/IBuildEngine.cs
 Microsoft.Build.Framework/IBuildEngine2.cs
+Microsoft.Build.Framework/IBuildEngine3.cs
+Microsoft.Build.Framework/IBuildEngine4.cs
 Microsoft.Build.Framework/ICancelableTask.cs
+Microsoft.Build.Framework/IEventRedirector.cs
 Microsoft.Build.Framework/IEventSource.cs
+Microsoft.Build.Framework/IForwardingLogger.cs
 Microsoft.Build.Framework/ILogger.cs
 Microsoft.Build.Framework/INodeLogger.cs
 Microsoft.Build.Framework/ITask.cs
+Microsoft.Build.Framework/ITaskFactory.cs
+Microsoft.Build.Framework/ITaskFactory2.cs
 Microsoft.Build.Framework/ITaskHost.cs
 Microsoft.Build.Framework/ITaskItem.cs
 Microsoft.Build.Framework/ITaskItem2.cs
@@ -39,6 +47,7 @@ Microsoft.Build.Framework/ProjectFinishedEventArgs.cs
 Microsoft.Build.Framework/ProjectFinishedEventHandler.cs
 Microsoft.Build.Framework/ProjectStartedEventArgs.cs
 Microsoft.Build.Framework/ProjectStartedEventHandler.cs
+Microsoft.Build.Framework/RegisteredTaskObjectLifetime.cs
 Microsoft.Build.Framework/RequiredAttribute.cs
 Microsoft.Build.Framework/TargetFinishedEventArgs.cs
 Microsoft.Build.Framework/TargetFinishedEventHandler.cs
@@ -47,5 +56,7 @@ Microsoft.Build.Framework/TargetStartedEventHandler.cs
 Microsoft.Build.Framework/TaskCommandLineEventArgs.cs
 Microsoft.Build.Framework/TaskFinishedEventArgs.cs
 Microsoft.Build.Framework/TaskFinishedEventHandler.cs
+Microsoft.Build.Framework/TaskPropertyInfo.cs
 Microsoft.Build.Framework/TaskStartedEventArgs.cs
 Microsoft.Build.Framework/TaskStartedEventHandler.cs
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEngineResult.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEngineResult.cs
new file mode 100644 (file)
index 0000000..05b65f1
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.Framework
+{
+       [SerializableAttribute]
+       public struct BuildEngineResult
+       {
+               public BuildEngineResult (bool result, List<IDictionary<string, ITaskItem[]>> targetOutputsPerProject)
+               {
+                       this.result = result;
+                       this.outputs = targetOutputsPerProject;
+               }
+
+               readonly bool result;
+               public bool Result {
+                       get { return result; }
+               }
+
+               readonly IList<IDictionary<string, ITaskItem[]>> outputs;
+               public IList<IDictionary<string, ITaskItem[]>> TargetOutputsPerProject {
+                       get { return outputs; }
+               }
+       }
+}
index f94f11c265a1b8b5ae660b5b245112f647ee762b..fd2c709dd04411aed849f3a2aaf7a238707572f6 100644 (file)
@@ -41,7 +41,8 @@ namespace Microsoft.Build.Framework
                string  senderName;
                int     threadId;
                DateTime        timestamp;
-               
+               BuildEventContext context;
+
                protected BuildEventArgs ()
                        : this (null, null, null)
                {
@@ -61,6 +62,7 @@ namespace Microsoft.Build.Framework
                        this.senderName = senderName;
                        this.threadId = Thread.CurrentThread.GetHashCode ();
                        this.timestamp = eventTimestamp;
+                       this.context = BuildEventContext.NewInstance ();
                }
 
                public string HelpKeyword {
@@ -93,6 +95,15 @@ namespace Microsoft.Build.Framework
                                return timestamp;
                        }
                }
+
+               public BuildEventContext BuildEventContext {
+                       get { return context; }
+                       set {
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
+                               context = value;
+                       }
+               }
        }
 }
 
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEventContext.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/BuildEventContext.cs
new file mode 100644 (file)
index 0000000..2a550f4
--- /dev/null
@@ -0,0 +1,94 @@
+using System;
+
+
+namespace Microsoft.Build.Framework
+{
+       [Serializable]
+       public class BuildEventContext
+       {
+               static readonly Random rnd = new Random ();
+
+               public static BuildEventContext Invalid = new BuildEventContext (
+                       InvalidSubmissionId,
+                       InvalidNodeId,
+                       InvalidProjectInstanceId,
+                       InvalidTargetId,
+                       InvalidProjectContextId,
+                       InvalidTaskId);
+
+               internal static BuildEventContext NewInstance ()
+               {
+                       return new BuildEventContext (rnd.Next (), rnd.Next (), rnd.Next (), rnd.Next ());
+               }
+
+               public BuildEventContext (int nodeId, int targetId, int projectContextId, int taskId)
+                       : this (nodeId, rnd.Next (), targetId, projectContextId, taskId)
+               {
+               }
+
+               public BuildEventContext (int nodeId, int projectInstanceId, int targetId, int projectContextId, int taskId)
+                       : this (rnd.Next (), nodeId, projectInstanceId, targetId, projectContextId, taskId)
+               {
+               }
+
+               public BuildEventContext (int submissionId, int nodeId, int projectInstanceId, int targetId, int projectContextId, int taskId)
+               {
+                       SubmissionId = submissionId;
+                       NodeId = nodeId;
+                       ProjectInstanceId = projectInstanceId;
+                       TargetId = targetId;
+                       ProjectContextId = projectContextId;
+                       TaskId = taskId;
+               }
+
+               public const int InvalidSubmissionId = -1;
+               public const int InvalidNodeId = -2;
+               public const int InvalidProjectInstanceId = -1;
+               public const int InvalidTargetId = -1;
+               public const int InvalidProjectContextId = -2;
+               public const int InvalidTaskId = -1;
+
+               public int SubmissionId { get; private set; }
+               public int NodeId { get; private set; }
+               public int ProjectInstanceId { get; private set; }
+               public int TargetId { get; private set; }
+               public int ProjectContextId { get; private set; }
+               public int TaskId { get; private set; }
+
+               // MSDN document says "true if the references are equal, false otherwise." but that doesn't make sense.
+               public override bool Equals (object other)
+               {
+                       var o = other as BuildEventContext;
+                       return (object) o != null &&
+                               o.NodeId == NodeId &&
+                               o.ProjectContextId == ProjectContextId &&
+                               o.ProjectInstanceId == ProjectInstanceId &&
+                               o.SubmissionId == SubmissionId &&
+                               o.TargetId == TargetId &&
+                               o.TaskId == TaskId;
+               }
+
+               public override int GetHashCode ()
+               {
+                       return
+                               (NodeId << 5) +
+                               (ProjectContextId << 4) +
+                               (ProjectInstanceId << 3) +
+                               (SubmissionId << 2) +
+                               (TargetId << 1) +
+                               TaskId;
+               }
+
+               public static bool operator == (BuildEventContext left, BuildEventContext right)
+               {
+                       return (object) left == null ? (object)right == null : left.Equals (right);
+               }
+
+               public static bool operator != (BuildEventContext left, BuildEventContext right)
+               {
+                       return (object) left == null ? (object)right != null : !left.Equals (right);
+               }
+       }
+}
+
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine3.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine3.cs
new file mode 100644 (file)
index 0000000..b4ce06a
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.Framework
+{
+       [MonoTODO]
+       public interface IBuildEngine3 : IBuildEngine2
+       {
+               BuildEngineResult BuildProjectFilesInParallel (
+                       string[] projectFileNames,
+                       string[] targetNames,
+                       IDictionary[] globalProperties,
+                       IList<string>[] removeGlobalProperties,
+                       string[] toolsVersion,
+                       bool returnTargetOutputs
+               );
+               void Reacquire ();
+               void Yield ();
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine4.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IBuildEngine4.cs
new file mode 100644 (file)
index 0000000..c2c16b4
--- /dev/null
@@ -0,0 +1,15 @@
+#if NET_4_5
+using System;
+
+namespace Microsoft.Build.Framework
+{
+       [MonoTODO]
+       public interface IBuildEngine4 : IBuildEngine3
+       {
+               object GetRegisteredTaskObject (object key, RegisteredTaskObjectLifetime lifetime);
+               void RegisterTaskObject (object key, object obj, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection);
+               object UnregisterTaskObject (object key, RegisteredTaskObjectLifetime lifetime);
+       }
+}
+
+#endif
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IEventRedirector.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IEventRedirector.cs
new file mode 100644 (file)
index 0000000..3078c20
--- /dev/null
@@ -0,0 +1,10 @@
+using System;
+
+namespace Microsoft.Build.Framework
+{
+       public interface IEventRedirector
+       {
+               void ForwardEvent (BuildEventArgs buildEvent);
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IForwardingLogger.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/IForwardingLogger.cs
new file mode 100644 (file)
index 0000000..4b08961
--- /dev/null
@@ -0,0 +1,15 @@
+using System;
+
+#if NET_4_0
+
+namespace Microsoft.Build.Framework
+{
+       public interface IForwardingLogger : INodeLogger, ILogger
+       {
+               IEventRedirector BuildEventRedirector { get; set; }
+               int NodeId { get; set; }
+       }
+}
+
+#endif
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskFactory.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskFactory.cs
new file mode 100644 (file)
index 0000000..0d6820b
--- /dev/null
@@ -0,0 +1,16 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.Framework
+{
+       public interface ITaskFactory
+       {
+               string FactoryName { get; }
+               Type TaskType { get; }
+               void CleanupTask (ITask task);
+               ITask CreateTask (IBuildEngine taskFactoryLoggingHost);
+               TaskPropertyInfo [] GetTaskParameters ();
+               bool Initialize (string taskName, IDictionary<string, TaskPropertyInfo> parameterGroup, string taskBody, IBuildEngine taskFactoryLoggingHost);
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskFactory2.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/ITaskFactory2.cs
new file mode 100644 (file)
index 0000000..9b53560
--- /dev/null
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.Framework
+{
+       public interface ITaskFactory2 : ITaskFactory
+       {
+               ITask CreateTask (IBuildEngine taskFactoryLoggingHost, IDictionary<string, string> taskIdentityParameters);
+               bool Initialize (string taskName, IDictionary<string, string> factoryIdentityParameters, IDictionary<string, TaskPropertyInfo> parameterGroup, string taskBody, IBuildEngine taskFactoryLoggingHost);
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/RegisteredTaskObjectLifetime.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/RegisteredTaskObjectLifetime.cs
new file mode 100644 (file)
index 0000000..1211078
--- /dev/null
@@ -0,0 +1,11 @@
+#if NET_4_5
+namespace Microsoft.Build.Framework
+{
+       public enum RegisteredTaskObjectLifetime
+       {
+               AppDomain,
+               Build
+       }
+}
+#endif
+
diff --git a/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/TaskPropertyInfo.cs b/mcs/class/Microsoft.Build.Framework/Microsoft.Build.Framework/TaskPropertyInfo.cs
new file mode 100644 (file)
index 0000000..a6fbfaa
--- /dev/null
@@ -0,0 +1,23 @@
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.Framework
+{
+       [Serializable]
+       public class TaskPropertyInfo
+       {
+               public TaskPropertyInfo (string name, Type typeOfParameter, bool output, bool required)
+               {
+                       Name = name;
+                       PropertyType = typeOfParameter;
+                       Output = output;
+                       Required = required;
+               }
+               
+               public string Name { get; private set; }
+               public bool Output { get; private set; }
+               public Type PropertyType { get; private set; }
+               public bool Required { get; private set; }
+       }
+}
+
index 45374e536e127af7e6121b93e9449a5f749fd62c..b7c639277aec24f48c0e936b29afb771bd2e4af6 100644 (file)
@@ -1,5 +1,6 @@
 Microsoft.Build.Framework/BuildErrorEventArgsTest.cs
 Microsoft.Build.Framework/BuildEventArgsTest.cs
+Microsoft.Build.Framework/BuildEventContextTest.cs
 Microsoft.Build.Framework/BuildFinishedEventArgsTest.cs
 Microsoft.Build.Framework/BuildMessageEventArgsTest.cs
 Microsoft.Build.Framework/BuildStartedEventArgsTest.cs
diff --git a/mcs/class/Microsoft.Build.Framework/Test/Microsoft.Build.Framework/BuildEventContextTest.cs b/mcs/class/Microsoft.Build.Framework/Test/Microsoft.Build.Framework/BuildEventContextTest.cs
new file mode 100644 (file)
index 0000000..ea8ff11
--- /dev/null
@@ -0,0 +1,29 @@
+using System;
+using Microsoft.Build.Framework;
+using NUnit.Framework;
+
+namespace MonoTests.Microsoft.Build.Framework
+{
+       [TestFixture]
+       public class BuildEventContextTest
+       {
+               [Test]
+               public void Compare ()
+               {
+                       Assert.IsTrue (BuildEventContext.Invalid == BuildEventContext.Invalid, "#1");
+                       Assert.IsFalse (BuildEventContext.Invalid != BuildEventContext.Invalid, "#2");
+                       var inst = new BuildEventContext (0, 0, 0, 0);
+                       Assert.IsFalse (BuildEventContext.Invalid == inst, "#3");
+                       Assert.IsTrue (BuildEventContext.Invalid != inst, "#4");
+                       Assert.IsFalse (BuildEventContext.Invalid == null, "#5");
+                       Assert.IsTrue (BuildEventContext.Invalid != null, "#6");
+                       Assert.IsFalse (BuildEventContext.Invalid.Equals (null), "#7");
+                       Assert.IsFalse (BuildEventContext.Invalid.Equals (inst), "#8");
+                       Assert.IsTrue (BuildEventContext.Invalid.Equals (BuildEventContext.Invalid), "#9");
+                       Assert.IsFalse (inst.Equals (null), "#10");
+                       Assert.IsTrue (inst.Equals (inst), "#11");
+                       Assert.IsFalse (inst.Equals (BuildEventContext.Invalid), "#12");
+               }
+       }
+}
+
index 2e457d5716b32da066f65e0802bfdfd5e171a91d..1461e176b4ae03be3e4245ed535dbf0e9c09983d 100755 (executable)
@@ -369,7 +369,8 @@ namespace MonoTests.Microsoft.Build.Tasks
                        CheckLoggedMessageAny (testLogger, "Number: 2 Color: Red-- Items in ExampColl:  ExampColl2: Item5", "A3");
                        CheckLoggedMessageAny (testLogger, "Number: 3 Color: Green-- Items in ExampColl:  ExampColl2: Item6", "A4");
                        CheckLoggedMessageAny (testLogger, "Number: 2 Color: -- Items in ExampColl: Item2 ExampColl2: ", "A5");
-                       Assert.AreEqual (0, testLogger.Count, "A6");
+                       Assert.AreEqual (0, testLogger.NormalMessageCount, "A6");
+                       Assert.AreEqual (0, testLogger.WarningMessageCount, "A7");
                        CheckEngineEventCounts (testLogger, 1, 1, 4, 4);
                }
 
@@ -459,7 +460,8 @@ namespace MonoTests.Microsoft.Build.Tasks
                        CheckLoggedMessageAny (testLogger, "Identity: Item4 -- Items in ExampColl: Item4;Item4", "A5");
                        CheckLoggedMessageAny (testLogger, "Identity: Item5 -- Items in ExampColl: Item5", "A6");
                        CheckLoggedMessageAny (testLogger, "Identity: Item6 -- Items in ExampColl: Item6", "A7");
-                       Assert.AreEqual (0, testLogger.Count, "A8");
+                       Assert.AreEqual (0, testLogger.NormalMessageCount, "A8");
+                       Assert.AreEqual (0, testLogger.WarningMessageCount, "A7");
                        CheckEngineEventCounts (testLogger, 1, 1, 6, 6);
                }
 
index 364b575ebe27017f2ab7a1152615ad659231ecf3..c6ca1a23901239cb1404143e2dc931d009ef10c0 100644 (file)
@@ -129,6 +129,18 @@ namespace MonoTests.Microsoft.Build.Tasks
                        }
                }
 
+               public int WarningMessageCount {
+                       get {
+                               int count = 0, i = 0;
+                               while (i++ < messages.Count) {
+                                       var importance = messages [i - 1].Importance;
+                                       if (importance == MessageImportance.High)
+                                               count++;
+                               }
+                               return count;
+                       }
+               }
+
                public int CheckHead (string text, MessageImportance importance)
                {
                        string actual_msg;
index 4401042a60d0e41b8bd39be6e6db28ed9ccec604..0906ef3ebf5cda566ecd857f35a602276fa27777 100644 (file)
@@ -31,7 +31,12 @@ namespace Microsoft.Build.Utilities
 {
        // If changing something here then update
        // ToolLocationHelper.GetPathToDotNetFramework also
-       public enum TargetDotNetFrameworkVersion
+       #if MICROSOFT_BUILD_DLL
+       internal
+       #else
+       public
+       #endif
+       enum TargetDotNetFrameworkVersion
        {
                Version11,
                Version20,
index d917d3e6a358d061fd74f11f8bd690fd9f32b23c..a65cb37bedddb3eba5e452150e61e25efcc57529 100644 (file)
@@ -36,7 +36,10 @@ using Mono.XBuild.Utilities;
 
 namespace Microsoft.Build.Utilities
 {
-       public sealed class TaskItem : MarshalByRefObject, ITaskItem
+#if !MICROSOFT_BUILD_DLL
+       public
+#endif
+       sealed class TaskItem : MarshalByRefObject, ITaskItem
        {
                IDictionary             metadata;
                string                  itemSpec;
index f16603fcfd0dc4d70f1bdf507feb4f40f636fe56..e61094bc8676f7ee479fd91c7563ec7983308d4a 100644 (file)
@@ -30,7 +30,12 @@ using System.IO;
 
 namespace Microsoft.Build.Utilities
 {
-       public static class ToolLocationHelper
+       #if MICROSOFT_BUILD_DLL
+       internal
+       #else
+       public
+       #endif
+       static class ToolLocationHelper
        {
                static string lib_mono_dir;
                static string [] mono_dir;
index f0f26c7675e90d5c0e985f1eb47f76128e2e8d68..b9d060f23bf2651401251edeed1a26e5896a44fa 100644 (file)
@@ -3,3 +3,4 @@ bin/
 *.vs10x
 *.docstates
 *.suo
+Microsoft.Build.Internal/ExpressionParser.cs
index 339dd9094efad8897e0fb38bb435ac4272dc3eab..f41641208cc7aa697cd516c7564673b8c11eec36 100644 (file)
@@ -17,20 +17,28 @@ LIB_MCS_FLAGS = \
        /r:System.Core.dll                      \
        /r:System.Xml.dll                       \
        /r:Microsoft.Build.Engine.dll           \
-       /r:Microsoft.Build.Framework.dll
+       /r:Microsoft.Build.Framework.dll        \
+       /d:MICROSOFT_BUILD_DLL
        
-TEST_MCS_FLAGS = /r:System.Core.dll            \
-       /r:Microsoft.Build.Engine.dll           \
-       /r:Microsoft.Build.Framework.dll
+TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 
 EXTRA_DISTFILES = \
+       Microsoft.Build.Internal/ExpressionParser.jay   \
        Test/FunctionalTestReferenceProject.csproj      \
        Test/FunctionalTestReferenceProject3.csproj     \
        Test/Microsoft.Build.Test.csproj        \
        Test/Microsoft.Build.csproj
 
+EXPR_PARSER = Microsoft.Build.Internal/ExpressionParser
+
+$(EXPR_PARSER).cs: $(EXPR_PARSER).jay $(topdir)/jay/skeleton.cs
+       (cd Microsoft.Build.Internal; $(topdir)/../jay/jay -ctv < $(topdir)/../jay/skeleton.cs ExpressionParser.jay > ExpressionParser.cs)
+
+BUILT_SOURCES = $(EXPR_PARSER).cs
+
 include ../../build/library.make
 
 export TESTING_MONO=a
 XBUILD_DIR=../../tools/xbuild
+XBUILD_FRAMEWORK_FOLDERS_PATH=xbuild-testing
 include $(XBUILD_DIR)/xbuild_targets.make
index 43f20dad9b6397a9cbdbc68a6cc601cf83ff35bb..15fe431cec6d431e241d67e7f272e7c3dc4a7b5b 100644 (file)
@@ -1,10 +1,10 @@
 //
-// ProjectItemDefinitionInstance.cs
+// ElementLocation.cs
 //
 // Author:
-//   Atsushi Enomoto (atsushi@veritas-vos-liberabit.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2012 Xamarin Inc.
+// Copyright (C) 2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -26,7 +26,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_5
 
 using Microsoft.Build.Framework;
 using System;
@@ -35,7 +34,10 @@ using System.Collections.Generic;
 namespace Microsoft.Build.Construction
 {
        [Serializable]
-       public abstract class ElementLocation
+#if NET_4_5
+       public
+#endif
+       abstract class ElementLocation
        {
                public abstract int Column { get; }
                public abstract string File { get; }
@@ -44,7 +46,16 @@ namespace Microsoft.Build.Construction
                public string LocationString {
                        get { return Line == 0 ? File : String.Format ("{0} ({1}{2})", File, Line, Column != 0 ? "," + Column : String.Empty); }
                }
+
+               public override bool Equals (object other)
+               {
+                       var o = other as ElementLocation;
+                       return (object) o != null && o.File == File && o.Line == Line && o.Column == Column;
+               }
+
+               public override int GetHashCode ()
+               {
+                       return (File.GetHashCode () << 16) + (Line << 8) + Column;
+               }
        }
 }
-
-#endif
index 551a67b4c57737661b23004313b2a424833319f8..d5a52d9b78bc4817986c27e8564f6ea3a593cfdf 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Exceptions;
 using Microsoft.Build.Internal;
 
@@ -54,8 +55,9 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return "Choose"; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
+                        var name = reader.LocalName;
                         switch (name) {
                         case "Otherwise":
                                 var other = ContainingProject.CreateOtherwiseElement ();
index 23666183d10b77662988932ea4c85a0370845026..36dc17a4fb4ccb0a19c2855850a1cf069883112c 100644 (file)
@@ -47,6 +47,7 @@ namespace Microsoft.Build.Construction
 
                 internal override void Load (XmlReader reader)
                 {
+                        FillLocation (reader);
                         LoadValue (reader);
                 }
 
index 7454665b7e2c73b0bb9849de8d124ed47b9d7004..6a3cd8f2f3b1ac922a4e0c075991fe6cb8252b1f 100644 (file)
@@ -35,6 +35,8 @@ namespace Microsoft.Build.Construction
 {
         public abstract class ProjectElement
         {
+                internal const string MSBuildNamespace = "http://schemas.microsoft.com/developer/msbuild/2003";
+
                 internal ProjectElement ()
                 {
                         linkedListNode = new LinkedListNode<ProjectElement> (this);
@@ -67,9 +69,11 @@ namespace Microsoft.Build.Construction
                 internal virtual void Load (XmlReader reader)
                 {
                         reader.ReadToFollowing (XmlName);
+                        FillLocation (reader);
                         while (reader.MoveToNextAttribute ()) {
                                 LoadAttribute (reader.Name, reader.Value);
                         }
+                        reader.MoveToElement ();
                         LoadValue (reader);
                 }
                 internal virtual void LoadAttribute (string name, string value)
@@ -84,7 +88,7 @@ namespace Microsoft.Build.Construction
                                 Condition = value;
                                 break;
                         default:
-                                throw new InvalidProjectFileException (string.Format (
+                                throw new InvalidProjectFileException (Location, null, string.Format (
                                         "Attribute \"{0}\" is not known on node \"{1}\" [type {2}].", name, XmlName,
                                         GetType ()));
                         }
@@ -109,5 +113,52 @@ namespace Microsoft.Build.Construction
                         if (!string.IsNullOrWhiteSpace (attributeValue))
                                 writer.WriteAttributeString (attributeName, attributeValue);
                 }
+                
+#if NET_4_5
+                public ElementLocation Location { get; private set; }
+                public ElementLocation LabelLocation { get; private set; }
+                public ElementLocation ConditionLocation { get; private set; }
+#else
+                internal ElementLocation Location { get; private set; }
+                internal ElementLocation LabelLocation { get; private set; }
+                internal ElementLocation ConditionLocation { get; private set; }
+#endif
+                
+                internal void FillLocation (XmlReader reader)
+                {
+                        var l = reader as IXmlLineInfo;
+                        if (l != null && l.HasLineInfo ())
+                                Location = new ProjectElementLocation (reader.BaseURI, l);
+                        if (reader.MoveToAttribute ("Condition") && l.HasLineInfo ())
+                                ConditionLocation = new ProjectElementLocation (reader.BaseURI, l);
+                        if (reader.MoveToAttribute ("Label") && l.HasLineInfo ())
+                                LabelLocation = new ProjectElementLocation (reader.BaseURI, l);
+                        reader.MoveToElement ();
+                }
+                
+                class ProjectElementLocation : ElementLocation
+                {
+                        public ProjectElementLocation (string file, IXmlLineInfo li)
+                        {
+                                this.file = file;
+                                this.line = li.LineNumber;
+                                this.column = li.LinePosition;
+                        }
+
+                        string file;
+                        int line;
+                        int column;
+
+                        public override string File { get { return file; } }
+                        public override int Line { get { return line; } }
+                        public override int Column { get { return column; } }
+                }
+                
+                internal InvalidProjectFileException CreateError (XmlReader reader, string message, int columnOffset = 0)
+                {
+                        var li = reader as IXmlLineInfo;
+                        bool valid = li != null && li.HasLineInfo ();
+                        throw new InvalidProjectFileException (reader.BaseURI, valid ? li.LineNumber : 0, valid ? li.LinePosition + columnOffset : 0, 0, 0, message, null, null, null);
+                }
         }
 }
index eb9f59e875d5c0b82e61c0d8a9cdb3fad057856b..1f1619bbd53cf379f098d4648c0cd37f256fc06f 100644 (file)
@@ -29,6 +29,7 @@
 using System.Collections.Generic;
 using System.Linq;
 using System.Xml;
+using Microsoft.Build.Exceptions;
 using Microsoft.Build.Internal;
 
 namespace Microsoft.Build.Construction
@@ -123,11 +124,25 @@ namespace Microsoft.Build.Construction
                                 child.Save (writer);
                 }
 
+                internal override void Load (XmlReader reader)
+                {
+                        reader.Read ();
+                        reader.MoveToContent ();
+                        FillLocation (reader);
+                        if (reader.LocalName != XmlName || reader.NamespaceURI != MSBuildNamespace)
+                                throw CreateError (reader, string.Format ("Unexpected XML {0} \"{1}\" in namespace \"{2}\" appeared, while \"{3}\" in namespace \"{4}\" is expected.",
+                                                reader.NodeType, reader.LocalName, reader.NamespaceURI, XmlName, MSBuildNamespace), -1);
+                        while (reader.MoveToNextAttribute ()) {
+                                LoadAttribute (reader.Name, reader.Value);
+                        }
+                        LoadValue (reader);
+                }
+
                 internal override void LoadValue (XmlReader reader)
                 {
                         while (reader.Read ()) {
                                 if (reader.NodeType == XmlNodeType.Element) {
-                                        var child = LoadChildElement (reader.Name);
+                                        var child = LoadChildElement (reader);
                                         child.Load (reader.ReadSubtree ());
                                 } else if (reader.NodeType == XmlNodeType.Comment) {
                                         var commentElement = new ProjectCommentElement (ContainingProject);
@@ -137,6 +152,6 @@ namespace Microsoft.Build.Construction
                         }
                 }
 
-                internal abstract ProjectElement LoadChildElement (string name);
+                internal abstract ProjectElement LoadChildElement (XmlReader reader);
         }
 }
index d6bcbbb12bcfe947a8d77148327e6d197d623a48..48d35f4f0ff23ddbf1c5ba3bdc8cbc46681997eb 100644 (file)
@@ -71,6 +71,7 @@ namespace Microsoft.Build.Construction
                 {
                         while (reader.Read () && reader.NodeType != XmlNodeType.Element)
                                 ;
+                        FillLocation (reader);
                         using (XmlReader subReader = reader.ReadSubtree ()) {
                                 document = new XmlDocument ();
                                 document.Load (subReader);
index d824cc7ee307dda80d679454d7eaa4cfaf59cc2d..889534839078d58fc3c076313d779c77cda0f646 100644 (file)
@@ -28,6 +28,9 @@
 
 using System;
 using System.Xml;
+using Microsoft.Build.Exceptions;
+
+
 namespace Microsoft.Build.Construction
 {
         [System.Diagnostics.DebuggerDisplayAttribute ("Project={Project} Condition={Condition}")]
@@ -56,6 +59,13 @@ namespace Microsoft.Build.Construction
                         SaveAttribute (writer, "Project", Project);
                         base.SaveValue (writer);
                 }
+                
+                internal override void LoadValue (XmlReader reader)
+                {
+                        if (string.IsNullOrWhiteSpace (Project))
+                                throw new InvalidProjectFileException (Location, null, "Project attribute is null or empty on an Import element");
+                        base.LoadValue (reader);
+                }
 
                 internal override void LoadAttribute (string name, string value)
                 {
index 9223b5dc4b0d5db029d2940c5b6171679bc01bbd..bd346f772adfe5392acc16058a86fb2bfd4e00ad 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using Microsoft.Build.Internal;
+using System.Xml;
 
 namespace Microsoft.Build.Construction
 {
@@ -50,7 +51,7 @@ namespace Microsoft.Build.Construction
                         return import;
                 }
                 internal override string XmlName { get { return "ImportGroup"; } }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
                         return AddImport (null);
                 }
index 283e8b700cfcc0d0f87621e7922c5544e7f0febc..497f631a07da099eb6494b5e381a66fd3ba9724d 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Internal;
 
 namespace Microsoft.Build.Construction
@@ -56,9 +57,9 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return ItemType; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        return AddMetadata (name, null);
+                        return AddMetadata (reader.LocalName, null);
                 }
         }
 }
index 43570e828efcef8484118436b5e1065ff983ebb9..1d74932b2ca8a6ad5d3a953581a48e2069eaf2a3 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Internal;
 
 namespace Microsoft.Build.Construction
@@ -53,9 +54,9 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return "ItemDefinitionGroup"; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        return AddItemDefinition (name);
+                        return AddItemDefinition (reader.LocalName);
                 }
         }
 }
index 02a1a6ec4995f231f27bcc7501802ee4043cb2c2..5b13e2024075a1811c9fe5198a6cd0003c271906 100644 (file)
@@ -31,6 +31,7 @@ using System.Collections.Generic;
 using System.Linq;
 using Microsoft.Build.Internal;
 using System.Xml;
+using Microsoft.Build.Exceptions;
 
 namespace Microsoft.Build.Construction
 {
@@ -61,6 +62,14 @@ namespace Microsoft.Build.Construction
                 }
                 string @remove;
                 public string Remove { get { return @remove ?? String.Empty; } set { @remove = value; } }
+                #if NET_4_5
+                string keepDuplicates;
+                public string KeepDuplicates { get { return keepDuplicates ?? String.Empty; } set { keepDuplicates = value; } }
+                string keepMetadata;
+                public string KeepMetadata { get { return keepMetadata ?? String.Empty; } set { keepMetadata = value; } }
+                string removeMetadata;
+                public string RemoveMetadata { get { return removeMetadata ?? String.Empty; } set { removeMetadata = value; } }
+                #endif
                 public ProjectMetadataElement AddMetadata (string name, string unevaluatedValue)
                 {
                         var metadata = ContainingProject.CreateMetadataElement (name, unevaluatedValue);
@@ -74,9 +83,15 @@ namespace Microsoft.Build.Construction
                 {
                         SaveAttribute (writer, "Include", Include);
                         SaveAttribute (writer, "Exclude", Exclude);
+#if NET_4_5
+                        SaveAttribute (writer, "KeepDuplicates", KeepDuplicates);
+                        SaveAttribute (writer, "KeepMetadata", KeepMetadata);
+                        SaveAttribute (writer, "RemoveMetadata", RemoveMetadata);
+#endif
                         SaveAttribute (writer, "Remove", Remove);
                         base.SaveValue (writer);
                 }
+
                 internal override void LoadAttribute (string name, string value)
                 {
                         switch (name) {
@@ -86,6 +101,17 @@ namespace Microsoft.Build.Construction
                         case "Exclude":
                                 Exclude = value;
                                 break;
+#if NET_4_5
+                        case "KeepDuplicates":
+                                KeepDuplicates = value;
+                                break;
+                        case "KeepMetadata":
+                                KeepMetadata = value;
+                                break;
+                        case "RemoveMetadata":
+                                RemoveMetadata = value;
+                                break;
+#endif
                         case "Remove":
                                 Remove = value;
                                 break;
@@ -94,11 +120,30 @@ namespace Microsoft.Build.Construction
                                 break;
                         }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override void LoadValue (XmlReader reader)
+                {
+                        if (string.IsNullOrWhiteSpace (Include) && string.IsNullOrEmpty (Remove))
+                                throw new InvalidProjectFileException (Location, null, string.Format ("Both Include and Remove attribute are null or empty on '{0}' item", ItemType));
+                        base.LoadValue (reader);
+                }
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        var metadata = ContainingProject.CreateMetadataElement (name);
+                        var metadata = ContainingProject.CreateMetadataElement (reader.LocalName);
                         AppendChild (metadata);
                         return metadata;
                 }
+#if NET_4_5
+                 public ElementLocation ExcludeLocation { get; private set; }
+                 public ElementLocation IncludeLocation { get; private set; }
+                 public ElementLocation KeepDuplicatesLocation { get; private set; }
+                 public ElementLocation RemoveLocation { get; private set; }
+                 public ElementLocation RemoveMetadataLocation { get; private set; }
+#else
+                 ElementLocation ExcludeLocation { get; set; }
+                 ElementLocation IncludeLocation { get; set; }
+                 ElementLocation KeepDuplicatesLocation { get; set; }
+                 ElementLocation RemoveLocation { get; set; }
+                 ElementLocation RemoveMetadataLocation { get; set; }
+#endif
         }
 }
index 5cece6419c60232292427113b4fbd87ba98c605b..f0bce4361b070c4a43aae7f806292d123811568a 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Internal;
-using System;
 
 namespace Microsoft.Build.Construction
 {
@@ -84,9 +85,9 @@ namespace Microsoft.Build.Construction
                         get { return "ItemGroup"; }
                 }
 
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        var item = ContainingProject.CreateItemElement (name);
+                        var item = ContainingProject.CreateItemElement (reader.LocalName);
                         AppendChild (item);
                         return item;
                 }
index 5d6b75a59fe90423ccb40030ed017066c735cccf..1590189e75ae71688f370e5a57809ea0aec25ba3 100644 (file)
@@ -61,5 +61,10 @@ namespace Microsoft.Build.Construction
                                 break;
                         }
                 }
+                
+                #if NET_4_5
+                public 
+                #endif
+                ElementLocation ExecuteTargetsAttributeLocation { get; set; }
         }
 }
index 9c25e506581456b118a5cc844ad1655216ef0d44..b8a2d6bec03d15421b3a81f8d7c931baf18cfe95 100644 (file)
@@ -29,6 +29,7 @@
 using System.Collections.Generic;
 using System;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Exceptions;
 using Microsoft.Build.Internal;
 
@@ -62,9 +63,9 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return "Otherwise"; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        switch (name) {
+                        switch (reader.LocalName) {
                         case "PropertyGroup":
                                 var property = ContainingProject.CreatePropertyGroupElement ();
                                 AppendChild (property);
@@ -79,7 +80,7 @@ namespace Microsoft.Build.Construction
                                 return when;
                         default:
                                 throw new InvalidProjectFileException (string.Format (
-                                        "Child \"{0}\" is not a known node type.", name));
+                                        "Child \"{0}\" is not a known node type.", reader.LocalName));
                         }
                 }
         }
index bb5693758d8c4264e113a4ba89e7160be1b3025a..98d9cb849b9b54b6bb90f2ef87914e5b99301e68 100644 (file)
@@ -57,6 +57,13 @@ namespace Microsoft.Build.Construction
                         get { return taskParameter ?? String.Empty; }
                         set { taskParameter = value; }
                 }
+                #if NET_4_5
+                ElementLocation taskParameterLocation;
+                public ElementLocation TaskParameterLocation {
+                        get { return taskParameterLocation; }
+                        set { taskParameterLocation = value; }
+                }
+                #endif
                 internal override string XmlName {
                         get { return "Output"; }
                 }
index 0050ff5fee3a0b924ba972d9e91e55e9490f056b..4cee2f9d98d19a5150bdcc6a7352a9fdc49b0aa2 100644 (file)
@@ -76,9 +76,15 @@ namespace Microsoft.Build.Construction
                         get { return "PropertyGroup"; }
                 }
 
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        return AddProperty (name, null);
+                        switch (reader.LocalName) {
+                        case "ItemGroup":
+                        case "PropertyGroup":
+                                throw CreateError (reader, string.Format ("{0} is a reserved name that cannot be used for a property.", reader.LocalName));
+                        // others need to be checked too, but things like "Project" are somehow allowed...
+                        }
+                        return AddProperty (reader.LocalName, null);
                 }
         }
 }
index ddbed1f42c55342d615e3235b4a72d236fbb2070..d7d5d77249b84d51a3addaae52efc374236b95fd 100644 (file)
@@ -63,8 +63,8 @@ namespace Microsoft.Build.Construction
 
                 string directoryPath;
                 public string DirectoryPath {
-                        get { return directoryPath ?? String.Empty; }
-                        internal set { directoryPath = value; }
+                        get { return directoryPath ?? Directory.GetCurrentDirectory (); }
+                        set { directoryPath = value; }
                 }
 
                 public ICollection<ProjectPropertyElement> Properties {
@@ -170,7 +170,7 @@ namespace Microsoft.Build.Construction
 
                 string toolsVersion;
                 public string ToolsVersion {
-                        get { return toolsVersion ?? "4.0"; }
+                        get { return toolsVersion ?? string.Empty; }
                         set { toolsVersion = value; }
                 }
 
@@ -185,6 +185,7 @@ namespace Microsoft.Build.Construction
 
                 ProjectRootElement (ProjectCollection projectCollection)
                 {
+                        ToolsVersion = "4.0";
                 }
 
                 public static ProjectRootElement Create ()
@@ -216,8 +217,9 @@ namespace Microsoft.Build.Construction
 
                 public static ProjectRootElement Create (XmlReader xmlReader, ProjectCollection projectCollection)
                 {
-                        // yes, this should create en empty project
                         var result = Create (projectCollection);
+                        result.ToolsVersion = null;
+                        result.Load (xmlReader);
                         return result;
                 }
 
@@ -467,6 +469,8 @@ namespace Microsoft.Build.Construction
 
                 public void Save ()
                 {
+                        if (FullPath == null)
+                                throw new InvalidOperationException ("This project was not given the file path to write to.");
                         Save (Encoding);
                 }
 
@@ -518,9 +522,9 @@ namespace Microsoft.Build.Construction
                         }
                 }
 
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        switch (name) {
+                        switch (reader.LocalName) {
                         case "PropertyGroup":
                                 var prop = CreatePropertyGroupElement ();
                                 AppendChild (prop);
@@ -538,7 +542,8 @@ namespace Microsoft.Build.Construction
                                 AppendChild (def);
                                 return def;
                         case "UsingTask":
-                                return AddUsingTask (null, null, null);
+                                var ut = AddUsingTask (null, null, null);
+                                return ut;
                         case "Choose":
                                 var choose = CreateChooseElement ();
                                 AppendChild (choose);
@@ -548,8 +553,7 @@ namespace Microsoft.Build.Construction
                                 AppendChild (ext);
                                 return ext;
                         default:
-                                throw new InvalidProjectFileException (string.Format (
-                                        "Child \"{0}\" is not a known node type.", name));
+                                throw CreateError (reader, string.Format ("Child \"{0}\" is not a known node type.", reader.LocalName), -1);
                         }
                 }
 
@@ -573,7 +577,7 @@ namespace Microsoft.Build.Construction
 
                 internal override void Save (XmlWriter writer)
                 {
-                        writer.WriteStartElement (XmlName, "http://schemas.microsoft.com/developer/msbuild/2003");
+                        writer.WriteStartElement (XmlName, MSBuildNamespace);
                         SaveValue (writer);
                         writer.WriteEndElement ();
                 }
index 66129eb7daf013d0c6e6ab00dfcf4a16144d035d..cfaaa60c18c0803503451ee12d364665c216cf84 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Internal;
 
 namespace Microsoft.Build.Construction
@@ -111,9 +112,30 @@ namespace Microsoft.Build.Construction
                         get { return "Target"; }
                 }
 
-                internal override ProjectElement LoadChildElement (string name)
+#if NET_4_5
+                 public ElementLocation AfterTargetsLocation { get; private set; }
+                 public ElementLocation BeforeTargetsLocation { get; private set; }
+                 public ElementLocation DependsOnTargetsLocation { get; private set; }
+                 public ElementLocation InputsLocation { get; private set; }
+                 public ElementLocation KeepDuplicateOutputsLocation { get; private set; }
+                 public ElementLocation NameLocation { get; private set; }
+                 public ElementLocation OutputsLocation { get; private set; }
+                 public ElementLocation ReturnsLocation { get; private set; }
+#else
+                 internal ElementLocation AfterTargetsLocation { get; set; }
+                 internal ElementLocation BeforeTargetsLocation { get; set; }
+                 internal ElementLocation DependsOnTargetsLocation { get; set; }
+                 internal ElementLocation InputsLocation { get; set; }
+                 internal ElementLocation KeepDuplicateOutputsLocation { get; set; }
+                 internal ElementLocation LabelLocation { get; set; }
+                 internal ElementLocation NameLocation { get; set; }
+                 internal ElementLocation OutputsLocation { get; set; }
+                 internal ElementLocation ReturnsLocation { get; set; }
+#endif
+
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        switch (name) {
+                        switch (reader.LocalName) {
                         case "OnError":
                                 var error = new ProjectOnErrorElement (ContainingProject);
                                 AppendChild (error);
@@ -123,9 +145,10 @@ namespace Microsoft.Build.Construction
                         case "ItemGroup":
                                 return AddItemGroup ();
                         default:
-                                return AddTask (name);
+                                return AddTask (reader.LocalName);
                         }
                 }
+                // This seriously needs to change to become able to fill ElementLocation...
                 internal override void LoadAttribute (string name, string value)
                 {
                         switch (name) {
index 00e0654526206a930df28bc04c21bfb5fc2fed59..fffe68eb1f30a99b80a6925ae82dfa6135c48529 100644 (file)
@@ -109,16 +109,16 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return Name; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        switch (name) {
+                        switch (reader.LocalName) {
                         case "Output":
                                 var output = ContainingProject.CreateOutputElement (null, null, null);
                                 AppendChild (output);
                                 return output;
                         default:
                                 throw new InvalidProjectFileException (string.Format (
-                                        "Child \"{0}\" is not a known node type.", name));
+                                        "Child \"{0}\" is not a known node type.", reader.LocalName));
                         }
                 }
                 internal override void LoadAttribute (string name, string value)
@@ -127,6 +127,17 @@ namespace Microsoft.Build.Construction
                         case "ContinueOnError":
                                 ContinueOnError = value;
                                 break;
+#if NET_4_5
+                        case "ExecuteTargets":
+                                ExecuteTargets = value;
+                                break;
+                        case "MSBuildArchitecture":
+                                MSBuildArchitecture = value;
+                                break;
+                        case "MSBuildRuntime":
+                                MSBuildRuntime = value;
+                                break;
+#endif
                         case "xmlns":
                                 break;
                         case "Label":
@@ -149,5 +160,15 @@ namespace Microsoft.Build.Construction
                         base.SaveValue (writer);
                 }
                 private Dictionary<string, string> parameters = new Dictionary<string, string> ();
+
+                public string ExecuteTargets { get; set; }
+                #if NET_4_5
+                public ElementLocation ExecuteTargetsLocation { get; set; }
+                public ElementLocation ContinueOnErrorLocation { get; set; }
+                public string MSBuildArchitecture { get; set; }
+                public ElementLocation MSBuildArchitectureLocation { get; set; }
+                public string MSBuildRuntime { get; set; }
+                public ElementLocation MSBuildRuntimeLocation { get; set; }
+                #endif
         }
 }
index eecc92aa27974cffe2bc270643b4af5f85978536..36c889dad572a9bd084e479b899da6c536d14b0a 100644 (file)
@@ -68,7 +68,6 @@ namespace Microsoft.Build.Construction
                 }
                 internal override void LoadValue (XmlReader reader)
                 {
-                        reader.MoveToElement ();
                         TaskBody = reader.ReadInnerXml ();
                 }
         }
index 83a5d607493a502c50c656854ba566933e7701d9..52a1dad01b429d4193249874602ccaa21dfb01f0 100644 (file)
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Xml;
 using Microsoft.Build.Exceptions;
 
 namespace Microsoft.Build.Construction
@@ -107,16 +108,16 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return "UsingTask"; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        switch (name) {
+                        switch (reader.LocalName) {
                         case "ParameterGroup":
                                 return AddParameterGroup ();
                         case "Task":
                                 return AddUsingTaskBody (null, null);
                         default:
                                 throw new InvalidProjectFileException (string.Format (
-                                        "Child \"{0}\" is not a known node type.", name));
+                                        "Child \"{0}\" is not a known node type.", reader.LocalName));
                         }
                 }
         }
index 68040f52c210fa55a53eeb58331fda86c0925304..0d7331afcbfdee8b32467ad2e67957295e461b7c 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Exceptions;
 using Microsoft.Build.Internal;
 
@@ -57,9 +58,9 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return "When"; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        switch (name) {
+                        switch (reader.LocalName) {
                         case "PropertyGroup":
                                 var property = ContainingProject.CreatePropertyGroupElement ();
                                 AppendChild (property);
@@ -74,7 +75,7 @@ namespace Microsoft.Build.Construction
                                 return when;
                         default:
                                 throw new InvalidProjectFileException (string.Format (
-                                        "Child \"{0}\" is not a known node type.", name));
+                                        "Child \"{0}\" is not a known node type.", reader.LocalName));
                         }
                 }
         }
index 8dd13943aa4896e75ff387250cf08ef6e5ff740c..ee808a170b60afe8eea7a604085d0510fdee2072 100644 (file)
@@ -29,6 +29,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using System.Xml;
 using Microsoft.Build.Internal;
 
 namespace Microsoft.Build.Construction
@@ -61,9 +62,9 @@ namespace Microsoft.Build.Construction
                 internal override string XmlName {
                         get { return "ParameterGroup"; }
                 }
-                internal override ProjectElement LoadChildElement (string name)
+                internal override ProjectElement LoadChildElement (XmlReader reader)
                 {
-                        return AddParameter (name);
+                        return AddParameter (reader.LocalName);
                 }
         }
 }
index c87ae5c3dff13ade321ae07526016c4a29a9c324..d384456d52b05321f8b77b31c6f31f45a80b1e93 100644 (file)
@@ -4,9 +4,10 @@
 // Author:
 //   Leszek Ciesielski (skolima@gmail.com)
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
 // (C) 2011 Leszek Ciesielski
-// Copyright (C) 2011 Xamarin Inc. (http://www.xamarin.com)
+// Copyright (C) 2011,2013 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
@@ -36,383 +37,674 @@ using System.Linq;
 using System.Text;
 using System.Xml;
 using Microsoft.Build.Construction;
-using Microsoft.Build.Internal;
+using Microsoft.Build.Exceptions;
 using Microsoft.Build.Execution;
 using Microsoft.Build.Framework;
+using Microsoft.Build.Internal;
+using Microsoft.Build.Internal.Expressions;
 using Microsoft.Build.Logging;
+using System.Collections;
+
+// Basically there are two semantic Project object models and their relationship is not obvious
+// (apart from Microsoft.Build.Construction.ProjectRootElement which is a "construction rule").
+//
+// Microsoft.Build.Evaluation.Project holds some "editable" project model, and it supports
+// detailed loader API (such as Items and AllEvaluatedItems).
+// ProjectPoperty holds UnevaluatedValue and gives EvaluatedValue too.
+//
+// Microsoft.Build.Execution.ProjectInstance holds "snapshot" of a project, and it lacks
+// detailed loader API. It does not give us Unevaluated property value.
+// On the other hand, it supports Targets object model. What Microsoft.Build.Evaluation.Project
+// offers there is actually a list of Microsoft.Build.Execution.ProjectInstance objects.
+// It should be also noted that only ProjectInstance has Evaluate() method (Project doesn't).
+//
+// And both API holds different set of descendant types for each and cannot really share the
+// loader code. That is lame.
+//
+// So, can either of them be used to construct the other model? Both API models share the same
+// "governor", which is Microsoft.Build.Evaluation.ProjectCollection/ Project is added to
+// its LoadedProjects list, while ProjectInstance isn't. Project cannot be loaded to load
+// a ProjectInstance, at least within the same ProjectCollection.
+//
+// On the other hand, can ProjectInstance be used to load a Project? Maybe. Since Project and
+// its descendants need Microsoft.Build.Construction.ProjectElement family as its API model
+// is part of the public API. Then I still have to understand how those AllEvaluatedItems/
+// AllEvaluatedProperties members make sense. EvaluationCounter is another propery in question.
 
 namespace Microsoft.Build.Evaluation
 {
-        [DebuggerDisplay("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties="
-                         +"{data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes="
-                         +"{data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items="
-                         +"{data.Items.Count} #Targets={data.Targets.Count}")]
-        public class Project
-        {
+       [DebuggerDisplay ("{FullPath} EffectiveToolsVersion={ToolsVersion} #GlobalProperties="
+       "{data.globalProperties.Count} #Properties={data.Properties.Count} #ItemTypes="
+       "{data.ItemTypes.Count} #ItemDefinitions={data.ItemDefinitions.Count} #Items="
+       "{data.Items.Count} #Targets={data.Targets.Count}")]
+       public class Project
+       {
                public Project (XmlReader xml)
                        : this (ProjectRootElement.Create (xml))
                {
                }
-                public Project (XmlReader xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion)
+
+               public Project (XmlReader xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion)
                        : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion)
                {
                }
-                public Project (XmlReader xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection)
+
+               public Project (XmlReader xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection)
                        : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion, projectCollection)
                {
                }
-                public Project (XmlReader xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection,
-                                ProjectLoadSettings loadSettings)
+
+               public Project (XmlReader xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection,
+                                             ProjectLoadSettings loadSettings)
                        : this (ProjectRootElement.Create (xml), globalProperties, toolsVersion, projectCollection, loadSettings)
                {
                }
 
-                public Project (ProjectRootElement xml) : this(xml, null, null)
-                {
-                }
-                public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion)
-                        : this(xml, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection)
-                {
-                }
-                public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection)
-                        : this(xml, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
-                {
-                }
-
-                public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection,
-                                ProjectLoadSettings loadSettings)
-                {
-                        ProjectCollection = projectCollection;
-                        Xml = xml;
-                        GlobalProperties = globalProperties;
-                        ToolsVersion = toolsVersion;
-                }
-
-                public Project (string projectFile) : this(projectFile, null, null)
-                {
-                }
-
-                public Project (string projectFile, IDictionary<string, string> globalProperties,
-                                string toolsVersion)
-                        : this(projectFile, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection, ProjectLoadSettings.Default)
-                {
-                }
-
-                public Project (string projectFile, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection)
-                        : this(projectFile, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
-                {
-                }
-
-                public Project (string projectFile, IDictionary<string, string> globalProperties,
-                                string toolsVersion, ProjectCollection projectCollection,
-                                ProjectLoadSettings loadSettings)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IDictionary<string, string> GlobalProperties { get; private set; }
-                public ProjectCollection ProjectCollection { get; private set; }
-                public string ToolsVersion { get; private set; }
-                public ProjectRootElement Xml { get; private set; }
-
-                public ICollection<ProjectItem> GetItemsIgnoringCondition (string itemType)
-                {
-                        return new CollectionFromEnumerable<ProjectItem> (
-                                new FilteredEnumerable<ProjectItemElement> (Xml.Items).
-                                Where (p => p.ItemType.Equals (itemType, StringComparison.OrdinalIgnoreCase)).
-                                Select (p => new ProjectItem(p)));
-                }
-                public void RemoveItems (IEnumerable<ProjectItem> items)
-                {
-                        var removal = new List<ProjectItem> (items);
-                        foreach (var item in removal) {
-                                var parent = item.Xml.Parent;
-                                parent.RemoveChild (item.Xml);
-                                if (parent.Count == 0)
-                                        parent.Parent.RemoveChild (parent);
-                        }
-                }
-
-                public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude,
-                        IEnumerable<KeyValuePair<string, string>> metadata)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude,
-                        IEnumerable<KeyValuePair<string, string>> metadata)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (IEnumerable<ILogger> loggers)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (string target)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (string[] targets)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (ILogger logger)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (string[] targets, IEnumerable<ILogger> loggers)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (string target, IEnumerable<ILogger> loggers)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (string[] targets, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool Build (string target, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ProjectInstance CreateProjectInstance ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public string ExpandString (string unexpandedValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string GetEvaluatedItemIncludeEscaped (ProjectItem item)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string GetEvaluatedItemIncludeEscaped (ProjectItemDefinition item)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ICollection<ProjectItem> GetItems (string itemType)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ICollection<ProjectItem> GetItemsByEvaluatedInclude (string evaluatedInclude)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IEnumerable<ProjectElement> GetLogicalProject ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string GetMetadataValueEscaped (ProjectMetadata metadatum)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string GetMetadataValueEscaped (ProjectItem item, string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string GetMetadataValueEscaped (ProjectItemDefinition item, string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public string GetPropertyValue (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string GetPropertyValueEscaped (ProjectProperty property)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ProjectProperty GetProperty (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void MarkDirty ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void ReevaluateIfNecessary ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool RemoveGlobalProperty (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool RemoveItem (ProjectItem item)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool RemoveProperty (ProjectProperty property)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Save ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Save (TextWriter writer)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Save (string path)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Save (Encoding encoding)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Save (string path, Encoding encoding)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void SaveLogicalProject (TextWriter writer)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool SetGlobalProperty (string name, string escapedValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ProjectProperty SetProperty (string name, string unevaluatedValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ICollection<ProjectMetadata> AllEvaluatedItemDefinitionMetadata {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<ProjectItem> AllEvaluatedItems {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<ProjectProperty> AllEvaluatedProperties {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public IDictionary<string, List<string>> ConditionedProperties {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string DirectoryPath {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public bool DisableMarkDirty { get; set; }
-
-                public int EvaluationCounter {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string FullPath {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public IList<ResolvedImport> Imports {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public IList<ResolvedImport> ImportsIncludingDuplicates {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public bool IsBuildEnabled {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public bool IsDirty {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public IDictionary<string, ProjectItemDefinition> ItemDefinitions {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<ProjectItem> Items {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<ProjectItem> ItemsIgnoringCondition {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<string> ItemTypes {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<ProjectProperty> Properties {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public bool SkipEvaluation { get; set; }
-
-                public IDictionary<string, ProjectTargetInstance> Targets {
-                        get { throw new NotImplementedException (); }
-                }
-        }
+               public Project (ProjectRootElement xml) : this (xml, null, null)
+               {
+               }
+
+               public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion)
+                        : this (xml, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection)
+               {
+               }
+
+               public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection)
+                        : this (xml, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
+               {
+               }
+
+               public Project (ProjectRootElement xml, IDictionary<string, string> globalProperties,
+                                             string toolsVersion, ProjectCollection projectCollection,
+                                             ProjectLoadSettings loadSettings)
+               {
+                       if (projectCollection == null)
+                               throw new ArgumentNullException ("projectCollection");
+                       this.Xml = xml;
+                       this.GlobalProperties = globalProperties ?? new Dictionary<string, string> ();
+                       this.ToolsVersion = toolsVersion;
+                       this.ProjectCollection = projectCollection;
+                       this.load_settings = loadSettings;
+
+                       Initialize (null);
+               }
+               
+               Project (ProjectRootElement imported, Project parent)
+               {
+                       this.Xml = imported;
+                       this.GlobalProperties = parent.GlobalProperties;
+                       this.ToolsVersion = parent.ToolsVersion;
+                       this.ProjectCollection = parent.ProjectCollection;
+                       this.load_settings = parent.load_settings;
+
+                       Initialize (parent);
+               }
+
+               public Project (string projectFile)
+                       : this (projectFile, null, null)
+               {
+               }
+
+               public Project (string projectFile, IDictionary<string, string> globalProperties,
+                               string toolsVersion)
+               : this (projectFile, globalProperties, toolsVersion, ProjectCollection.GlobalProjectCollection, ProjectLoadSettings.Default)
+               {
+               }
+
+               public Project (string projectFile, IDictionary<string, string> globalProperties,
+                               string toolsVersion, ProjectCollection projectCollection)
+               : this (projectFile, globalProperties, toolsVersion, projectCollection, ProjectLoadSettings.Default)
+               {
+               }
+
+               public Project (string projectFile, IDictionary<string, string> globalProperties,
+                               string toolsVersion, ProjectCollection projectCollection,
+                               ProjectLoadSettings loadSettings)
+                       : this (ProjectRootElement.Create (projectFile), globalProperties, toolsVersion, projectCollection, loadSettings)
+               {
+               }
+
+               ProjectLoadSettings load_settings;
+
+               public IDictionary<string, string> GlobalProperties { get; private set; }
+
+               public ProjectCollection ProjectCollection { get; private set; }
+
+               public string ToolsVersion { get; private set; }
+
+               public ProjectRootElement Xml { get; private set; }
+
+               string dir_path;
+               Dictionary<string, ProjectItemDefinition> item_definitions;
+               List<ResolvedImport> raw_imports;
+               List<ProjectItem> raw_items;
+               List<ProjectItem> all_evaluated_items;
+               List<ProjectProperty> properties;
+               Dictionary<string, ProjectTargetInstance> targets;
+
+               void Initialize (Project parent)
+               {
+                       dir_path = Directory.GetCurrentDirectory ();
+                       raw_imports = new List<ResolvedImport> ();
+                       item_definitions = new Dictionary<string, ProjectItemDefinition> ();
+                       targets = new Dictionary<string, ProjectTargetInstance> ();
+                       raw_items = new List<ProjectItem> ();
+                       
+                       // FIXME: this is likely hack. Test ImportedProject.Properties to see what exactly should happen.
+                       if (parent != null) {
+                               properties = parent.properties;
+                       } else {
+                               properties = new List<ProjectProperty> ();
+                       
+                               foreach (DictionaryEntry p in Environment.GetEnvironmentVariables ())
+                                       // FIXME: this is kind of workaround for unavoidable issue that PLATFORM=* is actually given
+                                       // on some platforms and that prevents setting default "PLATFORM=AnyCPU" property.
+                                       if (!string.Equals ("PLATFORM", (string) p.Key, StringComparison.OrdinalIgnoreCase))
+                                               this.properties.Add (new EnvironmentProjectProperty (this, (string)p.Key, (string)p.Value));
+                               foreach (var p in GlobalProperties)
+                                       this.properties.Add (new GlobalProjectProperty (this, p.Key, p.Value));
+                               var tools = ProjectCollection.GetToolset (this.ToolsVersion) ?? ProjectCollection.GetToolset (this.ProjectCollection.DefaultToolsVersion);
+                               foreach (var p in ProjectCollection.GetReservedProperties (tools, this))
+                                       this.properties.Add (p);
+                               foreach (var p in ProjectCollection.GetWellKnownProperties (this))
+                                       this.properties.Add (p);
+                       }
+
+                       ProcessXml (parent);
+                       
+                       ProjectCollection.AddProject (this);
+               }
+               
+               void ProcessXml (Project parent)
+               {
+                       // this needs to be initialized here (regardless of that items won't be evaluated at property evaluation;
+                       // Conditions could incorrectly reference items and lack of this list causes NRE.
+                       all_evaluated_items = new List<ProjectItem> ();
+
+                       // property evaluation happens couple of times.
+                       // At first step, all non-imported properties are evaluated TOO, WHILE those properties are being evaluated.
+                       // This means, Include and IncludeGroup elements with Condition attribute MAY contain references to
+                       // properties and they will be expanded.
+                       var elements = EvaluatePropertiesAndImports (Xml.Children).ToArray (); // ToArray(): to not lazily evaluate elements.
+                       
+                       // next, evaluate items
+                       EvaluateItems (elements);
+                       
+                       // finally, evaluate targets and tasks
+                       EvaluateTargets (elements);
+               }
+               
+               IEnumerable<ProjectElement> EvaluatePropertiesAndImports (IEnumerable<ProjectElement> elements)
+               {
+                       // First step: evaluate Properties
+                       foreach (var child in elements) {
+                               yield return child;
+                               var pge = child as ProjectPropertyGroupElement;
+                               if (pge != null && Evaluate (pge.Condition))
+                                       foreach (var p in pge.Properties)
+                                               // do not allow overwriting reserved or well-known properties by user
+                                               if (!this.properties.Any (_ => (_.IsReservedProperty || _.IsWellKnownProperty) && _.Name.Equals (p.Name, StringComparison.InvariantCultureIgnoreCase)))
+                                                       if (Evaluate (p.Condition))
+                                                               this.properties.Add (new XmlProjectProperty (this, p, PropertyType.Normal, ProjectCollection.OngoingImports.Any ()));
+
+                               var ige = child as ProjectImportGroupElement;
+                               if (ige != null && Evaluate (ige.Condition)) {
+                                       foreach (var incc in ige.Imports) {
+                                               foreach (var e in Import (incc))
+                                                       yield return e;
+                                       }
+                               }
+                               var inc = child as ProjectImportElement;
+                               if (inc != null && Evaluate (inc.Condition))
+                                       foreach (var e in Import (inc))
+                                               yield return e;
+                       }
+               }
+               
+               internal IEnumerable<T> GetAllItems<T> (string include, string exclude, Func<string,T> creator, Func<string,ITaskItem> taskItemCreator, Func<string,bool> itemTypeCheck, Action<T,string> assignRecurse)
+               {
+                       return ProjectCollection.GetAllItems<T> (ExpandString, include, exclude, creator, taskItemCreator, DirectoryPath, assignRecurse,
+                               t => all_evaluated_items.Any (i => i.EvaluatedInclude == t.ItemSpec && itemTypeCheck (i.ItemType)));
+               }
+
+               void EvaluateItems (IEnumerable<ProjectElement> elements)
+               {
+                       foreach (var child in elements) {
+                               var ige = child as ProjectItemGroupElement;
+                               if (ige != null) {
+                                       foreach (var p in ige.Items) {
+                                               if (!Evaluate (ige.Condition) || !Evaluate (p.Condition))
+                                                       continue;
+                                               Func<string,ProjectItem> creator = s => new ProjectItem (this, p, s);
+                                               foreach (var item in GetAllItems<ProjectItem> (p.Include, p.Exclude, creator, s => new ProjectTaskItem (p, s), it => string.Equals (it, p.ItemType, StringComparison.OrdinalIgnoreCase), (t, s) => t.RecursiveDir = s)) {
+                                                       raw_items.Add (item);
+                                                       all_evaluated_items.Add (item);
+                                               }
+                                       }
+                               }
+                               var def = child as ProjectItemDefinitionGroupElement;
+                               if (def != null) {
+                                       foreach (var p in def.ItemDefinitions) {
+                                               if (Evaluate (p.Condition)) {
+                                                       ProjectItemDefinition existing;
+                                                       if (!item_definitions.TryGetValue (p.ItemType, out existing))
+                                                               item_definitions.Add (p.ItemType, (existing = new ProjectItemDefinition (this, p.ItemType)));
+                                                       existing.AddItems (p);
+                                               }
+                                       }
+                               }
+                       }
+                       all_evaluated_items.Sort ((p1, p2) => string.Compare (p1.ItemType, p2.ItemType, StringComparison.OrdinalIgnoreCase));
+               }
+               
+               void EvaluateTargets (IEnumerable<ProjectElement> elements)
+               {
+                       foreach (var child in elements) {
+                               var te = child as ProjectTargetElement;
+                               if (te != null)
+                                       this.targets.Add (te.Name, new ProjectTargetInstance (te));
+                       }
+               }
+               
+               IEnumerable<ProjectElement> Import (ProjectImportElement import)
+               {
+                       string dir = ProjectCollection.GetEvaluationTimeThisFileDirectory (() => FullPath);
+                       string path = WindowsCompatibilityExtensions.NormalizeFilePath (ExpandString (import.Project));
+                       path = Path.IsPathRooted (path) ? path : dir != null ? Path.Combine (dir, path) : Path.GetFullPath (path);
+                       if (ProjectCollection.OngoingImports.Contains (path)) {
+                               switch (load_settings) {
+                               case ProjectLoadSettings.RejectCircularImports:
+                                       throw new InvalidProjectFileException (import.Location, null, string.Format ("Circular imports was detected: {0} (resolved as \"{1}\") is already on \"importing\" stack", import.Project, path));
+                               }
+                               return new ProjectElement [0]; // do not import circular references
+                       }
+                       ProjectCollection.OngoingImports.Push (path);
+                       try {
+                               using (var reader = XmlReader.Create (path)) {
+                                       var root = ProjectRootElement.Create (reader, ProjectCollection);
+                                       raw_imports.Add (new ResolvedImport (import, root, true));
+                                       return this.EvaluatePropertiesAndImports (root.Children).ToArray ();
+                               }
+                       } finally {
+                               ProjectCollection.OngoingImports.Pop ();
+                       }
+               }
+
+               public ICollection<ProjectItem> GetItemsIgnoringCondition (string itemType)
+               {
+                       return new CollectionFromEnumerable<ProjectItem> (raw_items.Where (p => p.ItemType.Equals (itemType, StringComparison.OrdinalIgnoreCase)));
+               }
+
+               public void RemoveItems (IEnumerable<ProjectItem> items)
+               {
+                       var removal = new List<ProjectItem> (items);
+                       foreach (var item in removal) {
+                               var parent = item.Xml.Parent;
+                               parent.RemoveChild (item.Xml);
+                               if (parent.Count == 0)
+                                       parent.Parent.RemoveChild (parent);
+                       }
+               }
+
+               static readonly Dictionary<string, string> empty_metadata = new Dictionary<string, string> ();
+
+               public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude)
+               {
+                       return AddItem (itemType, unevaluatedInclude, empty_metadata);
+               }
+
+               public IList<ProjectItem> AddItem (string itemType, string unevaluatedInclude,
+                               IEnumerable<KeyValuePair<string, string>> metadata)
+               {
+                       // FIXME: needs several check that AddItemFast() does not process (see MSDN for details).
+
+                       return AddItemFast (itemType, unevaluatedInclude, metadata);
+               }
+
+               public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude)
+               {
+                       return AddItemFast (itemType, unevaluatedInclude, empty_metadata);
+               }
+
+               public IList<ProjectItem> AddItemFast (string itemType, string unevaluatedInclude,
+                                                                    IEnumerable<KeyValuePair<string, string>> metadata)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               static readonly char [] target_sep = new char[] {';'};
+
+               public bool Build ()
+               {
+                       return Build (Xml.DefaultTargets.Split (target_sep, StringSplitOptions.RemoveEmptyEntries));
+               }
+
+               public bool Build (IEnumerable<ILogger> loggers)
+               {
+                       return Build (Xml.DefaultTargets.Split (target_sep, StringSplitOptions.RemoveEmptyEntries), loggers);
+               }
+
+               public bool Build (string target)
+               {
+                       return string.IsNullOrWhiteSpace (target) ? Build () : Build (new string [] {target});
+               }
+
+               public bool Build (string[] targets)
+               {
+                       return Build (targets, new ILogger [0]);
+               }
+
+               public bool Build (ILogger logger)
+               {
+                       return Build (Xml.DefaultTargets.Split (target_sep, StringSplitOptions.RemoveEmptyEntries), new ILogger [] {logger});
+               }
+
+               public bool Build (string[] targets, IEnumerable<ILogger> loggers)
+               {
+                       return Build (targets, loggers, new ForwardingLoggerRecord [0]);
+               }
+
+               public bool Build (IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
+               {
+                       return Build (Xml.DefaultTargets.Split (target_sep, StringSplitOptions.RemoveEmptyEntries), loggers, remoteLoggers);
+               }
+
+               public bool Build (string target, IEnumerable<ILogger> loggers)
+               {
+                       return Build (new string [] { target }, loggers);
+               }
+
+               public bool Build (string[] targets, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
+               {
+                       // Unlike ProjectInstance.Build(), there is no place to fill outputs by targets, so ignore them
+                       // (i.e. we don't use the overload with output).
+                       //
+                       // This does not check FullPath, so don't call GetProjectInstanceForBuild() directly.
+                       return new BuildManager ().GetProjectInstanceForBuildInternal (this).Build (targets, loggers, remoteLoggers);
+               }
+
+               public bool Build (string target, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
+               {
+                       return Build (new string [] { target }, loggers, remoteLoggers);
+               }
+
+               public ProjectInstance CreateProjectInstance ()
+               {
+                       var ret = new ProjectInstance (Xml, GlobalProperties, ToolsVersion, ProjectCollection);
+                       // FIXME: maybe fill other properties to the result.
+                       return ret;
+               }
+               
+               bool Evaluate (string unexpandedValue)
+               {
+                       return string.IsNullOrWhiteSpace (unexpandedValue) || new ExpressionEvaluator (this, null).EvaluateAsBoolean (unexpandedValue);
+               }
+
+               public string ExpandString (string unexpandedValue)
+               {
+                       return ExpandString (unexpandedValue, null);
+               }
+               
+               string ExpandString (string unexpandedValue, string replacementForMissingStuff)
+               {
+                       return new ExpressionEvaluator (this, replacementForMissingStuff).Evaluate (unexpandedValue);
+               }
+
+               public static string GetEvaluatedItemIncludeEscaped (ProjectItem item)
+               {
+                       return ProjectCollection.Escape (item.EvaluatedInclude);
+               }
+
+               public static string GetEvaluatedItemIncludeEscaped (ProjectItemDefinition item)
+               {
+                       // ?? ItemDefinition does not have Include attribute. What's the point here?
+                       throw new NotImplementedException ();
+               }
+
+               public ICollection<ProjectItem> GetItems (string itemType)
+               {
+                       return new CollectionFromEnumerable<ProjectItem> (Items.Where (p => p.ItemType.Equals (itemType, StringComparison.OrdinalIgnoreCase)));
+               }
+
+               public ICollection<ProjectItem> GetItemsByEvaluatedInclude (string evaluatedInclude)
+               {
+                       return new CollectionFromEnumerable<ProjectItem> (Items.Where (p => p.EvaluatedInclude.Equals (evaluatedInclude, StringComparison.OrdinalIgnoreCase)));
+               }
+
+               public IEnumerable<ProjectElement> GetLogicalProject ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string GetMetadataValueEscaped (ProjectMetadata metadatum)
+               {
+                       return ProjectCollection.Escape (metadatum.EvaluatedValue);
+               }
+
+               public static string GetMetadataValueEscaped (ProjectItem item, string name)
+               {
+                       var md = item.Metadata.FirstOrDefault (m => m.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+                       return md != null ? ProjectCollection.Escape (md.EvaluatedValue) : null;
+               }
+
+               public static string GetMetadataValueEscaped (ProjectItemDefinition item, string name)
+               {
+                       var md = item.Metadata.FirstOrDefault (m => m.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+                       return md != null ? ProjectCollection.Escape (md.EvaluatedValue) : null;
+               }
+
+               public string GetPropertyValue (string name)
+               {
+                       var prop = GetProperty (name);
+                       return prop != null ? prop.EvaluatedValue : string.Empty;
+               }
+
+               public static string GetPropertyValueEscaped (ProjectProperty property)
+               {
+                       // WTF happens here.
+                       //return ProjectCollection.Escape (property.EvaluatedValue);
+                       return property.EvaluatedValue;
+               }
+
+               public ProjectProperty GetProperty (string name)
+               {
+                       return properties.FirstOrDefault (p => p.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+               }
+
+               public void MarkDirty ()
+               {
+                       if (!DisableMarkDirty)
+                               is_dirty = true;
+               }
+
+               public void ReevaluateIfNecessary ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool RemoveGlobalProperty (string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool RemoveItem (ProjectItem item)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool RemoveProperty (ProjectProperty property)
+               {
+                       var removed = properties.FirstOrDefault (p => p.Name.Equals (property.Name, StringComparison.OrdinalIgnoreCase));
+                       if (removed == null)
+                               return false;
+                       properties.Remove (removed);
+                       return true;
+               }
+
+               public void Save ()
+               {
+                       Xml.Save ();
+               }
+
+               public void Save (TextWriter writer)
+               {
+                       Xml.Save (writer);
+               }
+
+               public void Save (string path)
+               {
+                       Save (path, Encoding.Default);
+               }
+
+               public void Save (Encoding encoding)
+               {
+                       Save (FullPath, encoding);
+               }
+
+               public void Save (string path, Encoding encoding)
+               {
+                       using (var writer = new StreamWriter (path, false, encoding))
+                               Save (writer);
+               }
+
+               public void SaveLogicalProject (TextWriter writer)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool SetGlobalProperty (string name, string escapedValue)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public ProjectProperty SetProperty (string name, string unevaluatedValue)
+               {
+                       var p = new ManuallyAddedProjectProperty (this, name, unevaluatedValue);
+                       properties.Add (p);
+                       return p;
+               }
+
+               public ICollection<ProjectMetadata> AllEvaluatedItemDefinitionMetadata {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public ICollection<ProjectItem> AllEvaluatedItems {
+                       get { return all_evaluated_items; }
+               }
+
+               public ICollection<ProjectProperty> AllEvaluatedProperties {
+                       get { return properties; }
+               }
+
+               public IDictionary<string, List<string>> ConditionedProperties {
+                       get {
+                               // this property returns different instances every time.
+                               var dic = new Dictionary<string, List<string>> ();
+                               
+                               // but I dunno HOW this evaluates
+                               
+                               throw new NotImplementedException ();
+                       }
+               }
+
+               public string DirectoryPath {
+                       get { return dir_path; }
+               }
+
+               public bool DisableMarkDirty { get; set; }
+
+               public int EvaluationCounter {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public string FullPath {
+                       get { return Xml.FullPath; }
+                       set { Xml.FullPath = value; }
+               }
+               
+               class ResolvedImportComparer : IEqualityComparer<ResolvedImport>
+               {
+                       public static ResolvedImportComparer Instance = new ResolvedImportComparer ();
+                       
+                       public bool Equals (ResolvedImport x, ResolvedImport y)
+                       {
+                               return x.ImportedProject.FullPath.Equals (y.ImportedProject.FullPath);
+                       }
+                       public int GetHashCode (ResolvedImport obj)
+                       {
+                               return obj.ImportedProject.FullPath.GetHashCode ();
+                       }
+               }
+
+               public IList<ResolvedImport> Imports {
+                       get { return raw_imports.Distinct (ResolvedImportComparer.Instance).ToList (); }
+               }
+
+               public IList<ResolvedImport> ImportsIncludingDuplicates {
+                       get { return raw_imports; }
+               }
+
+               public bool IsBuildEnabled {
+                       get { return ProjectCollection.IsBuildEnabled; }
+               }
+
+               bool is_dirty;
+               public bool IsDirty {
+                       get { return is_dirty; }
+               }
+
+               public IDictionary<string, ProjectItemDefinition> ItemDefinitions {
+                       get { return item_definitions; }
+               }
+
+               [MonoTODO ("should be different from AllEvaluatedItems")]
+               public ICollection<ProjectItem> Items {
+                       get { return AllEvaluatedItems; }
+               }
+
+               public ICollection<ProjectItem> ItemsIgnoringCondition {
+                       get { return raw_items; }
+               }
+
+               public ICollection<string> ItemTypes {
+                       get { return new CollectionFromEnumerable<string> (raw_items.Select (i => i.ItemType).Distinct ()); }
+               }
+
+               [MonoTODO ("should be different from AllEvaluatedProperties")]
+               public ICollection<ProjectProperty> Properties {
+                       get { return AllEvaluatedProperties; }
+               }
+
+               public bool SkipEvaluation { get; set; }
+
+               public IDictionary<string, ProjectTargetInstance> Targets {
+                       get { return targets; }
+               }
+               
+               // These are required for reserved property, represents dynamically changing property values.
+               // This should resolve to either the project file path or that of the imported file.
+               internal string GetEvaluationTimeThisFileDirectory ()
+               {
+                       var file = GetEvaluationTimeThisFile ();
+                       var dir = Path.IsPathRooted (file) ? Path.GetDirectoryName (file) : Directory.GetCurrentDirectory ();
+                       return dir + Path.DirectorySeparatorChar;
+               }
+
+               internal string GetEvaluationTimeThisFile ()
+               {
+                       return ProjectCollection.OngoingImports.Count > 0 ? ProjectCollection.OngoingImports.Peek () : FullPath ?? string.Empty;
+               }
+               
+               internal string GetFullPath (string pathRelativeToProject)
+               {
+                       if (Path.IsPathRooted (pathRelativeToProject))
+                               return pathRelativeToProject;
+                       return Path.GetFullPath (Path.Combine (DirectoryPath, pathRelativeToProject));
+               }
+       }
 }
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectChangedEventArgs.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..5372642
--- /dev/null
@@ -0,0 +1,42 @@
+//
+// ProjectChangedEventArgs.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@xamarin.com>
+//
+// Copyright (C) 2013 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.Linq;
+
+namespace Microsoft.Build.Evaluation
+{
+       public class ProjectChangedEventArgs : EventArgs
+       {
+               internal ProjectChangedEventArgs (Project project)
+               {
+                       Project = project;
+               }
+               public Project Project { get; private set; }
+       }
+}
index f5b2826961a54de0abf8fc86aacf8b6c7aa46907..0c3d226fcd3ea5b48901cbd6f74746fcef8ad2c5 100644 (file)
@@ -4,9 +4,10 @@
 // Author:
 //   Leszek Ciesielski (skolima@gmail.com)
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
 // (C) 2011 Leszek Ciesielski
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using Microsoft.Build.Construction;
+using Microsoft.Build.Execution;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Logging;
-
+using Microsoft.Build.Utilities;
 using System;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using System.Reflection;
+using System.Globalization;
 
 namespace Microsoft.Build.Evaluation
 {
-        public class ProjectCollection : IDisposable
-        {
-                public ProjectCollection ()
-                {
-                }
-
-                public ProjectCollection (IDictionary<string, string> globalProperties)
-                        : this (globalProperties, null, ToolsetDefinitionLocations.Registry | ToolsetDefinitionLocations.ConfigurationFile)
-                {
-                }
-
-                public ProjectCollection (ToolsetDefinitionLocations toolsetDefinitionLocations)
-                        : this (null, null, toolsetDefinitionLocations)
-                {
-                }
-
-                public ProjectCollection (IDictionary<string, string> globalProperties, IEnumerable<ILogger> loggers,
-                                ToolsetDefinitionLocations toolsetDefinitionLocations)
-                        : this (globalProperties, loggers, null, toolsetDefinitionLocations, 1, false)
-                {
-                }
-
-                public ProjectCollection (IDictionary<string, string> globalProperties,
-                                IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers,
-                                ToolsetDefinitionLocations toolsetDefinitionLocations,
-                                int maxNodeCount, bool onlyLogCriticalEvents)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public static string Escape (string unescapedString)
-                {
-                        return unescapedString;
-                }
-
-                public static ProjectCollection GlobalProjectCollection {
-                        get { return globalProjectCollection; }
-                }
-
-                public void Dispose ()
-                {
-                        Dispose (true);
-                        GC.SuppressFinalize (this);
-                }
-
-                protected virtual void Dispose (bool disposing)
-                {
-                        if (disposing) {
-                        }
-                }
-
-                static ProjectCollection globalProjectCollection = new ProjectCollection ();
-
-                public ICollection<Project> GetLoadedProjects (string fullPath)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ToolsetDefinitionLocations ToolsetLocations {
-                        get { throw new NotImplementedException (); }
-                }
+       public class ProjectCollection : IDisposable
+       {
+               public delegate void ProjectAddedEventHandler (object target, ProjectAddedToProjectCollectionEventArgs args);
+               
+               public class ProjectAddedToProjectCollectionEventArgs : EventArgs
+               {
+                       public ProjectAddedToProjectCollectionEventArgs (ProjectRootElement project)
+                       {
+                               if (project == null)
+                                       throw new ArgumentNullException ("project");
+                               ProjectRootElement = project;
+                       }
+                       
+                       public ProjectRootElement ProjectRootElement { get; private set; }
+               }
+
+               // static members
+
+               static readonly ProjectCollection global_project_collection;
+
+               static ProjectCollection ()
+               {
+                       #if NET_4_5
+                       global_project_collection = new ProjectCollection (new ReadOnlyDictionary<string, string> (new Dictionary<string, string> ()));
+                       #else
+                       global_project_collection = new ProjectCollection (new Dictionary<string, string> ());
+                       #endif
+               }
+
+               public static string Escape (string unescapedString)
+               {
+                       return Mono.XBuild.Utilities.MSBuildUtils.Escape (unescapedString);
+               }
+
+               public static string Unescape (string escapedString)
+               {
+                       return Mono.XBuild.Utilities.MSBuildUtils.Unescape (escapedString);
+               }
+
+               public static ProjectCollection GlobalProjectCollection {
+                       get { return global_project_collection; }
+               }
+
+               // semantic model part
+
+               public ProjectCollection ()
+                       : this (null)
+               {
+               }
+
+               public ProjectCollection (IDictionary<string, string> globalProperties)
+               : this (globalProperties, null, ToolsetDefinitionLocations.Registry | ToolsetDefinitionLocations.ConfigurationFile)
+               {
+               }
 
+               public ProjectCollection (ToolsetDefinitionLocations toolsetDefinitionLocations)
+               : this (null, null, toolsetDefinitionLocations)
+               {
+               }
+
+               public ProjectCollection (IDictionary<string, string> globalProperties, IEnumerable<ILogger> loggers,
+                               ToolsetDefinitionLocations toolsetDefinitionLocations)
+                       : this (globalProperties, loggers, null, toolsetDefinitionLocations, 1, false)
+               {
+               }
+
+               public ProjectCollection (IDictionary<string, string> globalProperties,
+                               IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers,
+                               ToolsetDefinitionLocations toolsetDefinitionLocations,
+                               int maxNodeCount, bool onlyLogCriticalEvents)
+               {
+                       global_properties = globalProperties ?? new Dictionary<string, string> ();
+                       this.loggers = loggers != null ? loggers.ToList () : new List<ILogger> ();
+                       toolset_locations = toolsetDefinitionLocations;
+                       MaxNodeCount = maxNodeCount;
+                       OnlyLogCriticalEvents = onlyLogCriticalEvents;
+
+                       LoadDefaultToolsets ();
+               }
+               
+               [MonoTODO ("not fired yet")]
+               public event ProjectAddedEventHandler ProjectAdded;
+               [MonoTODO ("not fired yet")]
+               public event EventHandler<ProjectChangedEventArgs> ProjectChanged;
+               [MonoTODO ("not fired yet")]
+               public event EventHandler<ProjectCollectionChangedEventArgs> ProjectCollectionChanged;
+               [MonoTODO ("not fired yet")]
+               public event EventHandler<ProjectXmlChangedEventArgs> ProjectXmlChanged;
+
+               public void AddProject (Project project)
+               {
+                       this.loaded_projects.Add (project);
+                       if (ProjectAdded != null)
+                               ProjectAdded (this, new ProjectAddedToProjectCollectionEventArgs (project.Xml));
+               }
+
+               public int Count {
+                       get { return loaded_projects.Count; }
+               }
+
+               string default_tools_version;
+               public string DefaultToolsVersion {
+                       get { return default_tools_version; }
+                       set {
+                               if (GetToolset (value) == null)
+                                       throw new InvalidOperationException (string.Format ("Toolset '{0}' does not exist", value));
+                               default_tools_version = value;
+                       }
+               }
+
+               public void Dispose ()
+               {
+                       Dispose (true);
+                       GC.SuppressFinalize (this);
+               }
+
+               protected virtual void Dispose (bool disposing)
+               {
+                       if (disposing) {
+                       }
+               }
+
+               public ICollection<Project> GetLoadedProjects (string fullPath)
+               {
+                       return LoadedProjects.Where (p => p.FullPath != null && Path.GetFullPath (p.FullPath) == Path.GetFullPath (fullPath)).ToList ();
+               }
+
+               readonly IDictionary<string, string> global_properties;
+
+               public IDictionary<string, string> GlobalProperties {
+                       get { return global_properties; }
+               }
+
+               readonly List<Project> loaded_projects = new List<Project> ();
+               
+               public Project LoadProject (string fileName)
+               {
+                       return LoadProject (fileName, DefaultToolsVersion);
+               }
+               
+               public Project LoadProject (string fileName, string toolsVersion)
+               {
+                       return LoadProject (fileName, null, toolsVersion);
+               }
+               
+               public Project LoadProject (string fileName, IDictionary<string,string> globalProperties, string toolsVersion)
+               {
+                       var ret = new Project (fileName, globalProperties, toolsVersion);
+                       loaded_projects.Add (ret);
+                       return ret;
+               }
+               
+               // These methods somehow don't add the project to ProjectCollection...
+               public Project LoadProject (XmlReader xmlReader)
+               {
+                       return LoadProject (xmlReader, DefaultToolsVersion);
+               }
+               
+               public Project LoadProject (XmlReader xmlReader, string toolsVersion)
+               {
+                       return LoadProject (xmlReader, null, toolsVersion);
+               }
+               
+               public Project LoadProject (XmlReader xmlReader, IDictionary<string,string> globalProperties, string toolsVersion)
+               {
+                       return new Project (xmlReader, globalProperties, toolsVersion);
+               }
+               
+               public ICollection<Project> LoadedProjects {
+                       get { return loaded_projects; }
+               }
+
+               readonly List<ILogger> loggers = new List<ILogger> ();
+               [MonoTODO]
+               public ICollection<ILogger> Loggers {
+                       get { return loggers; }
+               }
+
+               [MonoTODO]
+               public bool OnlyLogCriticalEvents { get; set; }
+
+               [MonoTODO]
+               public bool SkipEvaluation { get; set; }
+
+               readonly ToolsetDefinitionLocations toolset_locations;
+               public ToolsetDefinitionLocations ToolsetLocations {
+                       get { return toolset_locations; }
+               }
+
+               readonly List<Toolset> toolsets = new List<Toolset> ();
+               // so what should we do without ToolLocationHelper in Microsoft.Build.Utilities.dll? There is no reference to it in this dll.
                public ICollection<Toolset> Toolsets {
-                        get { throw new NotImplementedException (); }
-                }
+                       // For ConfigurationFile and None, they cannot be added externally.
+                       get { return (ToolsetLocations & ToolsetDefinitionLocations.Registry) != 0 ? toolsets : toolsets.ToList (); }
+               }
+               
+               public Toolset GetToolset (string toolsVersion)
+               {
+                       return Toolsets.FirstOrDefault (t => t.ToolsVersion == toolsVersion);
+               }
+
+               //FIXME: should also support config file, depending on ToolsetLocations
+               void LoadDefaultToolsets ()
+               {
+                       AddToolset (new Toolset ("2.0",
+                               ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version20), this, null));
+                       AddToolset (new Toolset ("3.0",
+                               ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version30), this, null));
+                       AddToolset (new Toolset ("3.5",
+                               ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version35), this, null));
+#if NET_4_0
+                       AddToolset (new Toolset ("4.0",
+                               ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40), this, null));
+#endif
+#if NET_4_5
+                       AddToolset (new Toolset ("12.0",
+                               ToolLocationHelper.GetMSBuildInstallPath ("12.0"), this, ToolLocationHelper.GetPathToDotNetFramework (TargetDotNetFrameworkVersion.Version40)));
+#endif
+                       default_tools_version = toolsets.First ().ToolsVersion;
+               }
+               
+               [MonoTODO ("not verified at all")]
+               public void AddToolset (Toolset toolset)
+               {
+                       toolsets.Add (toolset);
+               }
+               
+               [MonoTODO ("not verified at all")]
+               public void RemoveAllToolsets ()
+               {
+                       toolsets.Clear ();
+               }
+               
+               [MonoTODO ("not verified at all")]
+               public void RegisterLogger (ILogger logger)
+               {
+                       loggers.Add (logger);
+               }
+               
+               [MonoTODO ("not verified at all")]
+               public void RegisterLoggers (IEnumerable<ILogger> loggers)
+               {
+                       foreach (var logger in loggers)
+                               this.loggers.Add (logger);
+               }
 
                public void UnloadAllProjects ()
                {
-                        throw new NotImplementedException ();
+                       throw new NotImplementedException ();
                }
 
+               [MonoTODO ("Not verified at all")]
                public void UnloadProject (Project project)
                {
-                        throw new NotImplementedException ();
+                       this.loaded_projects.Remove (project);
                }
 
+               [MonoTODO ("Not verified at all")]
                public void UnloadProject (ProjectRootElement projectRootElement)
                {
-                        throw new NotImplementedException ();
+                       foreach (var proj in loaded_projects.Where (p => p.Xml == projectRootElement).ToArray ())
+                               UnloadProject (proj);
                }
 
                public static Version Version {
-                        get { throw new NotImplementedException (); }
-                }
-        }
+                       get { throw new NotImplementedException (); }
+               }
+
+               // Execution part
+
+               [MonoTODO]
+               public bool DisableMarkDirty { get; set; }
+
+               [MonoTODO]
+               public HostServices HostServices { get; set; }
+
+               [MonoTODO]
+               public bool IsBuildEnabled { get; set; }
+               
+               internal string BuildStartupDirectory { get; set; }
+               
+               internal int MaxNodeCount { get; private set; }
+               
+               Stack<string> ongoing_imports = new Stack<string> ();
+               
+               internal Stack<string> OngoingImports {
+                       get { return ongoing_imports; }
+               }
+               
+               // common part
+               internal static IEnumerable<EnvironmentProjectProperty> GetWellKnownProperties (Project project)
+               {
+                       Func<string,string,EnvironmentProjectProperty> create = (name, value) => new EnvironmentProjectProperty (project, name, value, true);
+                       return GetWellKnownProperties (create);
+               }
+               
+               internal static IEnumerable<ProjectPropertyInstance> GetWellKnownProperties (ProjectInstance project)
+               {
+                       Func<string,string,ProjectPropertyInstance> create = (name, value) => new ProjectPropertyInstance (name, true, value);
+                       return GetWellKnownProperties (create);
+               }
+               
+               static IEnumerable<T> GetWellKnownProperties<T> (Func<string,string,T> create)
+               {
+                       var ext = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath") ?? DefaultExtensionsPath;
+                       yield return create ("MSBuildExtensionsPath", ext);
+                       var ext32 = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath32") ?? DefaultExtensionsPath;
+                       yield return create ("MSBuildExtensionsPath32", ext32);
+                       var ext64 = Environment.GetEnvironmentVariable ("MSBuildExtensionsPath64") ?? DefaultExtensionsPath;
+                       yield return create ("MSBuildExtensionsPath64", ext64);
+               }
+
+               static string extensions_path;
+               internal static string DefaultExtensionsPath {
+                       get {
+                               if (extensions_path == null) {
+                                       // NOTE: code from mcs/tools/gacutil/driver.cs
+                                       PropertyInfo gac = typeof (System.Environment).GetProperty (
+                                                       "GacPath", BindingFlags.Static | BindingFlags.NonPublic);
+
+                                       if (gac != null) {
+                                               MethodInfo get_gac = gac.GetGetMethod (true);
+                                               string gac_path = (string) get_gac.Invoke (null, null);
+                                               extensions_path = Path.GetFullPath (Path.Combine (
+                                                                       gac_path, Path.Combine ("..", "xbuild")));
+                                       }
+                               }
+                               return extensions_path;
+                       }
+               }
+               
+               internal IEnumerable<ReservedProjectProperty> GetReservedProperties (Toolset toolset, Project project)
+               {
+                       Func<string,Func<string>,ReservedProjectProperty> create = (name, value) => new ReservedProjectProperty (project, name, value);
+                       return GetReservedProperties<ReservedProjectProperty> (toolset, project.Xml, create, () => project.FullPath);
+               }
+               
+               internal IEnumerable<ProjectPropertyInstance> GetReservedProperties (Toolset toolset, ProjectInstance project, ProjectRootElement xml)
+               {
+                       Func<string,Func<string>,ProjectPropertyInstance> create = (name, value) => new ProjectPropertyInstance (name, true, null, value);
+                       return GetReservedProperties<ProjectPropertyInstance> (toolset, xml, create, () => project.FullPath);
+               }
+               
+               // seealso http://msdn.microsoft.com/en-us/library/ms164309.aspx
+               IEnumerable<T> GetReservedProperties<T> (Toolset toolset, ProjectRootElement project, Func<string,Func<string>,T> create, Func<string> projectFullPath)
+               {
+                       yield return create ("MSBuildBinPath", () => toolset.ToolsPath);
+                       // FIXME: add MSBuildLastTaskResult
+                       // FIXME: add MSBuildNodeCount
+                       // FIXME: add MSBuildProgramFiles32
+                       yield return create ("MSBuildProjectDefaultTargets", () => project.DefaultTargets);
+                       yield return create ("MSBuildProjectDirectory", () => project.DirectoryPath + Path.DirectorySeparatorChar);
+                       yield return create ("MSBuildProjectDirectoryNoRoot", () => project.DirectoryPath.Substring (Path.GetPathRoot (project.DirectoryPath).Length));
+                       yield return create ("MSBuildProjectExtension", () => Path.GetExtension (project.FullPath));
+                       yield return create ("MSBuildProjectFile", () => Path.GetFileName (project.FullPath));
+                       yield return create ("MSBuildProjectFullPath", () => project.FullPath);
+                       yield return create ("MSBuildProjectName", () => Path.GetFileNameWithoutExtension (project.FullPath));
+                       yield return create ("MSBuildStartupDirectory", () => BuildStartupDirectory);
+                       yield return create ("MSBuildThisFile", () => Path.GetFileName (GetEvaluationTimeThisFile (projectFullPath)));
+                       yield return create ("MSBuildThisFileFullPath", () => GetEvaluationTimeThisFile (projectFullPath));
+                       yield return create ("MSBuildThisFileName", () => Path.GetFileNameWithoutExtension (GetEvaluationTimeThisFile (projectFullPath)));
+                       yield return create ("MSBuildThisFileExtension", () => Path.GetExtension (GetEvaluationTimeThisFile (projectFullPath)));
+
+                       yield return create ("MSBuildThisFileDirectory", () => Path.GetDirectoryName (GetEvaluationTimeThisFileDirectory (projectFullPath)));
+                       yield return create ("MSBuildThisFileDirectoryNoRoot", () => {
+                               string dir = GetEvaluationTimeThisFileDirectory (projectFullPath) + Path.DirectorySeparatorChar;
+                               return dir.Substring (Path.GetPathRoot (dir).Length);
+                               });
+                       yield return create ("MSBuildToolsPath", () => toolset.ToolsPath);
+                       yield return create ("MSBuildToolsVersion", () => toolset.ToolsVersion);
+               }
+               
+               // These are required for reserved property, represents dynamically changing property values.
+               // This should resolve to either the project file path or that of the imported file.
+               internal string GetEvaluationTimeThisFileDirectory (Func<string> nonImportingTimeFullPath)
+               {
+                       var file = GetEvaluationTimeThisFile (nonImportingTimeFullPath);
+                       var dir = Path.IsPathRooted (file) ? Path.GetDirectoryName (file) : Directory.GetCurrentDirectory ();
+                       return dir + Path.DirectorySeparatorChar;
+               }
+
+               internal string GetEvaluationTimeThisFile (Func<string> nonImportingTimeFullPath)
+               {
+                       return OngoingImports.Count > 0 ? OngoingImports.Peek () : (nonImportingTimeFullPath () ?? string.Empty);
+               }
+               
+               static readonly char [] item_target_sep = {';'};
+               
+               internal static IEnumerable<T> GetAllItems<T> (Func<string,string> expandString, string include, string exclude, Func<string,T> creator, Func<string,ITaskItem> taskItemCreator, string directory, Action<T,string> assignRecurse, Func<ITaskItem,bool> isDuplicate)
+               {
+                       var includes = expandString (include).Trim ().Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries);
+                       var excludes = expandString (exclude).Trim ().Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries);
+                       
+                       if (includes.Length == 0)
+                               yield break;
+                       if (includes.Length == 1 && includes [0].IndexOf ('*') < 0 && excludes.Length == 0) {
+                               // for most case - shortcut.
+                               var item = creator (includes [0]);
+                               yield return item;
+                       } else {
+                               var ds = new Microsoft.Build.BuildEngine.DirectoryScanner () {
+                                       BaseDirectory = new DirectoryInfo (directory),
+                                       Includes = includes.Where (s => !string.IsNullOrWhiteSpace (s)).Select (i => taskItemCreator (i)).ToArray (),
+                                       Excludes = excludes.Where (s => !string.IsNullOrWhiteSpace (s)).Select (e => taskItemCreator (e)).ToArray (),
+                               };
+                               ds.Scan ();
+                               foreach (var taskItem in ds.MatchedItems) {
+                                       if (isDuplicate (taskItem))
+                                               continue; // skip duplicate
+                                       var item = creator (taskItem.ItemSpec);
+                                       string recurse = taskItem.GetMetadata ("RecursiveDir");
+                                       assignRecurse (item, recurse);
+                                       yield return item;
+                               }
+                       }
+               }
+               
+               static readonly char [] path_sep = {Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar};
+               
+               internal static string GetWellKnownMetadata (string name, string file, Func<string,string> getFullPath, string recursiveDir)
+               {
+                       switch (name.ToLower (CultureInfo.InvariantCulture)) {
+                       case "fullpath":
+                               return getFullPath (file);
+                       case "rootdir":
+                               return Path.GetPathRoot (getFullPath (file));
+                       case "filename":
+                               return Path.GetFileNameWithoutExtension (file);
+                       case "extension":
+                               return Path.GetExtension (file);
+                       case "relativedir":
+                                       var idx = file.LastIndexOfAny (path_sep);
+                                       return idx < 0 ? string.Empty : file.Substring (0, idx + 1);
+                       case "directory":
+                                       var fp = getFullPath (file);
+                                       return Path.GetDirectoryName (fp).Substring (Path.GetPathRoot (fp).Length);
+                       case "recursivedir":
+                               return recursiveDir;
+                       case "identity":
+                               return file;
+                       case "modifiedtime":
+                               return new FileInfo (getFullPath (file)).LastWriteTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff");
+                       case "createdtime":
+                               return new FileInfo (getFullPath (file)).CreationTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff");
+                       case "accessedtime":
+                               return new FileInfo (getFullPath (file)).LastAccessTime.ToString ("yyyy-MM-dd HH:mm:ss.fffffff");
+                       }
+                       return null;
+               }
+       }
 }
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollectionChangedEventArgs.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollectionChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..a4e8ee9
--- /dev/null
@@ -0,0 +1,16 @@
+using System;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Evaluation
+{
+       public class ProjectCollectionChangedEventArgs : EventArgs
+       {
+               public ProjectCollectionChangedEventArgs (ProjectCollectionChangedState state)
+               {
+                       State = state;
+               }
+               
+               public ProjectCollectionChangedState State { get; private set; }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollectionChangedState.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectCollectionChangedState.cs
new file mode 100644 (file)
index 0000000..683080f
--- /dev/null
@@ -0,0 +1,19 @@
+using System;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Evaluation
+{
+       public enum ProjectCollectionChangedState
+       {
+               DefaultToolsVersion,
+               DisableMarkDirty,
+               GlobalProperties,
+               HostServices,
+               IsBuildEnabled,
+               Loggers,
+               OnlyLogCriticalEvents,
+               SkipEvaluation,
+               Toolsets
+       }
+}
+
index 393995e80cdc94c43a921170d7e6acc562a25bc4..cc187f9b94c0b8e5f1f26d67bad8af188f55e205 100644 (file)
@@ -4,9 +4,10 @@
 // Author:
 //   Leszek Ciesielski (skolima@gmail.com)
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
 // (C) 2011 Leszek Ciesielski
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
-
+using System.Linq;
 using Microsoft.Build.Construction;
+using System.IO;
+using Microsoft.Build.Framework;
 
 namespace Microsoft.Build.Evaluation
 {
-        [DebuggerDisplay("{ItemType}={EvaluatedInclude} [{UnevaluatedInclude}] #DirectMetadata={DirectMetadataCount}")]
-        public class ProjectItem
-        {
-                internal ProjectItem (ProjectItemElement xml)
-                {
-                        Xml = xml;
-                }
-
-                public ProjectMetadata GetMetadata (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public string GetMetadataValue (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool HasMetadata (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool RemoveMetadata (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void Rename (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void SetMetadataValue (string name, string unevaluatedValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IEnumerable<ProjectMetadata> DirectMetadata {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int DirectMetadataCount {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string EvaluatedInclude {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public bool IsImported {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string ItemType {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public ICollection<ProjectMetadata> Metadata {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int MetadataCount {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public Project Project {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string UnevaluatedInclude {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public ProjectItemElement Xml { get; private set; }
-
-        }
+       [DebuggerDisplay ("{ItemType}={EvaluatedInclude} [{UnevaluatedInclude}] #DirectMetadata={DirectMetadataCount}")]
+       public class ProjectItem
+       {
+               internal ProjectItem (Project project, ProjectItemElement xml, string evaluatedInclude)
+               {
+                       this.project = project;
+                       this.xml = xml;
+                       if (project.ItemDefinitions.ContainsKey (ItemType))
+                               foreach (var md in project.ItemDefinitions [ItemType].Metadata)
+                                       metadata.Add (md);
+                       foreach (var md in xml.Metadata)
+                               metadata.Add (new ProjectMetadata (project, ItemType, metadata, m => metadata.Remove (m), md));
+                       this.evaluated_include = evaluatedInclude;
+                       is_imported = project.ProjectCollection.OngoingImports.Any ();                  
+               }
+               
+               readonly Project project;
+               readonly ProjectItemElement xml;
+               readonly List<ProjectMetadata> metadata = new List<ProjectMetadata> ();
+               readonly bool is_imported;
+               readonly string evaluated_include;
+               
+               internal string RecursiveDir { get; set; }
+
+               public ProjectMetadata GetMetadata (string name)
+               {
+                       return metadata.FirstOrDefault (m => m.Name == name);
+               }
+
+               public string GetMetadataValue (string name)
+               {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       var wk = ProjectCollection.GetWellKnownMetadata (name, EvaluatedInclude, project.GetFullPath, RecursiveDir);
+                       if (wk != null)
+                               return wk;
+                       var m = GetMetadata (name);
+                       return m != null ? m.EvaluatedValue : string.Empty;
+               }
+
+               public bool HasMetadata (string name)
+               {
+                       return GetMetadata (name) != null;
+               }
+
+               public bool RemoveMetadata (string name)
+               {
+                       var m = GetMetadata (name);
+                       if (m == null)
+                               return false;
+                       return metadata.Remove (m);
+               }
+
+               public void Rename (string name)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public ProjectMetadata SetMetadataValue (string name, string unevaluatedValue)
+               {
+                       // This has to do several tasks:
+                       // - it cannot directly change Xml.Metadata because the ProjectItemElement might be shared
+                       //   among multiple ProjectItems.
+                       // - hence it has to create another ProjectItemElement instance and add it to the project
+                       //   XML construction, with specific Include value that is assigned to this instance, and
+                       //   metadata values that are assigned to this instance.
+                       throw new NotImplementedException ();
+               }
+
+               public IEnumerable<ProjectMetadata> DirectMetadata {
+                       get {
+                               var list = new List<ProjectMetadata> ();
+                               foreach (var xm in xml.Metadata)
+                                       yield return new ProjectMetadata (project, ItemType, list, p => list.Remove (p), xm);
+                       }
+               }
+
+               public int DirectMetadataCount {
+                       get { return xml.Metadata.Count; }
+               }
+
+               public string EvaluatedInclude {
+                       get { return evaluated_include; }
+               }
+
+               public bool IsImported {
+                       get { return is_imported; }
+               }
+
+               public string ItemType {
+                       get { return Xml.ItemType; }
+                       set { Xml.ItemType = value; }
+               }
+
+               public ICollection<ProjectMetadata> Metadata {
+                       get { return metadata; }
+               }
+
+               public int MetadataCount {
+                       get { return metadata.Count; }
+               }
+
+               public Project Project {
+                       get { return project; }
+               }
+
+               public string UnevaluatedInclude {
+                       get { return Xml.Include; }
+                       set { Xml.Include = value; }
+               }
+
+               public ProjectItemElement Xml {
+                       get { return xml; }
+               }               
+       }
 }
index 13ef541bc610e1c6dd51c3b59a309d040d5b432d..faa880603b978d9de4d591b1e2f48f2d20f51b60 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using System;
+using System.Collections.Generic;
+using Microsoft.Build.Construction;
 
 namespace Microsoft.Build.Evaluation
 {
-        public class ProjectItemDefinition
-        {
-                private ProjectItemDefinition ()
-                {
-                        throw new NotImplementedException ();
-                }
-        }
-}
+       public class ProjectItemDefinition
+       {
+               internal ProjectItemDefinition (Project project, string itemType)
+               {
+                       this.project = project;
+                       this.item_type = itemType;
+               }
+
+               Project project;
+               string item_type;
+               List<ProjectMetadata> metadata = new List<ProjectMetadata> ();
+
+               public string ItemType {
+                       get { return item_type; }
+               }
 
+               public IEnumerable<ProjectMetadata> Metadata {
+                       get { return metadata; }
+               }
+
+               public int MetadataCount {
+                       get { return metadata.Count; }
+               }
+
+               public Project Project {
+                       get { return project; }
+               }
+               
+               internal void AddItems (ProjectItemDefinitionElement xml)
+               {
+                       foreach (var item in xml.Metadata)
+                               metadata.Add (new ProjectMetadata (project, ItemType, metadata, m => metadata.Remove (m), item));
+               }
+       }
+}
index 45001f61a243323be0da41f561ba924338d06282..880a0e336be40952f44dc8a024845f712a99c18e 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using Microsoft.Build.Construction;
-
 using System;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace Microsoft.Build.Evaluation
 {
-        public class ProjectMetadata
-        {
-                private ProjectMetadata ()
-                {
-                        throw new NotImplementedException ();
-                }
+       public class ProjectMetadata
+       {
+               internal ProjectMetadata (Project project, string itemType, IEnumerable<ProjectMetadata> existingMetadata, Action<ProjectMetadata> remover, ProjectMetadataElement xml)
+               {
+                       this.xml = xml;
+                       this.project = project;
+                       item_type = itemType;
+                       predecessor = existingMetadata.FirstOrDefault (m => m.Name == xml.Name);
+                       if (predecessor != null)
+                               remover (predecessor);
+                       is_imported = Project.ProjectCollection.OngoingImports.Any ();
+               }
+
+               readonly Project project;
+               readonly string item_type;
+               readonly ProjectMetadataElement xml;
+               readonly ProjectMetadata predecessor;
+               readonly bool is_imported;
 
-                public string EvaluatedValue {
-                        get { throw new NotImplementedException (); }
-                }
+               public string EvaluatedValue {
+                       get { return project.ExpandString (xml.Value); }
+               }
 
-                public bool IsImported {
-                        get { throw new NotImplementedException (); }
-                }
+               public bool IsImported {
+                       get { return is_imported; }
+               }
 
-                public string ItemType {
-                        get { throw new NotImplementedException (); }
-                }
+               public string ItemType {
+                       get { return item_type; }
+               }
 
-                public string Name {
-                        get { throw new NotImplementedException (); }
-                }
+               public string Name {
+                       get { return xml.Name; }
+               }
 
-                public ProjectMetadata Predecessor {
-                        get { throw new NotImplementedException (); }
-                }
+               public ProjectMetadata Predecessor {
+                       get { return predecessor; }
+               }
 
-                public Project Project {
-                        get { throw new NotImplementedException (); }
-                }
+               public Project Project {
+                       get { return project; }
+               }
 
-                public string UnevaluatedValue {
-                        get { throw new NotImplementedException (); }
-                }
+               public string UnevaluatedValue {
+                       get { return xml.Value; }
+               }
 
-                public ProjectMetadataElement Xml {
-                        get { throw new NotImplementedException (); }
-                }
-        }
+               public ProjectMetadataElement Xml {
+                       get { return xml; }
+               }
+       }
 }
 
index e9d557f3e0fa3acdddbe518f7ab4fbe0b6e3dcbe..757b40f3ce01fd84ae522db3f5f6ef5e818c287d 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using System;
+using System.Linq;
 using Microsoft.Build.Construction;
+using Microsoft.Build.Internal;
+using System.Collections.Generic;
+using System.Reflection;
+using System.IO;
 
 namespace Microsoft.Build.Evaluation
 {
@@ -34,39 +40,249 @@ namespace Microsoft.Build.Evaluation
        // members are abstract and had been there since 4.0.
        // I take this as doc bug, as non-abstract to abstract is a
        // breaking change and I'd rather believe API designer's sanity.
-        public abstract class ProjectProperty
-        {
-               internal ProjectProperty () // hide default ctor
+       public abstract class ProjectProperty
+       {
+               internal ProjectProperty (Project project) // hide default ctor
                {
+                       Project = project;
                }
 
-                public string EvaluatedValue {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                }
+               public string EvaluatedValue {
+                       get { return InternalEvaluatedValue; }
+               }
 
                public abstract bool IsEnvironmentProperty { get; }
+
                public abstract bool IsGlobalProperty { get; }
+
+               [MonoTODO]
                public abstract bool IsImported { get; }
+
                public abstract bool IsReservedProperty { get; }
 
-               public string Name {
-                       get {
-                                throw new NotImplementedException ();
-                       }
+               internal virtual bool IsWellKnownProperty {
+                       get { return false; }
                }
 
+               public abstract string Name { get; }
+
                public abstract ProjectProperty Predecessor { get; }
 
-               public Project Project {
+               public Project Project { get; private set; }
+
+               public abstract string UnevaluatedValue { get; set; }
+
+               public abstract ProjectPropertyElement Xml { get; }
+               
+               internal abstract string InternalEvaluatedValue { get; }
+       }
+
+       // copy from MS.Build.Engine/BuildProperty.cs
+       internal enum PropertyType {
+               Reserved,
+               Global,
+               Normal,
+               Environment
+       }
+       
+       internal abstract class BaseProjectProperty : ProjectProperty
+       {
+               public BaseProjectProperty (Project project, PropertyType propertyType, string name)
+                       : base (project)
+               {
+                       property_type = propertyType;
+                       this.name = name;
+                       predecessor = project.Properties.FirstOrDefault (p => p.Name == name);
+                       if (predecessor != null)
+                               project.RemoveProperty (predecessor);
+               }
+               
+               PropertyType property_type;
+               
+               readonly string name;
+               public override string Name {
+                       get { return name; }
+               }
+               
+               public override bool IsEnvironmentProperty {
+                       get { return property_type == PropertyType.Environment; }
+               }
+               public override bool IsGlobalProperty {
+                       get { return property_type == PropertyType.Global; }
+               }
+               public override bool IsImported {
+                       get { return false; }
+               }
+               public override bool IsReservedProperty {
+                       get { return property_type == PropertyType.Reserved; }
+               }
+               readonly ProjectProperty predecessor; 
+               public override ProjectProperty Predecessor {
+                       get { return predecessor; }
+               }
+       }
+       
+       internal abstract class ImmutableProjectProperty : BaseProjectProperty
+       {
+               public ImmutableProjectProperty (Project project, PropertyType propertyType, string name)
+                       : base (project, propertyType, name)
+               {
+               }
+               
+               internal override string InternalEvaluatedValue {
+                       get { return UnevaluatedValue; }
+               }
+       }
+       
+       internal abstract class MutableProjectProperty : BaseProjectProperty
+       {
+               public MutableProjectProperty (Project project, PropertyType propertyType, string name)
+                       : base (project, propertyType, name)
+               {
+               }
+               
+               string evaluated_value; // see UpdateEvaluatedValue().
+               internal void UpdateEvaluatedValue ()
+               {
+                       evaluated_value = Project.ExpandString (UnevaluatedValue);
+               }
+               
+               internal override string InternalEvaluatedValue {
+                       get { return evaluated_value; }
+               }
+       }
+       
+       internal class XmlProjectProperty : MutableProjectProperty
+       {
+               public XmlProjectProperty (Project project, ProjectPropertyElement xml, PropertyType propertyType, bool isImported)
+                       : base (project, propertyType, xml.Name)
+               {
+                       this.xml = xml;
+                       this.is_imported = isImported;
+                       UpdateEvaluatedValue ();
+               }
+               
+               readonly ProjectPropertyElement xml;
+               readonly bool is_imported;
+               
+               public override bool IsImported {
+                       get { return is_imported; }
+               }
+               
+               public override string UnevaluatedValue {
+                       get { return xml.Value; }
+                       set { xml.Value = value; }
+               }
+               
+               public override ProjectPropertyElement Xml {
+                       get { return xml; }
+               }
+       }
+       
+       internal class EnvironmentProjectProperty : ImmutableProjectProperty
+       {
+               static string extensions_path;
+               internal static string DefaultExtensionsPath {
                        get {
-                                throw new NotImplementedException ();
+                               if (extensions_path == null) {
+                                       // NOTE: code from mcs/tools/gacutil/driver.cs
+                                       PropertyInfo gac = typeof (System.Environment).GetProperty (
+                                                       "GacPath", BindingFlags.Static | BindingFlags.NonPublic);
+
+                                       if (gac != null) {
+                                               MethodInfo get_gac = gac.GetGetMethod (true);
+                                               string gac_path = (string) get_gac.Invoke (null, null);
+                                               extensions_path = Path.GetFullPath (Path.Combine (
+                                                                       gac_path, Path.Combine ("..", "xbuild")));
+                                       }
+                               }
+                               return extensions_path;
                        }
                }
+               
+               public EnvironmentProjectProperty (Project project, string name, string value, bool wellknown = false)
+                       : base (project, PropertyType.Environment, name)
+               {
+                       this.value = value;
+                       this.wellknown = wellknown;
+               }
+               
+               readonly string value;
+               readonly bool wellknown;
 
-               public abstract string UnevaluatedValue { get; set; }
-               public abstract ProjectPropertyElement Xml { get; }
-        }
-}
+               internal override bool IsWellKnownProperty {
+                       get { return wellknown; }
+               }
 
+               // It can override possible another environment vairable property BUT never gives Predecessor.
+               public override ProjectProperty Predecessor {
+                       get { return null; }
+               }
+               
+               public override string UnevaluatedValue {
+                       get { return value; }
+                       set { throw new InvalidOperationException (string.Format ("You cannot change value of environment property '{0}'.", Name)); }
+               }
+               public override ProjectPropertyElement Xml {
+                       get { return null; }
+               }
+       }
+       
+       internal class GlobalProjectProperty : ImmutableProjectProperty
+       {
+               public GlobalProjectProperty (Project project, string name, string value)
+                       : base (project, PropertyType.Global, name)
+               {
+                       this.value = value;
+               }
+               
+               readonly string value;
+               
+               public override string UnevaluatedValue {
+                       get { return value; }
+                       set { throw new InvalidOperationException (string.Format ("You cannot change value of global property '{0}'.", Name)); }
+               }
+               public override ProjectPropertyElement Xml {
+                       get { return null; }
+               }
+       }
+       
+       internal class ManuallyAddedProjectProperty : MutableProjectProperty
+       {
+               public ManuallyAddedProjectProperty (Project project, string name, string value)
+                       : base (project, PropertyType.Normal, name)
+               {
+                       this.UnevaluatedValue = value;
+               }
+               
+               public override string UnevaluatedValue { get; set; }
+               
+               public override ProjectPropertyElement Xml {
+                       get { return null; }
+               }
+       }
+       
+       internal class ReservedProjectProperty : ImmutableProjectProperty
+       {
+               public ReservedProjectProperty (Project project, string name, Func<string> value)
+                       : base (project, PropertyType.Reserved, name)
+               {
+                       this.value = value;
+               }
+
+               // make sure it does not give access to any possible attempted overrrides.
+               public override ProjectProperty Predecessor {
+                       get { return null; }
+               }
+
+               readonly Func<string> value;
+               public override string UnevaluatedValue {
+                       get { return value (); }
+                       set { throw new InvalidOperationException (string.Format ("You cannot change value of reserved property '{0}'.", Name)); }
+               }
+               
+               public override ProjectPropertyElement Xml {
+                       get { return null; }
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectXmlChangedEventArgs.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/ProjectXmlChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..a0497a5
--- /dev/null
@@ -0,0 +1,45 @@
+//
+// ProjectXmlChangedEventArgs.cs
+//
+// Author:
+//     Atsushi Enomoto <atsushi@xamarin.com>
+//
+// Copyright (C) 2013 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 Microsoft.Build.Construction;
+using System;
+using System.Linq;
+
+namespace Microsoft.Build.Evaluation
+{
+       public class ProjectXmlChangedEventArgs : EventArgs
+       {
+               internal ProjectXmlChangedEventArgs (ProjectRootElement projectXml, string reason)
+               {
+                       ProjectXml = projectXml;
+                       Reason = reason;
+               }
+               public ProjectRootElement ProjectXml { get; private set; }
+               public string Reason { get; private set; }
+       }
+}
index 1e82c01a4c1ba29ca8377d370e36be2e94802322..8a5bed743732428b5986cad8fc1844cad486e134 100644 (file)
 //
 
 using Microsoft.Build.Construction;
-
 using System;
 
 namespace Microsoft.Build.Evaluation
 {
-        [System.Runtime.InteropServices.StructLayout (System.Runtime.InteropServices.LayoutKind.Sequential)]
-        public struct ResolvedImport
-        {
-                private ProjectImportElement import;
-                private ProjectRootElement root;
+       [System.Runtime.InteropServices.StructLayout (System.Runtime.InteropServices.LayoutKind.Sequential)]
+       public struct ResolvedImport
+       {
+               internal ResolvedImport (ProjectImportElement import, ProjectRootElement root, bool isImported)
+               {
+                       this.import = import;
+                       this.root = root;
+                       this.imported = isImported;
+               }
+
+               readonly ProjectImportElement import;
+               readonly ProjectRootElement root;
+               readonly bool imported;
 
-                public ProjectImportElement ImportingElement {
-                        get { return import; }
-                }
+               public ProjectImportElement ImportingElement {
+                       get { return import; }
+               }
 
-                public ProjectRootElement ImportedProject {
-                        get { return root; }
-                }
-        }
+               public ProjectRootElement ImportedProject {
+                       get { return root; }
+               }
+               
+               public bool IsImported {
+                       get { return imported; }
+               }
+       }
 }
 
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/SubToolset.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Evaluation/SubToolset.cs
new file mode 100644 (file)
index 0000000..0b4ad39
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using Microsoft.Build.Execution;
+
+namespace Microsoft.Build.Evaluation
+{
+       #if NET_4_5
+       public
+       #endif
+       class SubToolset
+       {
+               internal SubToolset (IDictionary<string, ProjectPropertyInstance> properties, string subToolsetVersion)
+               {
+                       Properties = properties;
+                       SubToolsetVersion = subToolsetVersion;
+               }
+
+               public IDictionary<string, ProjectPropertyInstance> Properties { get; private set; }
+               public string SubToolsetVersion { get; private set; }
+       }
+}
+
index 9da377be35fa87e3e890fae108be34f380ed817a..b0182c53bb856e891f31aa223dec97e96a411c38 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 
 using System;
 using System.Collections.Generic;
-
+using System.Linq;
 using Microsoft.Build.Execution;
 
 namespace Microsoft.Build.Evaluation
 {
-        public class Toolset
-        {
-                public Toolset (string toolsVersion, string toolsPath,
-                                ProjectCollection projectCollection, string msbuildOverrideTasksPath)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public Toolset (string toolsVersion, string toolsPath,
-                                IDictionary<string, string> buildProperties, ProjectCollection projectCollection,
-                                string msbuildOverrideTasksPath)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public IDictionary<string, ProjectPropertyInstance> Properties {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string ToolsPath {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string ToolsVersion {
-                        get { throw new NotImplementedException (); }
-                }
-        }
+       public class Toolset
+       {
+               public Toolset (string toolsVersion, string toolsPath,
+                               ProjectCollection projectCollection, string msbuildOverrideTasksPath)
+                       : this (toolsVersion, toolsPath, null, projectCollection, msbuildOverrideTasksPath)
+               {
+               }
+
+               public Toolset (string toolsVersion, string toolsPath,
+                               IDictionary<string, string> buildProperties, ProjectCollection projectCollection,
+                               string msbuildOverrideTasksPath)
+                       : this (toolsVersion, toolsPath, buildProperties, projectCollection, null, msbuildOverrideTasksPath)
+               {
+               }
+
+#if NET_4_5
+               public
+#endif
+               Toolset (string toolsVersion, string toolsPath, IDictionary<string, string> buildProperties,
+                       ProjectCollection projectCollection, IDictionary<string, SubToolset> subToolsets,
+                       string msbuildOverrideTasksPath)
+               {
+                       ToolsVersion = toolsVersion;
+                       ToolsPath = toolsPath;
+                       Properties = 
+                               buildProperties == null ?
+                               new Dictionary<string, ProjectPropertyInstance> () :
+                               buildProperties.Select (p => new ProjectPropertyInstance (p.Key, true, p.Value)).ToDictionary (e => e.Name);
+#if NET_4_5
+                       SubToolsets = subToolsets ?? new Dictionary<string, SubToolset> ();
+#endif
+               }
+
+#if NET_4_5
+               public string DefaultSubToolsetVersion { get; private set; }
+               public IDictionary<string, SubToolset> SubToolsets { get; private set; }
+#endif
+
+               public IDictionary<string, ProjectPropertyInstance> Properties { get; private set; }
+
+               public string ToolsPath { get; private set; }
+
+               public string ToolsVersion { get; private set; }
+       }
 }
 
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/BuildAbortedException.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/BuildAbortedException.cs
new file mode 100644 (file)
index 0000000..70a2969
--- /dev/null
@@ -0,0 +1,43 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Build.Exceptions
+{
+       public class BuildAbortedException : Exception
+       {
+               public BuildAbortedException ()
+                       : this ("Build aborted")
+               {
+               }
+               
+               public BuildAbortedException (string message)
+                       : base (message)
+               {
+               }
+               
+               public BuildAbortedException (string message, Exception innerException)
+                       : base (message, innerException)
+               {
+               }
+               protected BuildAbortedException (SerializationInfo info, StreamingContext context)
+                       : base (info, context)
+               {
+                       ErrorCode = info.GetString ("errorCode");
+               }
+               
+               internal BuildAbortedException (string message, string errorCode)
+                       : base (message + " error code: " + errorCode)
+               {
+                       ErrorCode = errorCode;
+               }
+               
+               public string ErrorCode { get; private set; }
+               
+               public override void GetObjectData (SerializationInfo info, StreamingContext context)
+               {
+                       base.GetObjectData (info, context);
+                       info.AddValue ("errorCode", ErrorCode);
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InternalLoggerException.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InternalLoggerException.cs
new file mode 100644 (file)
index 0000000..3aecdfd
--- /dev/null
@@ -0,0 +1,57 @@
+using System;
+using System.Runtime.Serialization;
+using Microsoft.Build.Framework;
+
+namespace Microsoft.Build.Exceptions
+{
+       public class InternalLoggerException : Exception
+       {
+               public InternalLoggerException ()
+                       : this ("Build aborted")
+               {
+               }
+               
+               public InternalLoggerException (string message)
+                       : base (message)
+               {
+               }
+               
+               public InternalLoggerException (string message, Exception innerException)
+                       : base (message, innerException)
+               {
+               }
+               
+               internal InternalLoggerException (string message, Exception innerException, BuildEventArgs buildEventArgs, string errorCode, string helpKeyword, bool initializationException)
+                       : base (message, innerException)
+               {
+                       BuildEventArgs = buildEventArgs;
+                       ErrorCode = errorCode;
+                       HelpKeyword = helpKeyword;
+                       InitializationException = initializationException;
+               }
+               
+               internal InternalLoggerException (SerializationInfo info, StreamingContext context)
+                       : base (info, context)
+               {
+                       BuildEventArgs = (BuildEventArgs) info.GetValue ("buildEventArgs", typeof (BuildEventArgs));
+                       ErrorCode = info.GetString ("errorCode");
+                       HelpKeyword = info.GetString ("helpKeyword");
+                       InitializationException = info.GetBoolean ("initializationException");
+               }
+               
+               public BuildEventArgs BuildEventArgs { get; private set; }
+               public string ErrorCode { get; private set; }
+               public string HelpKeyword { get; private set; }
+               public bool InitializationException { get; private set; }
+               
+               public override void GetObjectData (SerializationInfo info, StreamingContext context)
+               {
+                       base.GetObjectData (info, context);
+                       info.AddValue ("buildEventArgs", BuildEventArgs);
+                       info.AddValue ("errorCode", ErrorCode);
+                       info.AddValue ("helpKeyword", HelpKeyword);
+                       info.AddValue ("initializationException", InitializationException);
+               }
+       }
+}
+
index ea2a51dc40ca82b1c5a3e96a222d76a3980692b7..ad05ff6403aaba80fa678ed715858e2235d06d1a 100644 (file)
@@ -28,6 +28,8 @@
 
 using System;
 using System.Runtime.Serialization;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Internal.Expressions;
 
 namespace Microsoft.Build.Exceptions
 {
@@ -57,10 +59,31 @@ namespace Microsoft.Build.Exceptions
                         : base(message, innerException)
                 {
                 }
+                internal InvalidProjectFileException (ILocation start, string message,
+                                                      string errorSubcategory = null, string errorCode = null, string helpKeyword = null)
+                        : this (start != null ? start.File : null, 0, start != null ? start.Column : 0, 0, 0, message, errorSubcategory, errorCode, helpKeyword)
+                {
+                }
+                internal InvalidProjectFileException (ElementLocation start, ElementLocation end, string message,
+                                                    string errorSubcategory = null, string errorCode = null, string helpKeyword = null)
+                        : this (start != null ? start.File : null, start != null ? start.Line : 0, start != null ? start.Column : 0,
+                                end != null ? end.Line : 0, end != null ? end.Column : 0,
+                                message, errorSubcategory, errorCode, helpKeyword)
+                {
+                }
                 public InvalidProjectFileException (string projectFile, int lineNumber, int columnNumber,
                                                     int endLineNumber, int endColumnNumber, string message,
                                                     string errorSubcategory, string errorCode, string helpKeyword)
+                        : base(message)
                 {
+                        ProjectFile = projectFile;
+                        LineNumber = lineNumber;
+                        ColumnNumber = columnNumber;
+                        EndLineNumber = endLineNumber;
+                        EndColumnNumber = endColumnNumber;
+                        ErrorSubcategory = errorSubcategory;
+                        ErrorCode = errorCode;
+                        HelpKeyword = helpKeyword;
                 }
                 public override void GetObjectData (SerializationInfo info, StreamingContext context)
                 {
@@ -87,8 +110,15 @@ namespace Microsoft.Build.Exceptions
                 public string HelpKeyword { get; private set; }
                 public int LineNumber { get; private set; }
                 public override string Message {
-                        get { return ProjectFile == null ? base.Message : base.Message + " " + ProjectFile; }
+                        get { return ProjectFile == null ? base.Message : base.Message + " " + GetLocation (); }
                 }
                 public string ProjectFile { get; private set; }
+
+                string GetLocation ()
+                {
+                        string start = LineNumber == 0 ? string.Empty : ColumnNumber > 0 ? string.Format ("{0},{1}", LineNumber, ColumnNumber) : string.Format ("{0}", LineNumber);
+                        string end = EndLineNumber == 0 ? string.Empty : EndColumnNumber > 0 ? string.Format (" - {0},{1}", EndLineNumber, EndColumnNumber) : string.Format (" - {0}", EndLineNumber);
+                        return LineNumber == 0 ? ProjectFile : String.Format (" at: {0} ({1}{2})", ProjectFile, start, end);
+                }
         }
 }
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InvalidToolsetDefinitionException.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Exceptions/InvalidToolsetDefinitionException.cs
new file mode 100644 (file)
index 0000000..b518d18
--- /dev/null
@@ -0,0 +1,42 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace Microsoft.Build.Exceptions
+{
+       public class InvalidToolsetDefinitionException : Exception
+       {
+               public InvalidToolsetDefinitionException ()
+                       : this ("Invalid toolset definition")
+               {
+               }
+               
+               public InvalidToolsetDefinitionException (string message)
+                       : base (message)
+               {
+               }
+               
+               public InvalidToolsetDefinitionException (string message, Exception innerException)
+                       : base (message, innerException)
+               {
+               }
+               protected InvalidToolsetDefinitionException (SerializationInfo info, StreamingContext context)
+                       : base (info, context)
+               {
+                       ErrorCode = info.GetString ("errorCode");
+               }
+               
+               internal InvalidToolsetDefinitionException (string message, string errorCode)
+                       : base (message + " error code: " + errorCode)
+               {
+                       ErrorCode = errorCode;
+               }
+               
+               public string ErrorCode { get; private set; }
+               
+               public override void GetObjectData (SerializationInfo info, StreamingContext context)
+               {
+                       base.GetObjectData (info, context);
+                       info.AddValue ("errorCode", ErrorCode);
+               }
+       }
+}
index 3b4384b2f6be94c43f17d8d86dc91be4e277e9e4..0c179afa48efedf470ffea5b6c884576b8a7d6c8 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using Microsoft.Build.Evaluation;
-
 using System;
+using System.Collections.Generic;
+using System.Threading;
+using Microsoft.Build.Internal;
+using System.Linq;
 
 namespace Microsoft.Build.Execution
 {
-        public class BuildManager
-        {
-                public BuildManager ()
-                {
-                        throw new NotImplementedException ();
-                }
+       public class BuildManager
+       {
+               static BuildManager default_manager = new BuildManager ();
 
-                public BuildManager (string hostName)
-                {
-                        throw new NotImplementedException ();
-                }
+               public static BuildManager DefaultBuildManager {
+                       get { return default_manager; }
+               }
+               
+               public BuildManager ()
+               {
+               }
 
-                public void BeginBuild (BuildParameters parameters)
-                {
-                        throw new NotImplementedException ();
-                }
+               public BuildManager (string hostName)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               public void Dispose ()
+               {
+                       WaitHandle.WaitAll (submissions.Select (s => s.WaitHandle).ToArray ());
+                       BuildNodeManager.Stop ();
+               }
 
-                public BuildResult Build (BuildParameters parameters, BuildRequestData requestData)
-                {
-                        throw new NotImplementedException ();
-                }
+               ~BuildManager ()
+               {
+                       // maybe processes created by out-of-process nodes should be signaled.
+                       BuildNodeManager.Stop ();
+               }
 
-                public BuildResult BuildRequest (BuildRequestData requestData)
-                {
-                        throw new NotImplementedException ();
-                }
+               readonly List<BuildSubmission> submissions = new List<BuildSubmission> ();
+               
+               BuildParameters ongoing_build_parameters;
+               
+               internal BuildParameters OngoingBuildParameters {
+                       get { return ongoing_build_parameters; }
+               }
 
-                public void CancelAllSubmissions ()
-                {
-                        throw new NotImplementedException ();
-                }
+               public void BeginBuild (BuildParameters parameters)
+               {
+                       if (ongoing_build_parameters != null)
+                               throw new InvalidOperationException ("There is already ongoing build");
+                       ongoing_build_parameters = parameters.Clone ();
+               }
 
-                public void EndBuild ()
-                {
-                        throw new NotImplementedException ();
-                }
+               public BuildResult Build (BuildParameters parameters, BuildRequestData requestData)
+               {
+                       BeginBuild (parameters);
+                       var ret = BuildRequest (requestData);
+                       EndBuild ();
+                       return ret;
+               }
 
-                public ProjectInstance GetProjectInstanceForBuild (Project project)
-                {
-                        throw new NotImplementedException ();
-                }
+               public BuildResult BuildRequest (BuildRequestData requestData)
+               {
+                       var sub = PendBuildRequest (requestData);
+                       sub.Execute ();
+                       return sub.BuildResult;
+               }
+               
+               public void CancelAllSubmissions ()
+               {
+                       foreach (var sub in submissions) {
+                               try {
+                                       if (!sub.IsCompleted)
+                                               sub.Cancel ();
+                               } catch (InvalidOperationException) {
+                                       // some submissions could be already done during this iteration. Ignore that.
+                               }
+                       }
+                       submissions.Clear ();
+               }
 
-                public BuildSubmission PendBuildRequest (BuildRequestData requestData)
-                {
-                        throw new NotImplementedException ();
-                }
+               public void EndBuild ()
+               {
+                       if (ongoing_build_parameters == null)
+                               throw new InvalidOperationException ("Build has not started");
+                       if (submissions.Count > 0)
+                               WaitHandle.WaitAll (submissions.Select (s => s.WaitHandle).ToArray ());
+                       BuildNodeManager.Stop ();
+                       ongoing_build_parameters = null;
+               }
+               
+               Dictionary<Project,ProjectInstance> instances = new Dictionary<Project, ProjectInstance> ();
 
-                public void ResetCaches ()
-                {
-                        throw new NotImplementedException ();
-                }
+               public ProjectInstance GetProjectInstanceForBuild (Project project)
+               {
+                       if (project == null)
+                               throw new ArgumentNullException ("project");
+                       if (project.FullPath == null)
+                               throw new ArgumentNullException ("project", "FullPath parameter in the project cannot be null.");
+                       if (project.FullPath == string.Empty)
+                               throw new ArgumentException ("FullPath parameter in the project cannot be empty.", "project");
+                       // other than that, any invalid path character is accepted...
+                       
+                       return GetProjectInstanceForBuildInternal (project);
+               }
+                       
+               internal ProjectInstance GetProjectInstanceForBuildInternal (Project project)
+               {
+                       if (!instances.ContainsKey (project))
+                               instances [project] = project.CreateProjectInstance ();
+                       return instances [project];
+               }
 
-                public static BuildManager DefaultBuildManager {
-                        get { throw new NotImplementedException (); }
-                }
-        }
-}
+               public BuildSubmission PendBuildRequest (BuildRequestData requestData)
+               {
+                       if (ongoing_build_parameters == null)
+                               throw new InvalidOperationException ("This method cannot be called before calling BeginBuild method.");
+                       var sub = new BuildSubmission (this, requestData);
+                       submissions.Add (sub);
+                       return sub;
+               }
 
+               public void ResetCaches ()
+               {
+                       if (OngoingBuildParameters != null)
+                               throw new InvalidOperationException ("Cannot reset caches while builds are in progress.");
+                       
+                       BuildNodeManager.ResetCaches ();
+               }
+               
+               BuildNodeManager build_node_manager;
+               
+               internal BuildNodeManager BuildNodeManager {
+                       get {
+                               if (build_node_manager == null)
+                                               build_node_manager = new BuildNodeManager (this);
+                               return build_node_manager;
+                       }
+               }
+       }
+}
index 26944910f9ea2f7fcac8562ff1b6e544ad8d24cd..61f8393cda468fb076fd49687a549a9c45853cab 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 using Microsoft.Build.Evaluation;
 using Microsoft.Build.Framework;
 using Microsoft.Build.Logging;
-
 using System;
 using System.Collections.Generic;
 using System.Globalization;
+using System.Linq;
 using System.Threading;
+using System.Collections;
 
 namespace Microsoft.Build.Execution
 {
-        public class BuildParameters
-        {
-                public BuildParameters ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public BuildParameters (ProjectCollection projectCollection)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public BuildParameters Clone ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public Toolset GetToolset (string toolsVersion)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ThreadPriority BuildThreadPriority {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public CultureInfo Culture {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public string DefaultToolsVersion {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public bool DetailedSummary {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public bool EnableNodeReuse {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public IDictionary<string, string> EnvironmentProperties {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public IEnumerable<ForwardingLoggerRecord> ForwardingLoggers {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public IDictionary<string, string> GlobalProperties {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public HostServices HostServices {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public bool LegacyThreadingSemantics { get; set; }
-
-                public IEnumerable<ILogger> Loggers {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public int MaxNodeCount {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public int MemoryUseLimit {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public string NodeExeLocation {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public bool OnlyLogCriticalEvents {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public bool ResetCaches { get; set; }
-
-                public bool SaveOperatingEnvironment {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public ToolsetDefinitionLocations ToolsetDefinitionLocations {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public ICollection<Toolset> Toolsets {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public CultureInfo UICulture {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public bool UseSynchronousLogging {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-        }
+       public class BuildParameters
+       {
+               public BuildParameters ()
+                       : this (new ProjectCollection ())
+               {
+               }
+
+               public BuildParameters (ProjectCollection projectCollection)
+               {
+                       if (projectCollection == null)
+                               throw new ArgumentNullException ("projectCollection");
+                       projects = projectCollection;
+                       
+                       EnableNodeReuse = true;
+                       Culture = CultureInfo.CurrentCulture;
+                       UICulture = CultureInfo.CurrentUICulture;
+                       MaxNodeCount = projectCollection.MaxNodeCount;
+
+                       // these properties are copied, while some members (such as Loggers) are not.
+                       this.DefaultToolsVersion = projectCollection.DefaultToolsVersion;
+                       this.ToolsetDefinitionLocations = projectCollection.ToolsetLocations;
+                       this.GlobalProperties = projectCollection.GlobalProperties;
+                       environment_properties = new Dictionary<string,string> ();
+                       foreach (DictionaryEntry p in Environment.GetEnvironmentVariables ())
+                               environment_properties [(string) p.Key] = (string) p.Value;
+               }
+
+               readonly ProjectCollection projects;
+               Dictionary<string,string> environment_properties;
+               
+               internal ProjectCollection ProjectCollection {
+                       get { return projects; }
+               }
+
+               public BuildParameters Clone ()
+               {
+                       var ret = (BuildParameters) MemberwiseClone ();
+                       ret.ForwardingLoggers = ForwardingLoggers == null ? null : ForwardingLoggers.ToArray ();
+                       ret.GlobalProperties = GlobalProperties == null ? null : GlobalProperties.ToDictionary (p => p.Key, p => p.Value);
+                       ret.Loggers = Loggers == null ? null : new List<ILogger> (Loggers);
+                       ret.environment_properties = new Dictionary<string, string> (environment_properties);
+                       return ret;
+               }
+
+               public Toolset GetToolset (string toolsVersion)
+               {
+                       // can return null.
+                       return projects.Toolsets.FirstOrDefault (t => t.ToolsVersion == toolsVersion);
+               }
+
+               [MonoTODO]
+               public ThreadPriority BuildThreadPriority { get; set; }
+
+               [MonoTODO]
+               public CultureInfo Culture { get; set; }
+
+               public string DefaultToolsVersion { get; set; }
+
+               [MonoTODO]
+               public bool DetailedSummary { get; set; }
+
+               public bool EnableNodeReuse { get; set; }
+
+               [MonoTODO]
+               public IDictionary<string, string> EnvironmentProperties {
+                       get { return environment_properties; }
+               }
+
+               [MonoTODO]
+               public IEnumerable<ForwardingLoggerRecord> ForwardingLoggers { get; set; }
+
+               [MonoTODO]
+               public IDictionary<string, string> GlobalProperties { get; set; }
+
+               public HostServices HostServices { get; set; }
+
+               [MonoTODO]
+               public bool LegacyThreadingSemantics { get; set; }
+
+               [MonoTODO]
+               public IEnumerable<ILogger> Loggers { get; set; }
+
+               [MonoTODO]
+               public int MaxNodeCount { get; set; }
+
+               [MonoTODO]
+               public int MemoryUseLimit { get; set; }
+
+               [MonoTODO]
+               public string NodeExeLocation { get; set; }
+
+               [MonoTODO]
+               public bool OnlyLogCriticalEvents { get; set; }
+
+               [MonoTODO]
+               public bool ResetCaches { get; set; }
+
+               [MonoTODO]
+               public bool SaveOperatingEnvironment { get; set; }
+
+               [MonoTODO]
+               public ToolsetDefinitionLocations ToolsetDefinitionLocations { get; set; }
+
+               [MonoTODO]
+               public ICollection<Toolset> Toolsets {
+                       get { return projects.Toolsets; }
+               }
+
+               [MonoTODO]
+               public CultureInfo UICulture { get; set; }
+
+               [MonoTODO]
+               public bool UseSynchronousLogging { get; set; }
+       }
 }
 
index 2380077e51d11a937c108c2df04604c6705ba2c2..bd5edffd7c6f4daa6225b2090c09ef3540b4e7fb 100644 (file)
@@ -3,8 +3,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using System;
+using System.Linq;
 using System.Collections.Generic;
 
 namespace Microsoft.Build.Execution
 {
-        public class BuildRequestData
-        {
-                public BuildRequestData (ProjectInstance projectInstance, string[] targetsToBuild)
-                        : this (projectInstance, targetsToBuild, null, BuildRequestDataFlags.None)
-                {
-                }
+       public class BuildRequestData
+       {
+               public BuildRequestData (ProjectInstance projectInstance, string[] targetsToBuild)
+               : this (projectInstance, targetsToBuild, null, BuildRequestDataFlags.None)
+               {
+               }
 
-                public BuildRequestData (ProjectInstance projectInstance, string[] targetsToBuild, HostServices hostServices)
-                        : this (projectInstance, targetsToBuild, hostServices, BuildRequestDataFlags.None)
-                {
-                }
+               public BuildRequestData (ProjectInstance projectInstance, string[] targetsToBuild, HostServices hostServices)
+               : this (projectInstance, targetsToBuild, hostServices, BuildRequestDataFlags.None)
+               {
+               }
 
-                public BuildRequestData (ProjectInstance projectInstance, string[] targetsToBuild, HostServices hostServices,
-                                BuildRequestDataFlags flags)
-                {
-                        throw new NotImplementedException ();
-                }
+               public BuildRequestData (ProjectInstance projectInstance, string[] targetsToBuild, HostServices hostServices,
+                               BuildRequestDataFlags flags)
+               {
+                       ProjectInstance = projectInstance;
+                       TargetNames = targetsToBuild;
+                       HostServices = hostServices;
+                       Flags = flags;
+               }
 
-                public BuildRequestData (string projectFullPath, IDictionary<string, string> globalProperties,
-                                string toolsVersion, string[] targetsToBuild, HostServices hostServices)
-                        : this (projectFullPath, globalProperties, toolsVersion, targetsToBuild, hostServices, BuildRequestDataFlags.None)
-                {
-                }
+               public BuildRequestData (string projectFullPath, IDictionary<string, string> globalProperties,
+                               string toolsVersion, string[] targetsToBuild, HostServices hostServices)
+                       : this (projectFullPath, globalProperties, toolsVersion, targetsToBuild, hostServices, BuildRequestDataFlags.None)
+               {
+               }
 
-                public BuildRequestData (string projectFullPath, IDictionary<string, string> globalProperties,
-                                string toolsVersion, string[] targetsToBuild, HostServices hostServices, BuildRequestDataFlags flags)
-                {
-                        throw new NotImplementedException ();
-                }
+               public BuildRequestData (string projectFullPath, IDictionary<string, string> globalProperties,
+                               string toolsVersion, string[] targetsToBuild, HostServices hostServices, BuildRequestDataFlags flags)
+                       : this (new ProjectInstance (projectFullPath, globalProperties, toolsVersion), targetsToBuild, hostServices, flags)
+               {
+                       ExplicitlySpecifiedToolsVersion = toolsVersion;
+               }
 
-                public string ExplicitlySpecifiedToolsVersion { get; private set; }
-                public BuildRequestDataFlags Flags { get; private set; }
-                public HostServices HostServices { get; private set; }
-                public string ProjectFullPath { get; private set; }
-                public ProjectInstance ProjectInstance { get; private set; }
-                public ICollection<string> TargetNames { get; private set; }
+               public string ExplicitlySpecifiedToolsVersion { get; private set; }
 
-                ICollection<ProjectPropertyInstance> GlobalProperties {
-                        get { throw new NotImplementedException (); }
-                }
-        }
+               [MonoTODO ("unused")]
+               public BuildRequestDataFlags Flags { get; private set; }
+
+               [MonoTODO ("unused")]
+               public HostServices HostServices { get; private set; }
+
+               public string ProjectFullPath {
+                       get { return ProjectInstance.FullPath; }
+               }
+
+               [MonoTODO ("unused")]
+               public ProjectInstance ProjectInstance { get; private set; }
+               
+               [MonoTODO]
+               public IEnumerable<string> PropertiesToTransfer { get; private set; }
+
+               [MonoTODO]
+               public ICollection<string> TargetNames { get; private set; }
+
+               ICollection<ProjectPropertyInstance> GlobalProperties {
+                       get { return ProjectInstance.Properties.Where (p => ProjectInstance.GlobalProperties.Any (i => i.Key == p.Name)).ToArray (); } // we can use == as it should be identical match there.
+               }
+       }
 }
 
index 7286a247d23dc341a91d344abd1d2e7a307ab9b7..479b137a4f6c7cf6c921a1a16d17d5311d76e0f1 100644 (file)
 
 using System;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace Microsoft.Build.Execution
 {
-        public class BuildResult
-        {
-                public void AddResultsForTarget (string target, TargetResult result)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool HasResultsForTarget (string target)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void MergeResults (BuildResult results)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool CircularDependency {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int ConfigurationId {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public Exception Exception {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public int GlobalRequestId {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ITargetResult this [string target] {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int NodeRequestId {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public BuildResultCode OverallResult {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int ParentGlobalRequestId {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public IDictionary<string, TargetResult> ResultsByTarget {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int SubmissionId {
-                        get { throw new NotImplementedException (); }
-                }
-
-        }
+       public class BuildResult
+       {
+               public BuildResult ()
+               {
+                       ResultsByTarget = new Dictionary<string, TargetResult> ();
+               }
+               
+               public void AddResultsForTarget (string target, TargetResult result)
+               {
+                       ResultsByTarget.Add (target, result);
+               }
+
+               public bool HasResultsForTarget (string target)
+               {
+                       return ResultsByTarget.ContainsKey (target);
+               }
+
+               public void MergeResults (BuildResult results)
+               {
+                       if (ConfigurationId != results.ConfigurationId)
+                               throw new InvalidOperationException ("Argument BuildResults have inconsistent ConfigurationId.");
+                       if (GlobalRequestId != results.GlobalRequestId)
+                               throw new InvalidOperationException ("Argument BuildResults have inconsistent GlobalRequestId.");
+                       if (NodeRequestId != results.NodeRequestId)
+                               throw new InvalidOperationException ("Argument BuildResults have inconsistent NodeRequestId.");
+                       if (ParentGlobalRequestId != results.ParentGlobalRequestId)
+                               throw new InvalidOperationException ("Argument BuildResults have inconsistent ParentGlobalRequestId.");
+                       if (SubmissionId != results.SubmissionId)
+                               throw new InvalidOperationException ("Argument BuildResults have inconsistent SubmissionId.");
+                       
+                       CircularDependency |= results.CircularDependency;
+                       Exception = Exception ?? results.Exception;
+                       foreach (var p in results.ResultsByTarget)
+                               ResultsByTarget.Add (p.Key, p.Value);
+               }
+
+               public bool CircularDependency { get; internal set; }
+
+               public int ConfigurationId { get; internal set; }
+
+               public Exception Exception { get; set; }
+
+               public int GlobalRequestId { get; internal set; }
+
+               public ITargetResult this [string target] {
+                       get { return ResultsByTarget [target]; }
+               }
+
+               public int NodeRequestId { get; internal set; }
+
+               BuildResultCode? overall_result;
+               public BuildResultCode OverallResult {
+                       get {
+                               if (overall_result == null)
+                                       throw new InvalidOperationException ("Build has not finished");
+                               return overall_result.Value;
+                       }
+                       internal set { overall_result = value; }
+               }
+
+               public int ParentGlobalRequestId { get; internal set; }
+
+               public IDictionary<string, TargetResult> ResultsByTarget { get; private set; }
+
+               public int SubmissionId { get; internal set; }
+       }
 }
 
index 3a8a612b934292243f983020d789a8ef2dcfa299..91a9823ce810a2f539fddff0e37d0f120efebdc3 100644 (file)
@@ -2,8 +2,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using System;
+using System.Threading;
+using System.Threading.Tasks;
+using System.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Internal;
+using System.Collections.Generic;
 
 namespace Microsoft.Build.Execution
 {
-        public class BuildSubmission
-        {
-                private BuildSubmission ()
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+       public class BuildSubmission
+       {
+               static Random rnd = new Random ();
+
+               internal BuildSubmission (BuildManager build, BuildRequestData requestData)
+               {
+                       BuildManager = build;
+                       this.request = requestData;
+                       SubmissionId = rnd.Next ();
+               }
+
+               BuildRequestData request;
+               BuildSubmissionCompleteCallback callback;
+               bool is_started, is_completed, is_canceled;
+               ManualResetEvent wait_handle = new ManualResetEvent (true);
+
+               public object AsyncContext { get; private set; }
+               public BuildManager BuildManager { get; private set; }
+               public BuildResult BuildResult { get; set; }
+               public bool IsCompleted {
+                       get { return is_completed; }
+               }
+               public int SubmissionId { get; private set; }
+               public WaitHandle WaitHandle {
+                       get { return wait_handle; }
+               }
+               
+               internal BuildRequestData BuildRequest {
+                       get { return this.request; }
+               }
+
+               internal void Cancel ()
+               {
+                       if (is_canceled)
+                               throw new InvalidOperationException ("Build has already canceled");
+                       is_canceled = true;
+               }
+
+               public BuildResult Execute ()
+               {
+                       ExecuteAsync (null, null);
+                       WaitHandle.WaitOne ();
+                       return BuildResult;
+               }
+               
+               internal BuildResult InternalExecute ()
+               {
+                       BuildResult = new BuildResult () { SubmissionId = SubmissionId };
+                       try {
+                               var engine = new BuildEngine4 (this);
+                               string toolsVersion = request.ExplicitlySpecifiedToolsVersion ?? request.ProjectInstance.ToolsVersion ?? BuildManager.OngoingBuildParameters.DefaultToolsVersion;
+                               var outputs = new Dictionary<string,string> ();
+                               engine.BuildProject (() => is_canceled, BuildResult, request.ProjectInstance, request.TargetNames, BuildManager.OngoingBuildParameters.GlobalProperties, outputs, toolsVersion);
+                       } catch (Exception ex) {
+                               BuildResult.Exception = ex;
+                               BuildResult.OverallResult = BuildResultCode.Failure;
+                       }
+                       is_completed = true;
+                       if (callback != null)
+                               callback (this);
+                       wait_handle.Set ();
+                       return BuildResult;
+               }
+
+               public void ExecuteAsync (BuildSubmissionCompleteCallback callback, object context)
+               {
+                       if (is_completed)
+                               throw new InvalidOperationException ("Build has already completed");
+                       if (is_canceled)
+                               throw new InvalidOperationException ("Build has already canceled");
+                       if (is_started)
+                               throw new InvalidOperationException ("Build has already started");
+                       is_started = true;
+                       this.AsyncContext = context;
+                       this.callback = callback;
+                       wait_handle.Reset ();
+                       
+                       BuildManager.BuildNodeManager.Enqueue (this);
+               }
+       }
 }
 
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildSubmissionCompleteCallback.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/BuildSubmissionCompleteCallback.cs
new file mode 100644 (file)
index 0000000..fba101a
--- /dev/null
@@ -0,0 +1,5 @@
+namespace Microsoft.Build.Execution
+{
+       public delegate void BuildSubmissionCompleteCallback (BuildSubmission submission);
+}
+
index 2389bdf3309cb3440e875d4e7f59ad16d212c48f..e68755affeea6e50762384b827eb0871189e8c10 100644 (file)
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using Microsoft.Build.Framework;
 using System;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Framework;
 
 namespace Microsoft.Build.Execution
 {
-        public class HostServices
-        {
-                public ITaskHost GetHostObject (string projectFile, string targetName, string taskName)
-                {
-                        throw new NotImplementedException ();
-                }
+       public class HostServices
+       {
+               class HostObjectRegistration
+               {
+                       public string ProjectFile { get; set; }
+                       public string TargetName { get; set; }
+                       public string TaskName { get; set; }
+                       public ITaskHost HostObject { get; set; }
+               }
+               
+               readonly List<HostObjectRegistration> hosts = new List<HostObjectRegistration> ();
+               readonly Dictionary<string,NodeAffinity> node_affinities = new Dictionary<string, NodeAffinity> ();
+               
+               HostObjectRegistration GetHostRegistration (string projectFile, string targetName, string taskName)
+               {
+                       if (projectFile == null)
+                               throw new ArgumentNullException ("projectFile");
+                       if (targetName == null)
+                               throw new ArgumentNullException ("targetName");
+                       if (taskName == null)
+                               throw new ArgumentNullException ("taskName");
+                       return hosts.FirstOrDefault (h =>
+                               string.Equals (projectFile, h.ProjectFile, StringComparison.OrdinalIgnoreCase) &&
+                               string.Equals (targetName, h.TargetName, StringComparison.OrdinalIgnoreCase) &&
+                               string.Equals (taskName, h.TaskName, StringComparison.OrdinalIgnoreCase));
+               }
+               
+               public ITaskHost GetHostObject (string projectFile, string targetName, string taskName)
+               {
+                       var reg = GetHostRegistration (projectFile, targetName, taskName);
+                       return reg != null ? reg.HostObject : null;
+               }
 
-                public NodeAffinity GetNodeAffinity (string projectFile)
-                {
-                        throw new NotImplementedException ();
-                }
+               public NodeAffinity GetNodeAffinity (string projectFile)
+               {
+                       if (projectFile == null)
+                               throw new ArgumentNullException ("projectFile");
+                       NodeAffinity na;
+                       return node_affinities.TryGetValue (projectFile, out na) ? na : NodeAffinity.Any;
+               }
+               
+               IEnumerable<HostObjectRegistration> GetRegistrationsByProject (string project)
+               {
+                       return hosts.Where (h => string.Equals (project, h.ProjectFile, StringComparison.OrdinalIgnoreCase));
+               }
 
-                public void OnRenameProject (string oldFullPath, string newFullPath)
-                {
-                        throw new NotImplementedException ();
-                }
+               public void OnRenameProject (string oldFullPath, string newFullPath)
+               {
+                       if (oldFullPath == null)
+                               throw new ArgumentNullException ("oldFullPath");
+                       if (newFullPath == null)
+                               throw new ArgumentNullException ("newFullPath");
+                       foreach (var reg in GetRegistrationsByProject (oldFullPath))
+                               reg.ProjectFile = newFullPath;
+               }
 
-                public void RegisterHostObject (string projectFile, string targetName, string taskName, ITaskHost hostObject)
-                {
-                        throw new NotImplementedException ();
-                }
+               public void RegisterHostObject (string projectFile, string targetName, string taskName, ITaskHost hostObject)
+               {
+                       if (hostObject == null)
+                               throw new ArgumentNullException ("hostObject");
+                       var reg = GetHostRegistration (projectFile, targetName, taskName);
+                       if (reg != null)
+                               reg.HostObject = hostObject;
+                       else
+                               hosts.Add (new HostObjectRegistration () { ProjectFile = projectFile, TargetName = targetName, TaskName = taskName, HostObject = hostObject });
+               }
 
-                public void SetNodeAffinity (string projectFile, NodeAffinity nodeAffinity)
-                {
-                        throw new NotImplementedException ();
-                }
+               public void SetNodeAffinity (string projectFile, NodeAffinity nodeAffinity)
+               {
+                       if (projectFile == null)
+                               throw new ArgumentNullException ("projectFile");
+                       node_affinities [projectFile] = nodeAffinity;
+               }
 
-                public void UnregisterProject (string projectFullPath)
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+               public void UnregisterProject (string projectFullPath)
+               {
+                       if (projectFullPath == null)
+                               throw new ArgumentNullException ("projectFullPath");
+                       var removed = GetRegistrationsByProject (projectFullPath).ToArray ();
+                       foreach (var r in removed)
+                               hosts.Remove (r);
+               }
+       }
 }
 
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/NodeEngineShutdownReason.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/NodeEngineShutdownReason.cs
new file mode 100644 (file)
index 0000000..b88423f
--- /dev/null
@@ -0,0 +1,47 @@
+//
+// NodeEngineShutdownReason.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections;
+using System.Collections.Generic;
+using Microsoft.Build.BuildEngine;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Evaluation;
+using System.Linq;
+using System.IO;
+
+namespace Microsoft.Build.Internal
+{
+       public enum NodeEngineShutdownReason
+       {
+               BuildComplete,
+               BuildCompleteReuse,
+               ConnectionFailed,
+               Error,
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/OutOfProcNode.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/OutOfProcNode.cs
new file mode 100644 (file)
index 0000000..7237052
--- /dev/null
@@ -0,0 +1,48 @@
+//
+// OutOfProcNode.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections;
+using System.Collections.Generic;
+using Microsoft.Build.BuildEngine;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Evaluation;
+using System.Linq;
+using System.IO;
+
+namespace Microsoft.Build.Internal
+{
+       // from MSDN: this class has deprecated and there is no alternative.
+       public class OutOfProcNode
+       {
+               public NodeEngineShutdownReason Run (out Exception shutdownException)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
index 46614962228287b0b320dc7e6514c988aa2a56ff..91ce68a040ca2612db12f77207181e85caeea6bf 100644 (file)
@@ -3,8 +3,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 //
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
+using System.Linq;
 
 using Microsoft.Build.Construction;
 using Microsoft.Build.Evaluation;
 using Microsoft.Build.Framework;
+using Microsoft.Build.Internal.Expressions;
 using Microsoft.Build.Logging;
 
+//
+// It is not always consistent to reuse Project and its evaluation stuff mostly because
+// both BuildParameters.ctor() and Project.ctor() takes arbitrary ProjectCollection, which are not very likely eqivalent
+// (as BuildParameters.ctor(), unlike Project.ctor(...), is known to create a new ProjectCollection instance).
+//
+// However, that inconsistency could happen even if you only use ProjectInstance and BuildParameters.
+// They both have constructors that take ProjectCollection and there is no guarantee that the arguments are the same.
+// BuildManager.Build() does not fail because of inconsistent ProjectCollection instance on .NET.
+//
+// Anyhow, I'm not going to instantiate Project within ProjectInstance code for another reason:
+// ProjectCollection.GetLoadedProject() does not return any Project instnace for corresponding ProjectInstance
+// (or I should say, ProjectRootElement for both).
+using Microsoft.Build.Internal;
+using System.Xml;
+using Microsoft.Build.Exceptions;
+using System.IO;
+
+
 namespace Microsoft.Build.Execution
 {
        public class ProjectInstance
@@ -59,35 +81,210 @@ namespace Microsoft.Build.Execution
                public ProjectInstance (ProjectRootElement xml, IDictionary<string, string> globalProperties,
                                string toolsVersion, ProjectCollection projectCollection)
                {
-                       InitializeProperties ();
-                       
-                       throw new NotImplementedException ();
+                       projects = projectCollection;
+                       global_properties = globalProperties ?? new Dictionary<string, string> ();
+                       tools_version = !string.IsNullOrEmpty (toolsVersion) ? toolsVersion :
+                               !string.IsNullOrEmpty (xml.ToolsVersion) ? xml.ToolsVersion :
+                               projects.DefaultToolsVersion;
+                       InitializeProperties (xml, null);
                }
 
                public ProjectInstance (string projectFile, IDictionary<string, string> globalProperties,
                                string toolsVersion, ProjectCollection projectCollection)
+                       : this (ProjectRootElement.Create (projectFile), globalProperties, toolsVersion, projectCollection)
+               {
+               }
+
+               ProjectCollection projects;
+               IDictionary<string, string> global_properties;
+               
+               string full_path, directory;
+               #if NET_4_5
+               ElementLocation location;
+               #endif
+               
+               Dictionary<string, ProjectItemDefinitionInstance> item_definitions;
+               List<ResolvedImport> raw_imports; // maybe we don't need this...
+               List<ProjectItemInstance> all_evaluated_items;
+               List<ProjectItemInstance> raw_items;
+               List<ProjectPropertyInstance> properties;
+               Dictionary<string, ProjectTargetInstance> targets;
+               string tools_version;
+               
+               List<string> GetDefaultTargets (ProjectRootElement xml)
                {
-                       InitializeProperties ();
+                       var ret = xml.DefaultTargets.Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries).Select (s => s.Trim ()).ToList ();
+                       if (ret.Count == 0 && xml.Targets.Any ())
+                               ret.Add (xml.Targets.First ().Name);
+                       return ret;
+               }
+
+               void InitializeProperties (ProjectRootElement xml, ProjectInstance parent)
+               {
+                       #if NET_4_5
+                       location = xml.Location;
+                       #endif
+                       full_path = xml.FullPath;
+                       directory = string.IsNullOrWhiteSpace (xml.DirectoryPath) ? System.IO.Directory.GetCurrentDirectory () : xml.DirectoryPath;
+                       DefaultTargets = GetDefaultTargets (xml);
+                       InitialTargets = xml.InitialTargets.Split (item_target_sep, StringSplitOptions.RemoveEmptyEntries).Select (s => s.Trim ()).ToList ();
+
+                       raw_imports = new List<ResolvedImport> ();
+                       item_definitions = new Dictionary<string, ProjectItemDefinitionInstance> ();
+                       targets = new Dictionary<string, ProjectTargetInstance> ();
+                       raw_items = new List<ProjectItemInstance> ();
                        
-                       throw new NotImplementedException ();
+                       // FIXME: this is likely hack. Test ImportedProject.Properties to see what exactly should happen.
+                       if (parent != null) {
+                               properties = parent.properties;
+                       } else {
+                               properties = new List<ProjectPropertyInstance> ();
+                       
+                               foreach (DictionaryEntry p in Environment.GetEnvironmentVariables ())
+                                       // FIXME: this is kind of workaround for unavoidable issue that PLATFORM=* is actually given
+                                       // on some platforms and that prevents setting default "PLATFORM=AnyCPU" property.
+                                       if (!string.Equals ("PLATFORM", (string) p.Key, StringComparison.OrdinalIgnoreCase))
+                                               this.properties.Add (new ProjectPropertyInstance ((string) p.Key, false, (string) p.Value));
+                               foreach (var p in global_properties)
+                                       this.properties.Add (new ProjectPropertyInstance (p.Key, false, p.Value));
+                               var tools = projects.GetToolset (tools_version) ?? projects.GetToolset (projects.DefaultToolsVersion);
+                               foreach (var p in projects.GetReservedProperties (tools, this, xml))
+                                       this.properties.Add (p);
+                               foreach (var p in ProjectCollection.GetWellKnownProperties (this))
+                                       this.properties.Add (p);
+                       }
+
+                       ProcessXml (parent, xml);
                }
                
-               void InitializeProperties ()
+               static readonly char [] item_target_sep = {';'};
+               
+               void ProcessXml (ProjectInstance parent, ProjectRootElement xml)
                {
-                       DefaultTargets = new List<string> ();
-                       InitialTargets = new List<string> ();
+                       TaskDatabase = new BuildTaskDatabase (this, xml);
+                       
+                       // this needs to be initialized here (regardless of that items won't be evaluated at property evaluation;
+                       // Conditions could incorrectly reference items and lack of this list causes NRE.
+                       all_evaluated_items = new List<ProjectItemInstance> ();
+
+                       // property evaluation happens couple of times.
+                       // At first step, all non-imported properties are evaluated TOO, WHILE those properties are being evaluated.
+                       // This means, Include and IncludeGroup elements with Condition attribute MAY contain references to
+                       // properties and they will be expanded.
+                       var elements = EvaluatePropertiesAndImports (xml.Children).ToArray (); // ToArray(): to not lazily evaluate elements.
+                       
+                       // next, evaluate items
+                       EvaluateItems (xml, elements);
+                       
+                       // finally, evaluate targets and tasks
+                       EvaluateTasks (elements);                       
                }
                
-               Dictionary<string, string> global_properties = new Dictionary<string, string> ();
+               IEnumerable<ProjectElement> EvaluatePropertiesAndImports (IEnumerable<ProjectElement> elements)
+               {
+                       // First step: evaluate Properties
+                       foreach (var child in elements) {
+                               yield return child;
+                               var pge = child as ProjectPropertyGroupElement;
+                               if (pge != null && EvaluateCondition (pge.Condition))
+                                       foreach (var p in pge.Properties)
+                                               // do not allow overwriting reserved or well-known properties by user
+                                               if (!this.properties.Any (_ => (_.IsImmutable) && _.Name.Equals (p.Name, StringComparison.InvariantCultureIgnoreCase)))
+                                                       if (EvaluateCondition (p.Condition))
+                                                               this.properties.Add (new ProjectPropertyInstance (p.Name, false, ExpandString (p.Value)));
+
+                               var ige = child as ProjectImportGroupElement;
+                               if (ige != null && EvaluateCondition (ige.Condition)) {
+                                       foreach (var incc in ige.Imports) {
+                                               foreach (var e in Import (incc))
+                                                       yield return e;
+                                       }
+                               }
+                               var inc = child as ProjectImportElement;
+                               if (inc != null && EvaluateCondition (inc.Condition))
+                                       foreach (var e in Import (inc))
+                                               yield return e;
+                       }
+               }
                
+               internal IEnumerable<T> GetAllItems<T> (string include, string exclude, Func<string,T> creator, Func<string,ITaskItem> taskItemCreator, Func<string,bool> itemTypeCheck, Action<T,string> assignRecurse)
+               {
+                       return ProjectCollection.GetAllItems<T> (ExpandString, include, exclude, creator, taskItemCreator, Directory, assignRecurse,
+                               t => all_evaluated_items.Any (i => i.EvaluatedInclude == t.ItemSpec && itemTypeCheck (i.ItemType)));
+               }
+
+               void EvaluateItems (ProjectRootElement xml, IEnumerable<ProjectElement> elements)
+               {
+                       foreach (var child in elements) {
+                               var ige = child as ProjectItemGroupElement;
+                               if (ige != null) {
+                                       foreach (var p in ige.Items) {
+                                               if (!EvaluateCondition (ige.Condition) || !EvaluateCondition (p.Condition))
+                                                       continue;
+                                               Func<string,ProjectItemInstance> creator = s => new ProjectItemInstance (this, p.ItemType, p.Metadata.Select (m => new KeyValuePair<string,string> (m.Name, m.Value)).ToList (), s);
+                                               foreach (var item in GetAllItems (p.Include, p.Exclude, creator, s => new ProjectTaskItem (p, s), it => string.Equals (it, p.ItemType, StringComparison.OrdinalIgnoreCase), (t, s) => t.RecursiveDir = s)) {
+                                                       raw_items.Add (item);
+                                                       all_evaluated_items.Add (item);
+                                               }
+                                       }
+                               }
+                               var def = child as ProjectItemDefinitionGroupElement;
+                               if (def != null) {
+                                       foreach (var p in def.ItemDefinitions) {
+                                               if (EvaluateCondition (p.Condition)) {
+                                                       ProjectItemDefinitionInstance existing;
+                                                       if (!item_definitions.TryGetValue (p.ItemType, out existing))
+                                                               item_definitions.Add (p.ItemType, (existing = new ProjectItemDefinitionInstance (p)));
+                                                       existing.AddItems (p);
+                                               }
+                                       }
+                               }
+                       }
+                       all_evaluated_items.Sort ((p1, p2) => string.Compare (p1.ItemType, p2.ItemType, StringComparison.OrdinalIgnoreCase));
+               }
+               
+               void EvaluateTasks (IEnumerable<ProjectElement> elements)
+               {
+                       foreach (var child in elements) {
+                               var te = child as ProjectTargetElement;
+                               if (te != null)
+                                       this.targets.Add (te.Name, new ProjectTargetInstance (te));
+                       }
+               }
+               
+               IEnumerable<ProjectElement> Import (ProjectImportElement import)
+               {
+                       string dir = projects.GetEvaluationTimeThisFileDirectory (() => FullPath);
+                       string path = WindowsCompatibilityExtensions.NormalizeFilePath (ExpandString (import.Project));
+                       path = Path.IsPathRooted (path) ? path : dir != null ? Path.Combine (dir, path) : Path.GetFullPath (path);
+                       if (projects.OngoingImports.Contains (path))
+                               throw new InvalidProjectFileException (import.Location, null, string.Format ("Circular imports was detected: {0} is already on \"importing\" stack", path));
+                       projects.OngoingImports.Push (path);
+                       try {
+                               using (var reader = XmlReader.Create (path)) {
+                                       var root = ProjectRootElement.Create (reader, projects);
+                                       if (DefaultTargets.Count == 0)
+                                               DefaultTargets.AddRange (GetDefaultTargets (root));
+                                       raw_imports.Add (new ResolvedImport (import, root, true));
+                                       return this.EvaluatePropertiesAndImports (root.Children).ToArray ();
+                               }
+                       } finally {
+                               projects.OngoingImports.Pop ();
+                       }
+               }
+
+               internal IEnumerable<ProjectItemInstance> AllEvaluatedItems {
+                       get { return all_evaluated_items; }
+               }
+
                public List<string> DefaultTargets { get; private set; }
                
                public string Directory {
-                       get { throw new NotImplementedException (); }
+                       get { return directory; }
                }
                
                public string FullPath {
-                       get { throw new NotImplementedException (); }
+                       get { return full_path; }
                }
                
                public IDictionary<string, string> GlobalProperties {
@@ -103,33 +300,33 @@ namespace Microsoft.Build.Execution
 #endif
                
                public IDictionary<string, ProjectItemDefinitionInstance> ItemDefinitions {
-                       get { throw new NotImplementedException (); }
+                       get { return item_definitions; }
                }
                
                public ICollection<ProjectItemInstance> Items {
-                       get { throw new NotImplementedException (); }
+                       get { return all_evaluated_items; }
                }
                
                public ICollection<string> ItemTypes {
-                       get { throw new NotImplementedException (); }
+                       get { return all_evaluated_items.Select (i => i.ItemType).Distinct ().ToArray (); }
                }
 
 #if NET_4_5            
                public ElementLocation ProjectFileLocation {
-                       get { throw new NotImplementedException (); }
+                       get { return location; }
                }
 #endif
 
                public ICollection<ProjectPropertyInstance> Properties {
-                       get { throw new NotImplementedException (); }
+                       get { return properties; }
                }
                
                public IDictionary<string, ProjectTargetInstance> Targets {
-                       get { throw new NotImplementedException (); }
+                       get { return targets; }
                }
                
                public string ToolsVersion {
-                       get { throw new NotImplementedException (); }
+                       get { return tools_version; }
                }
 
                public ProjectItemInstance AddItem (string itemType, string evaluatedInclude)
@@ -139,7 +336,10 @@ namespace Microsoft.Build.Execution
                
                public ProjectItemInstance AddItem (string itemType, string evaluatedInclude, IEnumerable<KeyValuePair<string, string>> metadata)
                {
-                       throw new NotImplementedException ();
+                       var item = new ProjectItemInstance (this, itemType, metadata, evaluatedInclude);
+                       raw_items.Add (item);
+                       all_evaluated_items.Add (item);
+                       return item;
                }
 
                public bool Build ()
@@ -154,7 +354,7 @@ namespace Microsoft.Build.Execution
                
                public bool Build (IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers)
                {
-                       return Build ((string []) null, loggers, remoteLoggers);
+                       return Build (DefaultTargets.ToArray (), loggers, remoteLoggers);
                }
 
                public bool Build (string target, IEnumerable<ILogger> loggers)
@@ -180,12 +380,20 @@ namespace Microsoft.Build.Execution
 
                public bool Build (string[] targets, IEnumerable<ILogger> loggers, out IDictionary<string, TargetResult> targetOutputs)
                {
-                               return Build (targets, loggers, new ForwardingLoggerRecord [0], out targetOutputs);
+                       return Build (targets, loggers, new ForwardingLoggerRecord [0], out targetOutputs);
                }
 
                public bool Build (string[] targets, IEnumerable<ILogger> loggers, IEnumerable<ForwardingLoggerRecord> remoteLoggers, out IDictionary<string, TargetResult> targetOutputs)
                {
-                       throw new NotImplementedException ();
+                       var manager = new BuildManager ();
+                       var parameters = new BuildParameters (projects) {
+                               ForwardingLoggers = remoteLoggers,
+                               Loggers = loggers,
+                       };
+                       var requestData = new BuildRequestData (this, targets);
+                       var result = manager.Build (parameters, requestData);
+                       targetOutputs = result.ResultsByTarget;
+                       return result.OverallResult == BuildResultCode.Success;
                }
                
                public ProjectInstance DeepCopy ()
@@ -200,17 +408,22 @@ namespace Microsoft.Build.Execution
                
                public bool EvaluateCondition (string condition)
                {
-                       throw new NotImplementedException ();
+                       return string.IsNullOrWhiteSpace (condition) || new ExpressionEvaluator (this, null).EvaluateAsBoolean (condition);
                }
 
                public string ExpandString (string unexpandedValue)
                {
-                       throw new NotImplementedException ();
+                       return ExpandString (unexpandedValue, null);
+               }
+               
+               string ExpandString (string unexpandedValue, string replacementForMissingStuff)
+               {
+                       return new ExpressionEvaluator (this, replacementForMissingStuff).Evaluate (unexpandedValue);
                }
 
                public ICollection<ProjectItemInstance> GetItems (string itemType)
                {
-                       throw new NotImplementedException ();
+                       return new CollectionFromEnumerable<ProjectItemInstance> (Items.Where (p => p.ItemType.Equals (itemType, StringComparison.OrdinalIgnoreCase)));
                }
 
                public IEnumerable<ProjectItemInstance> GetItemsByItemTypeAndEvaluatedInclude (string itemType, string evaluatedInclude)
@@ -220,27 +433,36 @@ namespace Microsoft.Build.Execution
 
                public ProjectPropertyInstance GetProperty (string name)
                {
-                       throw new NotImplementedException ();
+                       return properties.FirstOrDefault (p => p.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
                }
                
                public string GetPropertyValue (string name)
                {
-                       throw new NotImplementedException ();
+                       var prop = GetProperty (name);
+                       return prop != null ? prop.EvaluatedValue : string.Empty;
                }
                
                public bool RemoveItem (ProjectItemInstance item)
                {
-                       throw new NotImplementedException ();
+                       // yeah, this raw_items should vanish...
+                       raw_items.Remove (item);
+                       return all_evaluated_items.Remove (item);
                }
 
                public bool RemoveProperty (string name)
                {
-                       throw new NotImplementedException ();
+                       var removed = properties.FirstOrDefault (p => p.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+                       if (removed == null)
+                               return false;
+                       properties.Remove (removed);
+                       return true;
                }
                
                public ProjectPropertyInstance SetProperty (string name, string evaluatedValue)
                {
-                       throw new NotImplementedException ();
+                       var p = new ProjectPropertyInstance (name, false, evaluatedValue);
+                       properties.Add (p);
+                       return p;
                }
                
                public ProjectRootElement ToProjectRootElement ()
@@ -259,32 +481,46 @@ namespace Microsoft.Build.Execution
 
                public static string GetEvaluatedItemIncludeEscaped (ProjectItemDefinitionInstance item)
                {
+                       // ?? ItemDefinition does not have Include attribute. What's the point here?
                        throw new NotImplementedException ();
                }
 
                public static string GetEvaluatedItemIncludeEscaped (ProjectItemInstance item)
                {
-                       throw new NotImplementedException ();
+                       return ProjectCollection.Escape (item.EvaluatedInclude);
                }
 
                public static string GetMetadataValueEscaped (ProjectMetadataInstance metadatum)
                {
-                       throw new NotImplementedException ();
+                       return ProjectCollection.Escape (metadatum.EvaluatedValue);
                }
                
                public static string GetMetadataValueEscaped (ProjectItemDefinitionInstance item, string name)
                {
-                       throw new NotImplementedException ();
+                       var md = item.Metadata.FirstOrDefault (m => m.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+                       return md != null ? ProjectCollection.Escape (md.EvaluatedValue) : null;
                }
                
                public static string GetMetadataValueEscaped (ProjectItemInstance item, string name)
                {
-                       throw new NotImplementedException ();
+                       var md = item.Metadata.FirstOrDefault (m => m.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+                       return md != null ? ProjectCollection.Escape (md.EvaluatedValue) : null;
                }
 
                public static string GetPropertyValueEscaped (ProjectPropertyInstance property)
                {
-                       throw new NotImplementedException ();
+                       // WTF happens here.
+                       //return ProjectCollection.Escape (property.EvaluatedValue);
+                       return property.EvaluatedValue;
+               }
+
+               internal BuildTaskDatabase TaskDatabase { get; private set; }
+               
+               internal string GetFullPath (string pathRelativeToProject)
+               {
+                       if (Path.IsPathRooted (pathRelativeToProject))
+                               return pathRelativeToProject;
+                       return Path.GetFullPath (Path.Combine (Directory, pathRelativeToProject));
                }
        }
 }
index 4641a951cecc2c57a290f67fd3c0b0a5bae399a7..fb10ceec177a720dd4ed38383eaf6584a1a78a14 100644 (file)
@@ -4,7 +4,7 @@
 // Author:
 //   Atsushi Enomoto (atsushi@veritas-vos-liberabit.com)
 //
-// Copyright (C) 2012 Xamarin Inc.
+// Copyright (C) 2012,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 using Microsoft.Build.Framework;
 using System;
 using System.Collections.Generic;
+using Microsoft.Build.Construction;
+using System.Linq;
 
 namespace Microsoft.Build.Execution
 {
        public class ProjectItemDefinitionInstance
        {
-               internal ProjectItemDefinitionInstance ()
+               internal ProjectItemDefinitionInstance (ProjectItemDefinitionElement xml)
                {
+                       ItemType = xml.ItemType;
+                       AddItems (xml);
                }
                
-               public string ItemType {
-                       get { throw new NotImplementedException (); }
-               }
+               List<ProjectMetadataInstance> metadata = new List<ProjectMetadataInstance> ();
+               
+               public string ItemType { get; private set; }
                
                public ICollection<ProjectMetadataInstance> Metadata {
-                       get { throw new NotImplementedException (); }
+                       get { return metadata; }
                }
                
                public int MetadataCount {
-                       get { throw new NotImplementedException (); }
+                       get { return metadata.Count; }
                }
                
                public IEnumerable<string> MetadataNames {
-                       get { throw new NotImplementedException (); }
+                       get { return metadata.Select (m => m.Name).ToArray (); }
+               }
+               
+               internal void AddItems (ProjectItemDefinitionElement xml)
+               {
+                       foreach (var item in xml.Metadata) {
+                               var existing = metadata.FirstOrDefault (i => i.Name == item.Name);
+                               if (existing != null)
+                                       metadata.Remove (existing);
+                               metadata.Add (new ProjectMetadataInstance (item.Name, item.Value));
+                       }
                }
        }
 }
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskInstance.cs
new file mode 100644 (file)
index 0000000..bf9d03f
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// ProjectItemGroupTaskInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public sealed class ProjectItemGroupTaskInstance : ProjectTargetInstanceChild
+       {
+               internal ProjectItemGroupTaskInstance (ProjectItemGroupElement xml)
+               {
+                       condition = xml.Condition;
+                       condition_location = xml.ConditionLocation;
+                       //this.FullPath = fullPath;
+                       location = xml.Location;
+                       
+                       Items = xml.Items.Select (item => new ProjectItemGroupTaskItemInstance (item)).ToArray ();
+               }
+               
+               readonly string condition;
+               readonly ElementLocation condition_location, location;
+               
+               public override string Condition {
+                       get { return condition; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation ConditionLocation {
+                       get { return condition_location; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation Location {
+                       get { return location; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               ElementLocation ExecuteTargetsLocation { get; private set; }
+               
+               public ICollection<ProjectItemGroupTaskItemInstance> Items { get; private set; }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskItemInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskItemInstance.cs
new file mode 100644 (file)
index 0000000..8d947b7
--- /dev/null
@@ -0,0 +1,95 @@
+//
+// ProjectItemGroupTaskItemInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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 Microsoft.Build.Construction;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.Build.Execution
+{
+       public class ProjectItemGroupTaskItemInstance
+       {
+               internal ProjectItemGroupTaskItemInstance (ProjectItemElement xml)
+               {
+                       Condition = xml.Condition;
+                       Exclude = xml.Exclude;
+                       Include = xml.Include;
+                       ItemType = xml.ItemType;
+                       Metadata = xml.Metadata.Select (m => new ProjectItemGroupTaskMetadataInstance (m)).ToArray ();
+                       Remove = xml.Remove;
+                       #if NET_4_5
+                       KeepDuplicates = xml.KeepDuplicates;
+                       KeepMetadata = xml.KeepMetadata;
+                       RemoveMetadata = xml.RemoveMetadata;
+                       
+                       ConditionLocation = xml.ConditionLocation;
+                       ExcludeLocation = xml.ExcludeLocation;
+                       IncludeLocation = xml.IncludeLocation;
+                       Location = xml.Location;
+                       KeepDuplicatesLocation = xml.KeepDuplicatesLocation;
+                       RemoveLocation = xml.RemoveLocation;
+                       RemoveMetadataLocation = xml.RemoveMetadataLocation;                    
+                       #endif
+               }
+               
+               public string Condition { get; private set; }
+
+               public string Exclude { get; private set; }
+
+               public string Include { get; private set; }
+
+               public string ItemType { get; private set; }
+
+               public string KeepDuplicates { get; private set; }
+
+               public string KeepMetadata { get; private set; }
+
+               public ICollection<ProjectItemGroupTaskMetadataInstance> Metadata { get; private set; }
+
+               public string Remove { get; private set; }
+
+               public string RemoveMetadata { get; private set; }
+               #if NET_4_5
+               public ElementLocation ConditionLocation { get; private set; }
+
+               public ElementLocation ExcludeLocation { get; private set; }
+
+               public ElementLocation IncludeLocation { get; private set; }
+
+               public ElementLocation KeepDuplicatesLocation { get; private set; }
+
+               public ElementLocation KeepMetadataLocation { get; private set; }
+
+               public ElementLocation Location { get; private set; }
+
+               public ElementLocation RemoveLocation { get; private set; }
+
+               public ElementLocation RemoveMetadataLocation { get; private set; }
+               #endif
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskMetadataInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectItemGroupTaskMetadataInstance.cs
new file mode 100644 (file)
index 0000000..ad87173
--- /dev/null
@@ -0,0 +1,58 @@
+//
+// ProjectItemGroupTaskMetadataInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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.Collections.Generic;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public sealed class ProjectItemGroupTaskMetadataInstance
+       {
+               internal ProjectItemGroupTaskMetadataInstance (ProjectMetadataElement xml)
+               {
+                       Condition = xml.Condition;
+                       Name = xml.Name;
+                       Value = xml.Value;
+                       #if NET_4_5
+                       ConditionLocation = xml.ConditionLocation;
+                       Location = xml.Location;
+                       #endif
+               }
+               public string Condition { get; private set; }
+
+               public string Name { get; private set; }
+
+               public string Value { get; private set; }
+               #if NET_4_5
+               public ElementLocation ConditionLocation { get; private set; }
+
+               public ElementLocation Location { get; private set; }
+               #endif
+       }
+}
+
index 0e27811ef889aec5d23e4c33ac5477dc6868731f..720c4b32b165710aa09f7359963358ca43a05120 100644 (file)
@@ -3,8 +3,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-using Microsoft.Build.Framework;
 using System;
 using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Evaluation;
+using System.Collections;
+using Microsoft.Build.Construction;
+using System.Globalization;
+using System.IO;
 
 namespace Microsoft.Build.Execution
 {
-        public class ProjectItemInstance
+       public class ProjectItemInstance
                 : ITaskItem2
-        {
-                private ProjectItemInstance ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ProjectMetadataInstance GetMetadata (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public string GetMetadataValue (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public bool HasMetadata (string name)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void RemoveMetadata (string metadataName)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public void SetMetadata (IEnumerable<KeyValuePair<string, string>> metadataDictionary)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public ProjectMetadataInstance SetMetadata (string name, string evaluatedValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                public int DirectMetadataCount {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public string EvaluatedInclude {
-                        get { throw new NotImplementedException (); }
-                        set { throw new NotImplementedException (); }
-                }
-
-                public string ItemType {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public IEnumerable<ProjectMetadataInstance> Metadata {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public int MetadataCount {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ICollection<string> MetadataNames {
-                        get { throw new NotImplementedException (); }
-                }
-
-                public ProjectInstance Project {
-                        get { throw new NotImplementedException (); }
-                }
-
-                #region ITaskItem2 implementation
-                string ITaskItem2.GetMetadataValueEscaped (string metadataName)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                void ITaskItem2.SetMetadataValueLiteral (string metadataName, string metadataValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                System.Collections.IDictionary ITaskItem2.CloneCustomMetadataEscaped ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                string ITaskItem2.EvaluatedIncludeEscaped {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                        set {
-                                throw new NotImplementedException ();
-                        }
-                }
-                #endregion
-
-                #region ITaskItem implementation
-                System.Collections.IDictionary ITaskItem.CloneCustomMetadata ()
-                {
-                        throw new NotImplementedException ();
-                }
-
-                void ITaskItem.CopyMetadataTo (ITaskItem destinationItem)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                string ITaskItem.GetMetadata (string metadataName)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                void ITaskItem.RemoveMetadata (string metadataName)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                void ITaskItem.SetMetadata (string metadataName, string metadataValue)
-                {
-                        throw new NotImplementedException ();
-                }
-
-                string ITaskItem.ItemSpec {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                        set {
-                                throw new NotImplementedException ();
-                        }
-                }
-
-                int ITaskItem.MetadataCount {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                }
-
-                System.Collections.ICollection ITaskItem.MetadataNames {
-                        get {
-                                throw new NotImplementedException ();
-                        }
-                }
-                #endregion
-        }
+       {
+               internal ProjectItemInstance (ProjectInstance project, string itemType, IEnumerable<KeyValuePair<string,string>> metadata, string evaluatedInclude)
+               {
+                       this.project = project;
+                       this.evaluated_include = evaluatedInclude;
+                       this.item_type = itemType;
+                       this.metadata = new List<ProjectMetadataInstance> ();
+                       SetMetadata (metadata);
+               }
+               
+               readonly ProjectInstance project;
+               readonly string item_type;
+               string evaluated_include;
+               readonly List<ProjectMetadataInstance> metadata;
+               
+               public ProjectMetadataInstance GetMetadata (string name)
+               {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       // This does not return any Well Known metadata
+                       return Metadata.FirstOrDefault (m => m.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+               }
+
+               public string GetMetadataValue (string name)
+               {
+                       if (name == null)
+                               throw new ArgumentNullException ("name");
+                       var wk = ProjectCollection.GetWellKnownMetadata (name, EvaluatedInclude, project.GetFullPath, RecursiveDir);
+                       if (wk != null)
+                               return wk;
+                       var m = GetMetadata (name);
+                       return m != null ? m.EvaluatedValue : null;
+               }
+
+               public bool HasMetadata (string name)
+               {
+                       return GetMetadata (name) != null;
+               }
+
+               public void RemoveMetadata (string metadataName)
+               {
+                       var m = GetMetadata (metadataName);
+                       if (m != null)
+                               metadata.Remove (m);
+               }
+
+               public void SetMetadata (IEnumerable<KeyValuePair<string, string>> metadataDictionary)
+               {
+                       foreach (var p in metadataDictionary)
+                               SetMetadata (p.Key, p.Value);
+               }
+
+               public ProjectMetadataInstance SetMetadata (string name, string evaluatedValue)
+               {
+                       var m = metadata.FirstOrDefault (_ => _.Name.Equals (name, StringComparison.OrdinalIgnoreCase));
+                       if (m != null)
+                               metadata.Remove (m);
+                       m = new ProjectMetadataInstance (name, evaluatedValue);
+                       metadata.Add (m);
+                       return m;
+               }
+
+               public int DirectMetadataCount {
+                       get { throw new NotImplementedException (); }
+               }
+
+               public string EvaluatedInclude {
+                       get { return evaluated_include; }
+                       set {
+                               if (value == null)
+                                       throw new ArgumentNullException ("value");
+                               evaluated_include = value;
+                       }
+               }
+
+               public string ItemType {
+                       get { return item_type; }
+               }
+
+               public IEnumerable<ProjectMetadataInstance> Metadata {
+                       get { return metadata; }
+               }
+
+               public int MetadataCount {
+                       get { return metadata.Count; }
+               }
+
+               public ICollection<string> MetadataNames {
+                       get { return metadata.Select (m => m.Name).ToArray (); }
+               }
+
+               public ProjectInstance Project {
+                       get { return project; }
+               }
+               
+               internal string RecursiveDir { get; set; }
+
+               #region ITaskItem2 implementation
+
+               string ITaskItem2.GetMetadataValueEscaped (string metadataName)
+               {
+                       return ProjectCollection.Escape (GetMetadataValue (metadataName));
+               }
+
+               void ITaskItem2.SetMetadataValueLiteral (string metadataName, string metadataValue)
+               {
+                       SetMetadata (metadataName, metadataValue);
+               }
+
+               System.Collections.IDictionary ITaskItem2.CloneCustomMetadataEscaped ()
+               {
+                       var dic = ((ITaskItem) this).CloneCustomMetadata ();
+                       foreach (DictionaryEntry p in dic)
+                               dic [p.Key] = ProjectCollection.Escape ((string) p.Value);
+                       return dic;
+               }
+
+               string ITaskItem2.EvaluatedIncludeEscaped {
+                       get { return ProjectCollection.Escape (EvaluatedInclude); }
+                       set { EvaluatedInclude = ProjectCollection.Unescape (value); }
+               }
+
+               #endregion
+
+               #region ITaskItem implementation
+
+               IDictionary ITaskItem.CloneCustomMetadata ()
+               {
+                       var dic = new Hashtable ();
+                       foreach (var md in Metadata)
+                               dic [md.Name] = md.EvaluatedValue;
+                       return dic;
+               }
+
+               void ITaskItem.CopyMetadataTo (ITaskItem destinationItem)
+               {
+                       if (destinationItem == null)
+                               throw new ArgumentNullException ("destinationItem");
+                       foreach (var md in Metadata)
+                               destinationItem.SetMetadata (md.Name, md.EvaluatedValue);
+               }
+
+               string ITaskItem.GetMetadata (string metadataName)
+               {
+                       return GetMetadataValue (metadataName);
+               }
+
+               void ITaskItem.RemoveMetadata (string metadataName)
+               {
+                       RemoveMetadata (metadataName);
+               }
+
+               void ITaskItem.SetMetadata (string metadataName, string metadataValue)
+               {
+                       SetMetadata (metadataName, ProjectCollection.Unescape (metadataValue));
+               }
+
+               string ITaskItem.ItemSpec {
+                       get { return EvaluatedInclude; }
+                       set { EvaluatedInclude = value; }
+               }
+
+               int ITaskItem.MetadataCount {
+                       get { return MetadataCount; }
+               }
+
+               ICollection ITaskItem.MetadataNames {
+                       get { return MetadataNames.ToArray (); }
+               }
+
+               #endregion
+       }
 }
 
index b0386fe28aafca49fcf8ed231c7f3b471f2b907b..c94fe8740dab68500023ce41d0694ceaa6869891 100644 (file)
 //
 
 using System;
+using Microsoft.Build.Construction;
 
 namespace Microsoft.Build.Execution
 {
-        public class ProjectMetadataInstance
-        {
-                private ProjectMetadataInstance ()
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+       public class ProjectMetadataInstance
+       {
+               internal ProjectMetadataInstance (string name, string value)
+               {
+                       Name = name;
+                       EvaluatedValue = value;
+               }
+               
+               public string EvaluatedValue { get; private set; }
+               public string Name { get; private set; }
+               
+               public ProjectMetadataInstance DeepClone ()
+               {
+                       return new ProjectMetadataInstance (Name, EvaluatedValue);
+               }
+               
+               public override string ToString ()
+               {
+                       return string.Format ("{0}={1}", Name, EvaluatedValue);
+               }
+       }
 }
-
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectOnErrorInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectOnErrorInstance.cs
new file mode 100644 (file)
index 0000000..b5572ef
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// ProjectOnErrorInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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 Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public class ProjectOnErrorInstance : ProjectTargetInstanceChild
+       {
+               internal ProjectOnErrorInstance (ProjectOnErrorElement xml)
+               {
+                       condition = xml.Condition;
+                       ExecuteTargets = xml.ExecuteTargetsAttribute;
+                       //this.FullPath = fullPath;
+                       #if NET_4_5
+                       condition_location = xml.ConditionLocation;
+                       ExecuteTargetsLocation = xml.ExecuteTargetsAttributeLocation;
+                       location = xml.Location;
+                       #endif
+               }
+               
+               readonly string condition;
+               
+               public override string Condition {
+                       get { return condition; }
+               }
+
+               public string ExecuteTargets { get; private set; }
+               
+               readonly ElementLocation condition_location, location;
+               
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation ConditionLocation {
+                       get { return condition_location; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               ElementLocation ExecuteTargetsLocation { get; private set; }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation Location {
+                       get { return location; }
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyGroupTaskInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyGroupTaskInstance.cs
new file mode 100644 (file)
index 0000000..1e5d7fa
--- /dev/null
@@ -0,0 +1,82 @@
+//
+// ProjectPropertyGroupTaskInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public sealed class ProjectPropertyGroupTaskInstance : ProjectTargetInstanceChild
+       {
+               internal ProjectPropertyGroupTaskInstance (ProjectPropertyGroupElement xml)
+               {
+                       condition = xml.Condition;
+                       condition_location = xml.ConditionLocation;
+                       //this.FullPath = fullPath;
+                       location = xml.Location;
+                       
+                       Properties = xml.Properties.Select (prop => new ProjectPropertyGroupTaskPropertyInstance (prop)).ToArray ();
+               }
+               
+               readonly string condition;
+               readonly ElementLocation condition_location, location;
+               
+               public override string Condition {
+                       get { return condition; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation ConditionLocation {
+                       get { return condition_location; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation Location {
+                       get { return location; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               ElementLocation ExecuteTargetsLocation { get; private set; }
+               
+               public ICollection<ProjectPropertyGroupTaskPropertyInstance> Properties { get; private set; }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyGroupTaskPropertyInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectPropertyGroupTaskPropertyInstance.cs
new file mode 100644 (file)
index 0000000..df1d2c6
--- /dev/null
@@ -0,0 +1,61 @@
+//
+// ProjectPropertyGroupTaskPropertyInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public class ProjectPropertyGroupTaskPropertyInstance
+       {
+               internal ProjectPropertyGroupTaskPropertyInstance (ProjectPropertyElement xml)
+               {
+                       Condition = xml.Condition;
+                       Name = xml.Name;
+                       Value = xml.Value;
+                       #if NET_4_5
+                       ConditionLocation = xml.ConditionLocation;
+                       Location = xml.Location;
+                       #endif
+               }
+               
+               public string Condition { get; private set; }
+
+               public string Name { get; private set; }
+
+               public string Value { get; private set; }
+
+               #if NET_4_5
+               public ElementLocation ConditionLocation { get; private set; }
+
+               public ElementLocation Location { get; private set; }
+               #endif
+       }
+}
+
index 3b6b32c2d81938c3b16dd6bc1fac0ba787e8d3cb..5bacdbe61aa76070c3ee3d4abdb51b5de4ce8673 100644 (file)
@@ -3,8 +3,9 @@
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsushi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
@@ -30,12 +31,32 @@ using System;
 
 namespace Microsoft.Build.Execution
 {
-        public class ProjectPropertyInstance
-        {
-                private ProjectPropertyInstance ()
-                {
-                        throw new NotImplementedException ();
-                }
-        }
-}
+       public class ProjectPropertyInstance
+       {
+               internal ProjectPropertyInstance (string name, bool isImmutable, string evaluatedValue, Func<string> evaluatedValueGetter = null)
+               {
+                       Name = name;
+                       IsImmutable = isImmutable;
+                       evaluated_value_getter = evaluatedValueGetter ?? (() => evaluatedValue);
+               }
+
+               Func<string> evaluated_value_getter;
+               public string EvaluatedValue {
+                       get { return evaluated_value_getter (); }
+                       set {
+                               if (IsImmutable)
+                                       throw new InvalidOperationException ();
+                               evaluated_value_getter = () => value;
+                       }
+               }
 
+               public virtual bool IsImmutable { get; private set; }
+
+               public string Name { get; private set; }
+               
+               public override string ToString ()
+               {
+                       return string.Format ("{0}={1}", Name, EvaluatedValue);
+               }
+       }
+}
index a95ee16cb07c5ab540deb0f920ba916a919c57a8..3046811068e427fd1d5336d1b2a751430fd11610 100644 (file)
@@ -1,9 +1,11 @@
+//
 // ProjectTargetInstance.cs
 //
 // Author:
 //   Rolf Bjarne Kvinge (rolf@xamarin.com)
+//   Atsushi Enomoto (atsshi@xamarin.com)
 //
-// Copyright (C) 2011 Xamarin Inc.
+// Copyright (C) 2011,2013 Xamarin Inc.
 //
 // Permission is hereby granted, free of charge, to any person obtaining
 // a copy of this software and associated documentation files (the
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
+
 using System;
+using Microsoft.Build.Construction;
+using System.Collections.Generic;
+using System.Linq;
 
 namespace Microsoft.Build.Execution
 {
-        public sealed class ProjectTargetInstance
-        {
-                private ProjectTargetInstance ()
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+       public sealed class ProjectTargetInstance
+       {
+               internal ProjectTargetInstance (ProjectTargetElement xml)
+               {
+                       FullPath = xml.ContainingProject.FullPath;
+                       Children = xml.Children.Select<ProjectElement,ProjectTargetInstanceChild> (c => {
+                               if (c is ProjectOnErrorElement)
+                                       return new ProjectOnErrorInstance ((ProjectOnErrorElement) c);
+                               if (c is ProjectItemGroupElement)
+                                       return new ProjectItemGroupTaskInstance ((ProjectItemGroupElement) c);
+                               if (c is ProjectPropertyGroupElement)
+                                       return new ProjectPropertyGroupTaskInstance ((ProjectPropertyGroupElement) c);
+                               if (c is ProjectTaskElement)
+                                       return new ProjectTaskInstance ((ProjectTaskElement) c);
+                               throw new NotSupportedException ();
+                       }).ToArray ();
+                       Condition = xml.Condition;
+                       DependsOnTargets = xml.DependsOnTargets;
+                       //FullPath = fullPath;
+                       Inputs = xml.Inputs;
+                       KeepDuplicateOutputs = xml.KeepDuplicateOutputs;
+                       Name = xml.Name;
+                       OnErrorChildren = xml.OnErrors.Select (c => new ProjectOnErrorInstance (c)).ToArray ();
+                       Outputs = xml.Outputs;
+                       Returns = xml.Returns;
+                       Tasks = xml.Tasks.Select (t => new ProjectTaskInstance (t)).ToArray ();
+                       AfterTargetsLocation = xml.AfterTargetsLocation;
+                       BeforeTargetsLocation = xml.BeforeTargetsLocation;
+                       ConditionLocation = xml.ConditionLocation;
+                       DependsOnTargetsLocation = xml.DependsOnTargetsLocation;
+                       InputsLocation = xml.InputsLocation;
+                       KeepDuplicateOutputsLocation = xml.KeepDuplicateOutputsLocation;
+                       Location = xml.Location;
+                       OutputsLocation = xml.OutputsLocation;
+                       ReturnsLocation = xml.ReturnsLocation;
+               }
+
+               public IList<ProjectTargetInstanceChild> Children { get; private set; }
+               public string Condition { get; private set; }
+               public string DependsOnTargets { get; private set; }
+               public string FullPath { get; private set; }
+               public string Inputs { get; private set; }
+               public string KeepDuplicateOutputs { get; private set; }
+               public string Name { get; private set; }
+               public IList<ProjectOnErrorInstance> OnErrorChildren { get; private set; }
+               public string Outputs { get; private set; }
+               public string Returns { get; private set; }
+               public ICollection<ProjectTaskInstance> Tasks { get; private set; }
+#if NET_4_5
+               public ElementLocation AfterTargetsLocation { get; private set; }
+               public ElementLocation BeforeTargetsLocation { get; private set; }
+               public ElementLocation ConditionLocation { get; private set; }
+               public ElementLocation DependsOnTargetsLocation { get; private set; }
+               public ElementLocation InputsLocation { get; private set; }
+               public ElementLocation KeepDuplicateOutputsLocation { get; private set; }
+               public ElementLocation Location { get; private set; }
+               public ElementLocation OutputsLocation { get; private set; }
+               public ElementLocation ReturnsLocation { get; private set; }
+#else
+               internal ElementLocation AfterTargetsLocation { get; private set; }
+               internal ElementLocation BeforeTargetsLocation { get; private set; }
+               internal ElementLocation ConditionLocation { get; private set; }
+               internal ElementLocation DependsOnTargetsLocation { get; private set; }
+               internal ElementLocation InputsLocation { get; private set; }
+               internal ElementLocation KeepDuplicateOutputsLocation { get; private set; }
+               internal ElementLocation Location { get; private set; }
+               internal ElementLocation OutputsLocation { get; private set; }
+               internal ElementLocation ReturnsLocation { get; private set; }
+#endif
+       }
 }
 
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTargetInstanceChild.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTargetInstanceChild.cs
new file mode 100644 (file)
index 0000000..aa38e6b
--- /dev/null
@@ -0,0 +1,52 @@
+//
+// ProjectTargetInstanceChild.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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 Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public abstract class ProjectTargetInstanceChild
+       {
+               public abstract string Condition { get; }
+               public string FullPath { get; internal set; }
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               abstract ElementLocation ConditionLocation { get; }
+               
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               abstract ElementLocation Location { get; }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskInstance.cs
new file mode 100644 (file)
index 0000000..bc53da1
--- /dev/null
@@ -0,0 +1,108 @@
+//
+// ProjectOnErrorInstance.cs
+//
+// Author:
+//    Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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.Collections.Generic;
+using Microsoft.Build.Construction;
+using System.Linq;
+
+namespace Microsoft.Build.Execution
+{
+       public sealed class ProjectTaskInstance : ProjectTargetInstanceChild
+       {
+               internal ProjectTaskInstance (ProjectTaskElement xml)
+               {
+                       condition = xml.Condition;
+                       ContinueOnError = xml.ContinueOnError;
+                       Name = xml.Name;
+                       Outputs = xml.Outputs.Select (o => {
+                               if (o.IsOutputItem)
+                                       return (ProjectTaskInstanceChild) new ProjectTaskOutputItemInstance ((ProjectOutputElement) o);
+                               if (o.IsOutputProperty)
+                                       return new ProjectTaskOutputPropertyInstance ((ProjectOutputElement) o);
+                               throw new NotSupportedException ();
+                               }).ToArray ();
+                       Parameters = new Dictionary<string,string> (xml.Parameters);
+                       #if NET_4_5
+                       MSBuildArchitecture = xml.MSBuildArchitecture;
+                       MSBuildRuntime = xml.MSBuildRuntime;
+                       
+                       condition_location = xml.ConditionLocation;
+                       ContinueOnErrorLocation = xml.ContinueOnErrorLocation;
+                       location = xml.Location;
+                       MSBuildArchitectureLocation = xml.MSBuildArchitectureLocation;
+                       MSBuildRuntimeLocation = xml.MSBuildRuntimeLocation;
+                       #endif
+               }
+               
+               string condition;
+               public override string Condition {
+                       get { return condition; }
+               }
+               
+               ElementLocation condition_location, location;
+               
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation ConditionLocation {
+                       get { return condition_location; }
+               }
+
+               #if NET_4_5
+               public
+               #else
+               internal
+               #endif
+               override ElementLocation Location {
+                       get { return location; }
+               }
+               
+               public string ContinueOnError { get; private set; }
+               
+               #if NET_4_5
+               public ElementLocation ContinueOnErrorLocation { get; private set; }
+
+               public string MSBuildArchitecture { get; private set; }
+
+               public ElementLocation MSBuildArchitectureLocation { get; private set; }
+
+               public string MSBuildRuntime { get; private set; }
+
+               public ElementLocation MSBuildRuntimeLocation { get; private set; }
+               #endif
+               
+               public string Name { get; private set; }
+
+               public IList<ProjectTaskInstanceChild> Outputs { get; private set; }
+
+               public IDictionary<string, string> Parameters { get; private set; }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskInstanceChild.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskInstanceChild.cs
new file mode 100644 (file)
index 0000000..77ea7a2
--- /dev/null
@@ -0,0 +1,16 @@
+using System;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public abstract class ProjectTaskInstanceChild
+       {
+               public abstract string Condition { get; }
+               #if NET_4_5
+               public abstract ElementLocation ConditionLocation { get; }
+               public abstract ElementLocation Location { get; }
+               public abstract ElementLocation TaskParameterLocation { get; }
+               #endif
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskOutputItemInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskOutputItemInstance.cs
new file mode 100644 (file)
index 0000000..356f9a6
--- /dev/null
@@ -0,0 +1,42 @@
+using System;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public class ProjectTaskOutputItemInstance : ProjectTaskInstanceChild
+       {
+               internal ProjectTaskOutputItemInstance (ProjectOutputElement xml)
+               {
+                       condition = xml.Condition;
+                       ItemType = xml.ItemType;
+                       TaskParameter = xml.TaskParameter;
+                       #if NET_4_5
+                       condition_location = xml.ConditionLocation;
+                       location = xml.Location;
+                       task_parameter_location = xml.TaskParameterLocation;
+                       #endif
+               }
+               
+               public string ItemType { get; private set; }
+               public string TaskParameter { get; private set; }
+
+               readonly string condition;
+               public override string Condition {
+                       get { return condition; }
+               }
+               #if NET_4_5
+               readonly ElementLocation condition_location, location, task_parameter_location;
+               public ElementLocation ItemTypeLocation { get; private set; }
+               public override ElementLocation ConditionLocation {
+                       get { return condition_location; }
+               }
+               public override ElementLocation Location {
+                       get { return location; }
+               }
+               public override ElementLocation TaskParameterLocation {
+                       get { return task_parameter_location; }
+               }
+               #endif
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskOutputPropertyInstance.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Execution/ProjectTaskOutputPropertyInstance.cs
new file mode 100644 (file)
index 0000000..855268e
--- /dev/null
@@ -0,0 +1,43 @@
+using System;
+using Microsoft.Build.Construction;
+
+namespace Microsoft.Build.Execution
+{
+       public class ProjectTaskOutputPropertyInstance : ProjectTaskInstanceChild
+       {
+               internal ProjectTaskOutputPropertyInstance (ProjectOutputElement xml)
+               {
+                       condition = xml.Condition;
+                       PropertyName = xml.PropertyName;
+                       TaskParameter = xml.TaskParameter;
+                       #if NET_4_5
+                       condition_location = xml.ConditionLocation;
+                       location = xml.Location;
+                       task_parameter_location = xml.TaskParameterLocation;
+                       #endif
+               }
+
+               public string PropertyName { get; private set; }
+               public string TaskParameter { get; private set; }
+
+               readonly string condition;
+               public override string Condition {
+                       get { return condition; }
+               }
+               
+               #if NET_4_5
+               readonly ElementLocation condition_location, location, task_parameter_location;
+               public ElementLocation PropertyNameLocation { get; private set; }
+               public override ElementLocation ConditionLocation {
+                       get { return condition_location; }
+               }               
+               public override ElementLocation Location {
+                       get { return location; }
+               }
+               public override ElementLocation TaskParameterLocation {
+                       get { return task_parameter_location; }
+               }
+               #endif
+       }
+}
+
index 863966ba78a5b0b9142e55c1e2d9df3fd762a32f..d6dac3a8ffa5590944e53dc61f65af6bc7e55fbe 100644 (file)
 //
 
 using Microsoft.Build.Framework;
-
 using System;
+using System.Linq;
+using System.Collections.Generic;
 
 namespace Microsoft.Build.Execution
 {
-        public class TargetResult : ITargetResult
-        {
-                internal TargetResult ()
-                {
-                        throw new NotImplementedException ();
-                }
+       public class TargetResult : ITargetResult
+       {
+               internal TargetResult ()
+               {
+               }
 
-                public Exception Exception {
-                        get { throw new NotImplementedException (); }
-                }
+               public Exception Exception { get; private set; }
 
-                public ITaskItem[] Items {
-                        get { throw new NotImplementedException (); }
-                }
+               public ITaskItem[] Items { get; private set; }
 
+               public TargetResultCode ResultCode { get; private set; }
 
-                public TargetResultCode ResultCode {
-                        get { throw new NotImplementedException (); }
-                }
-        }
+               internal void Failure (Exception exception)
+               {
+                       this.Exception = exception;
+                       ResultCode = TargetResultCode.Failure;
+               }
+               
+               internal void Skip ()
+               {
+                       ResultCode = TargetResultCode.Skipped;
+               }
+               
+               internal void Success (IEnumerable<ITaskItem> items)
+               {
+                       Items = items.ToArray ();
+                       ResultCode = TargetResultCode.Success; 
+               }
+       }
 }
 
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildEngine4.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildEngine4.cs
new file mode 100644 (file)
index 0000000..22a8c61
--- /dev/null
@@ -0,0 +1,634 @@
+//
+// BuildEngine4.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections;
+using System.Collections.Generic;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Evaluation;
+using System.Linq;
+using System.IO;
+using Microsoft.Build.Exceptions;
+using System.Globalization;
+
+namespace Microsoft.Build.Internal
+{
+       class BuildEngine4
+#if NET_4_5
+               : IBuildEngine4
+#else
+               : IBuildEngine3
+#endif
+       {
+               public BuildEngine4 (BuildSubmission submission)
+               {
+                       this.submission = submission;
+                       event_source = new Microsoft.Build.BuildEngine.EventSource ();
+                       if (submission.BuildManager.OngoingBuildParameters.Loggers != null)
+                               foreach (var l in submission.BuildManager.OngoingBuildParameters.Loggers)
+                                       l.Initialize (event_source);
+               }
+
+               BuildSubmission submission;
+               ProjectInstance project;
+               ProjectTaskInstance current_task;
+               Microsoft.Build.BuildEngine.EventSource event_source;
+               
+               public ProjectCollection Projects {
+                       get { return submission.BuildManager.OngoingBuildParameters.ProjectCollection; }
+               }
+
+               // FIXME:
+               // While we are not faced to implement those features, there are some modern task execution requirements.
+               //
+               // This will have to be available for "out of process" nodes (see NodeAffinity).
+               // NodeAffinity is set per project file at BuildManager.HostServices.
+               // When NodeAffinity is set to OutOfProc, it should probably launch different build host
+               // that runs separate build tasks. (.NET has MSBuildTaskHost.exe which I guess is about that.)
+               //
+               // Also note that the complete implementation has to support LoadInSeparateAppDomainAttribute
+               // (which is most likely derived from AppDomainIsolatedBuildTask) that marks a task to run
+               // in separate AppDomain.
+               //
+               public void BuildProject (Func<bool> checkCancel, BuildResult result, ProjectInstance project, IEnumerable<string> targetNames, IDictionary<string,string> globalProperties, IDictionary<string,string> targetOutputs, string toolsVersion)
+               {
+                       if (toolsVersion == null)
+                               throw new ArgumentNullException ("toolsVersion");
+                       
+                       var parameters = submission.BuildManager.OngoingBuildParameters;
+                       var toolset = parameters.GetToolset (toolsVersion);
+                       if (toolset == null)
+                               throw new InvalidOperationException (string.Format ("Toolset version '{0}' was not resolved to valid toolset", toolsVersion));
+                       LogMessageEvent (new BuildMessageEventArgs (string.Format ("Using Toolset version {0}.", toolsVersion), null, null, MessageImportance.Low));
+                       var buildTaskFactory = new BuildTaskFactory (BuildTaskDatabase.GetDefaultTaskDatabase (toolset), submission.BuildRequest.ProjectInstance.TaskDatabase);
+                       BuildProject (new InternalBuildArguments () { CheckCancel = checkCancel, Result = result, Project = project, TargetNames = targetNames, GlobalProperties = globalProperties, TargetOutputs = targetOutputs, ToolsVersion = toolsVersion, BuildTaskFactory = buildTaskFactory });
+               }
+
+               class InternalBuildArguments
+               {
+                       public Func<bool> CheckCancel;
+                       public BuildResult Result;
+                       public ProjectInstance Project;
+                       public IEnumerable<string> TargetNames;
+                       public IDictionary<string,string> GlobalProperties;
+                       public IDictionary<string,string> TargetOutputs;
+                       public string ToolsVersion;
+                       public BuildTaskFactory BuildTaskFactory;
+                       
+                       public void AddTargetResult (string targetName, TargetResult targetResult)
+                       {
+                               if (!Result.HasResultsForTarget (targetName))
+                                       Result.AddResultsForTarget (targetName, targetResult);
+                       }
+               }
+               
+               void BuildProject (InternalBuildArguments args)
+               {
+                       var request = submission.BuildRequest;
+                       var parameters = submission.BuildManager.OngoingBuildParameters;
+                       this.project = args.Project;
+                       
+                       event_source.FireBuildStarted (this, new BuildStartedEventArgs ("Build Started", null, DateTime.Now));
+                       
+                       try {
+                               
+                               var initialPropertiesFormatted = "Initial Properties:\n" + string.Join (Environment.NewLine, project.Properties.OrderBy (p => p.Name).Select (p => string.Format ("{0} = {1}", p.Name, p.EvaluatedValue)).ToArray ());
+                               LogMessageEvent (new BuildMessageEventArgs (initialPropertiesFormatted, null, null, MessageImportance.Low));
+                               var initialItemsFormatted = "Initial Items:\n" + string.Join (Environment.NewLine, project.Items.OrderBy (i => i.ItemType).Select (i => string.Format ("{0} : {1}", i.ItemType, i.EvaluatedInclude)).ToArray ());
+                               LogMessageEvent (new BuildMessageEventArgs (initialItemsFormatted, null, null, MessageImportance.Low));
+                               
+                               // null targets -> success. empty targets -> success(!)
+                               if (request.TargetNames == null)
+                                       args.Result.OverallResult = BuildResultCode.Success;
+                               else {
+                                       foreach (var targetName in (args.TargetNames ?? request.TargetNames).Where (t => t != null))
+                                               BuildTargetByName (targetName, args);
+                       
+                                       // FIXME: check .NET behavior, whether cancellation always results in failure.
+                                       args.Result.OverallResult = args.CheckCancel () ? BuildResultCode.Failure : args.Result.ResultsByTarget.Any (p => p.Value.ResultCode == TargetResultCode.Failure) ? BuildResultCode.Failure : BuildResultCode.Success;
+                               }
+                       } catch (Exception ex) {
+                               args.Result.OverallResult = BuildResultCode.Failure;
+                               LogErrorEvent (new BuildErrorEventArgs (null, null, project.FullPath, 0, 0, 0, 0, "Unhandled exception occured during a build", null, null));
+                               LogMessageEvent (new BuildMessageEventArgs ("Exception details: " + ex, null, null, MessageImportance.Low));
+                               throw; // BuildSubmission re-catches this.
+                       } finally {
+                               event_source.FireBuildFinished (this, new BuildFinishedEventArgs ("Build Finished.", null, args.Result.OverallResult == BuildResultCode.Success, DateTime.Now));
+                       }
+               }
+               
+               bool BuildTargetByName (string targetName, InternalBuildArguments args)
+               {
+                       var request = submission.BuildRequest;
+                       var parameters = submission.BuildManager.OngoingBuildParameters;
+                       ProjectTargetInstance target;
+                       TargetResult dummyResult;
+
+                       if (args.Result.ResultsByTarget.TryGetValue (targetName, out dummyResult) && dummyResult.ResultCode == TargetResultCode.Success) {
+                               LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because it was already built successfully.", targetName), null, null, MessageImportance.Low));
+                               return true; // do not add result.
+                       }
+                       
+                       var targetResult = new TargetResult ();
+
+                       // null key is allowed and regarded as blind success(!) (as long as it could retrieve target)
+                       if (!request.ProjectInstance.Targets.TryGetValue (targetName, out target))
+                               throw new InvalidOperationException (string.Format ("target '{0}' was not found in project '{1}'", targetName, project.FullPath));
+                       else if (!args.Project.EvaluateCondition (target.Condition)) {
+                               LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because condition '{1}' was not met.", target.Name, target.Condition), null, null, MessageImportance.Low));
+                               targetResult.Skip ();
+                       } else {
+                               // process DependsOnTargets first.
+                               foreach (var dep in project.ExpandString (target.DependsOnTargets).Split (';').Select (s => s.Trim ()).Where (s => !string.IsNullOrEmpty (s))) {
+                                       if (!BuildTargetByName (dep, args)) {
+                                               return false;
+                                       }
+                               }
+                               
+                               Func<string,ITaskItem> creator = s => new TargetOutputTaskItem () { ItemSpec = s };
+                       
+                               event_source.FireTargetStarted (this, new TargetStartedEventArgs ("Target Started", null, target.Name, project.FullPath, target.FullPath));
+                               try {
+                                       if (!string.IsNullOrEmpty (target.Inputs) != !string.IsNullOrEmpty (target.Outputs)) {
+                                               targetResult.Failure (new InvalidProjectFileException (target.Location, null, string.Format ("Target {0} has mismatching Inputs and Outputs specification. When one is specified, another one has to be specified too.", targetName), null, null, null));
+                                       } else {
+                                               bool skip = false;
+                                               if (!string.IsNullOrEmpty (target.Inputs)) {
+                                                       var inputs = args.Project.GetAllItems (target.Inputs, string.Empty, creator, creator, s => true, (t, s) => {
+                                                       });
+                                                       if (!inputs.Any ()) {
+                                                               LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because there is no input.", target.Name), null, null, MessageImportance.Low));
+                                                               skip = true;
+                                                       } else {
+                                                               var outputs = args.Project.GetAllItems (target.Outputs, string.Empty, creator, creator, s => true, (t, s) => {
+                                                               });
+                                                               var needsUpdates = GetOlderOutputsThanInputs (inputs, outputs).FirstOrDefault ();
+                                                               if (needsUpdates != null)
+                                                                       LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' needs to be built because new output {1} is needed.", target.Name, needsUpdates.ItemSpec), null, null, MessageImportance.Low));
+                                                               else {
+                                                                       LogMessageEvent (new BuildMessageEventArgs (string.Format ("Target '{0}' was skipped because all the outputs are newer than all the inputs.", target.Name), null, null, MessageImportance.Low));
+                                                                       skip = true;
+                                                               }
+                                                       }
+                                               }
+                                               if (skip) {
+                                                       targetResult.Skip ();
+                                               } else {
+                                                       if (DoBuildTarget (target, targetResult, args)) {
+                                                               var items = args.Project.GetAllItems (target.Outputs, string.Empty, creator, creator, s => true, (t, s) => {
+                                                               });
+                                                               targetResult.Success (items);
+                                                       }
+                                               }
+                                       }
+                               } finally {
+                                       event_source.FireTargetFinished (this, new TargetFinishedEventArgs ("Target Finished", null, targetName, project.FullPath, target.FullPath, targetResult.ResultCode != TargetResultCode.Failure));
+                               }
+                       }
+                       args.AddTargetResult (targetName, targetResult);
+                       
+                       return targetResult.ResultCode != TargetResultCode.Failure;
+               }
+               
+               IEnumerable<ITaskItem> GetOlderOutputsThanInputs (IEnumerable<ITaskItem> inputs, IEnumerable<ITaskItem> outputs)
+               {
+                       return outputs.Where (o => !File.Exists (o.GetMetadata ("FullPath")) || inputs.Any (i => string.CompareOrdinal (i.GetMetadata ("LastModifiedTime"), o.GetMetadata ("LastModifiedTime")) > 0));
+               }
+               
+               bool DoBuildTarget (ProjectTargetInstance target, TargetResult targetResult, InternalBuildArguments args)
+               {
+                       var request = submission.BuildRequest;
+       
+                       // Here we check cancellation (only after TargetStarted event).
+                       if (args.CheckCancel ()) {
+                               targetResult.Failure (new BuildAbortedException ("Build has canceled"));
+                               return false;
+                       }
+                       
+                       var propsToRestore = new Dictionary<string,string> ();
+                       var itemsToRemove = new List<ProjectItemInstance> ();
+                       try {
+                               // Evaluate additional target properties
+                               foreach (var c in target.Children.OfType<ProjectPropertyGroupTaskInstance> ()) {
+                                       if (!args.Project.EvaluateCondition (c.Condition))
+                                               continue;
+                                       foreach (var p in c.Properties) {
+                                               if (!args.Project.EvaluateCondition (p.Condition))
+                                                       continue;
+                                               var value = args.Project.ExpandString (p.Value);
+                                               propsToRestore.Add (p.Name, project.GetPropertyValue (value));
+                                               project.SetProperty (p.Name, value);
+                                       }
+                               }
+                               
+                               // Evaluate additional target items
+                               foreach (var c in target.Children.OfType<ProjectItemGroupTaskInstance> ()) {
+                                       if (!args.Project.EvaluateCondition (c.Condition))
+                                               continue;
+                                       foreach (var item in c.Items) {
+                                               if (!args.Project.EvaluateCondition (item.Condition))
+                                                       continue;
+                                               Func<string,ProjectItemInstance> creator = i => new ProjectItemInstance (project, item.ItemType, item.Metadata.Select (m => new KeyValuePair<string,string> (m.Name, m.Value)), i);
+                                               foreach (var ti in project.GetAllItems (item.Include, item.Exclude, creator, creator, s => s == item.ItemType, (ti, s) => ti.SetMetadata ("RecurseDir", s)))
+                                                       itemsToRemove.Add (ti);
+                                       }
+                               }
+                               
+                               foreach (var c in target.Children.OfType<ProjectOnErrorInstance> ()) {
+                                       if (!args.Project.EvaluateCondition (c.Condition))
+                                               continue;
+                                       throw new NotImplementedException ();
+                               }
+                               
+                               // run tasks
+                               foreach (var ti in target.Children.OfType<ProjectTaskInstance> ()) {
+                                       current_task = ti;
+                                       if (!args.Project.EvaluateCondition (ti.Condition)) {
+                                               LogMessageEvent (new BuildMessageEventArgs (string.Format ("Task '{0}' was skipped because condition '{1}' wasn't met.", ti.Name, ti.Condition), null, null, MessageImportance.Low));
+                                               continue;
+                                       }
+                                       if (!RunBuildTask (target, ti, targetResult, args))
+                                               return false;
+                               }
+                       } finally {
+                               // restore temporary property state to the original state.
+                               foreach (var p in propsToRestore) {
+                                       if (p.Value == string.Empty)
+                                               project.RemoveProperty (p.Key);
+                                       else
+                                               project.SetProperty (p.Key, p.Value);
+                               }
+                               foreach (var item in itemsToRemove)
+                                       project.RemoveItem (item);
+                       }
+                       return true;
+               }
+               
+               bool RunBuildTask (ProjectTargetInstance target, ProjectTaskInstance taskInstance, TargetResult targetResult, InternalBuildArguments args)
+               {
+                       var request = submission.BuildRequest;
+
+                       var host = request.HostServices == null ? null : request.HostServices.GetHostObject (request.ProjectFullPath, target.Name, taskInstance.Name);
+                       
+                       // Create Task instance.
+                       var factoryIdentityParameters = new Dictionary<string,string> ();
+                       #if NET_4_5
+                       factoryIdentityParameters ["MSBuildRuntime"] = taskInstance.MSBuildRuntime;
+                       factoryIdentityParameters ["MSBuildArchitecture"] = taskInstance.MSBuildArchitecture;
+                       #endif
+                       var task = args.BuildTaskFactory.CreateTask (taskInstance.Name, factoryIdentityParameters, this);
+                       LogMessageEvent (new BuildMessageEventArgs (string.Format ("Using task {0} from {1}", taskInstance.Name, task.GetType ().AssemblyQualifiedName), null, null, MessageImportance.Low));
+                       task.HostObject = host;
+                       task.BuildEngine = this;
+                       
+                       // Prepare task parameters.
+                       var evaluatedTaskParams = taskInstance.Parameters.Select (p => new KeyValuePair<string,string> (p.Key, project.ExpandString (p.Value)));
+                       
+                       var requiredProps = task.GetType ().GetProperties ()
+                               .Where (p => p.CanWrite && p.GetCustomAttributes (typeof (RequiredAttribute), true).Any ());
+                       var missings = requiredProps.Where (p => !evaluatedTaskParams.Any (tp => tp.Key.Equals (p.Name, StringComparison.OrdinalIgnoreCase)));
+                       if (missings.Any ())
+                               throw new InvalidOperationException (string.Format ("Task {0} of type {1} is used without specifying mandatory property: {2}",
+                                       taskInstance.Name, task.GetType (), string.Join (", ", missings.Select (p => p.Name).ToArray ())));
+                       
+                       foreach (var p in evaluatedTaskParams) {
+                               var prop = task.GetType ().GetProperty (p.Key);
+                               if (prop == null)
+                                       throw new InvalidOperationException (string.Format ("Task {0} does not have property {1}", taskInstance.Name, p.Key));
+                               if (!prop.CanWrite)
+                                       throw new InvalidOperationException (string.Format ("Task {0} has property {1} but it is read-only.", taskInstance.Name, p.Key));
+                               if (string.IsNullOrEmpty (p.Value) && !requiredProps.Contains (prop))
+                                       continue;
+                               try {
+                                       var valueInstance = ConvertTo (p.Value, prop.PropertyType);
+                                       prop.SetValue (task, valueInstance, null);
+                               } catch (Exception ex) {
+                                       throw new InvalidOperationException (string.Format ("Failed to convert '{0}' for property '{1}' of type {2}", p.Value, prop.Name, prop.PropertyType), ex);
+                               }
+                       }
+                       
+                       // Do execute task.
+                       bool taskSuccess = false;
+                       event_source.FireTaskStarted (this, new TaskStartedEventArgs ("Task Started", null, project.FullPath, taskInstance.FullPath, taskInstance.Name));
+                       try {
+                               taskSuccess = task.Execute ();
+                       
+                               if (!taskSuccess) {
+                                       targetResult.Failure (null);
+                                       if (!ContinueOnError) {
+                                               return false;
+                                       }
+                               } else {
+                                       // Evaluate task output properties and items.
+                                       foreach (var to in taskInstance.Outputs) {
+                                               if (!project.EvaluateCondition (to.Condition))
+                                                       continue;
+                                               var toItem = to as ProjectTaskOutputItemInstance;
+                                               var toProp = to as ProjectTaskOutputPropertyInstance;
+                                               string taskParameter = toItem != null ? toItem.TaskParameter : toProp.TaskParameter;
+                                               var pi = task.GetType ().GetProperty (taskParameter);
+                                               if (pi == null)
+                                                       throw new InvalidOperationException (string.Format ("Task {0} does not have property {1} specified as TaskParameter", taskInstance.Name, toItem.TaskParameter));
+                                               if (!pi.CanRead)
+                                                       throw new InvalidOperationException (string.Format ("Task {0} has property {1} specified as TaskParameter, but it is write-only", taskInstance.Name, toItem.TaskParameter));
+                                               var value = ConvertFrom (pi.GetValue (task, null));
+                                               if (toItem != null) {
+                                                       LogMessageEvent (new BuildMessageEventArgs (string.Format ("Output Item {0} from TaskParameter {1}: {2}", toItem.ItemType, toItem.TaskParameter, value), null, null, MessageImportance.Low));
+                                                       foreach (var item in value.Split (';'))
+                                                               args.Project.AddItem (toItem.ItemType, item);
+                                               } else {
+                                                       LogMessageEvent (new BuildMessageEventArgs (string.Format ("Output Property {0} from TaskParameter {1}: {2}", toProp.PropertyName, toProp.TaskParameter, value), null, null, MessageImportance.Low));
+                                                       args.Project.SetProperty (toProp.PropertyName, value);
+                                               }
+                                       }
+                               }
+                       } finally {
+                               event_source.FireTaskFinished (this, new TaskFinishedEventArgs ("Task Finished", null, project.FullPath, taskInstance.FullPath, taskInstance.Name, taskSuccess));
+                       }
+                       return true;
+               }
+               
+               object ConvertTo (string source, Type targetType)
+               {
+                       if (targetType == typeof(ITaskItem) || targetType.IsSubclassOf (typeof(ITaskItem)))
+                               return new TargetOutputTaskItem () { ItemSpec = WindowsCompatibilityExtensions.NormalizeFilePath (source.Trim ()) };
+                       if (targetType.IsArray)
+                               return new ArrayList (source.Split (';').Select (s => s.Trim ()).Where (s => !string.IsNullOrEmpty (s)).Select (s => ConvertTo (s, targetType.GetElementType ())).ToArray ())
+                                               .ToArray (targetType.GetElementType ());
+                       if (targetType == typeof(bool)) {
+                               switch (source != null ? source.ToLower (CultureInfo.InvariantCulture) : string.Empty) {
+                               case "true":
+                               case "yes":
+                               case "on":
+                                       return true;
+                               case "false":
+                               case "no":
+                               case "off":
+                               case "":
+                                       return false;
+                               }
+                       }
+                       return Convert.ChangeType (source == "" ? null : source, targetType);
+               }
+               
+               string ConvertFrom (object source)
+               {
+                       if (source == null)
+                               return string.Empty;
+                       if (source is ITaskItem)
+                               return ((ITaskItem) source).ItemSpec;
+                       if (source.GetType ().IsArray)
+                               return string.Join (";", ((Array) source).Cast<object> ().Select (o => ConvertFrom (o)).ToArray ());
+                       else
+                               return (string) Convert.ChangeType (source, typeof (string));
+               }
+               
+               class TargetOutputTaskItem : ITaskItem2
+               {
+                       Hashtable metadata = new Hashtable ();
+                       
+                       #region ITaskItem2 implementation
+                       public string GetMetadataValueEscaped (string metadataName)
+                       {
+                               return ProjectCollection.Escape ((string) metadata [metadataName]);
+                       }
+                       public void SetMetadataValueLiteral (string metadataName, string metadataValue)
+                       {
+                               metadata [metadataName] = ProjectCollection.Unescape (metadataValue);
+                       }
+                       public IDictionary CloneCustomMetadataEscaped ()
+                       {
+                               var ret = new Hashtable ();
+                               foreach (DictionaryEntry e in metadata)
+                                       ret [e.Key] = ProjectCollection.Escape ((string) e.Value);
+                               return ret;
+                       }
+                       public string EvaluatedIncludeEscaped {
+                               get { return ProjectCollection.Escape (ItemSpec); }
+                               set { ItemSpec = ProjectCollection.Unescape (value); }
+                       }
+                       #endregion
+                       #region ITaskItem implementation
+                       public IDictionary CloneCustomMetadata ()
+                       {
+                               return new Hashtable (metadata);
+                       }
+                       public void CopyMetadataTo (ITaskItem destinationItem)
+                       {
+                               foreach (DictionaryEntry e in metadata)
+                                       destinationItem.SetMetadata ((string) e.Key, (string) e.Value);
+                       }
+                       public string GetMetadata (string metadataName)
+                       {
+                               var wk = ProjectCollection.GetWellKnownMetadata (metadataName, ItemSpec, Path.GetFullPath, null);
+                               if (wk != null)
+                                       return wk;
+                               return (string) metadata [metadataName];
+                       }
+                       public void RemoveMetadata (string metadataName)
+                       {
+                               metadata.Remove (metadataName);
+                       }
+                       public void SetMetadata (string metadataName, string metadataValue)
+                       {
+                               metadata [metadataName] = metadataValue;
+                       }
+                       public string ItemSpec { get; set; }
+                       public int MetadataCount {
+                               get { return metadata.Count; }
+                       }
+                       public ICollection MetadataNames {
+                               get { return metadata.Keys; }
+                       }
+                       #endregion
+               }
+               
+#if NET_4_5
+               #region IBuildEngine4 implementation
+               
+               // task objects are not in use anyways though...
+               
+               class TaskObjectRegistration
+               {
+                       public TaskObjectRegistration (object key, object obj, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection)
+                       {
+                               Key = key;
+                               Object = obj;
+                               Lifetime = lifetime;
+                               AllowEarlyCollection = allowEarlyCollection;
+                       }
+                       public object Key { get; private set; }
+                       public object Object { get; private set; }
+                       public RegisteredTaskObjectLifetime Lifetime { get; private set; }
+                       public bool AllowEarlyCollection { get; private set; }
+               }
+               
+               List<TaskObjectRegistration> task_objects = new List<TaskObjectRegistration> ();
+
+               public object GetRegisteredTaskObject (object key, RegisteredTaskObjectLifetime lifetime)
+               {
+                       var reg = task_objects.FirstOrDefault (t => t.Key == key && t.Lifetime == lifetime);
+                       return reg != null ? reg.Object : null;
+               }
+
+               public void RegisterTaskObject (object key, object obj, RegisteredTaskObjectLifetime lifetime, bool allowEarlyCollection)
+               {
+                       task_objects.Add (new TaskObjectRegistration (key, obj, lifetime, allowEarlyCollection));
+               }
+
+               public object UnregisterTaskObject (object key, RegisteredTaskObjectLifetime lifetime)
+               {
+                       var reg = task_objects.FirstOrDefault (t => t.Key == key && t.Lifetime == lifetime);
+                       if (reg != null)
+                               task_objects.Remove (reg);
+                       return reg.Object;
+               }
+               #endregion
+#endif
+
+               #region IBuildEngine3 implementation
+
+               public BuildEngineResult BuildProjectFilesInParallel (string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IList<string>[] removeGlobalProperties, string[] toolsVersion, bool returnTargetOutputs)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void Reacquire ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void Yield ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               #endregion
+
+               #region IBuildEngine2 implementation
+
+               public bool BuildProjectFile (string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs, string toolsVersion)
+               {
+                       var proj = GetProjectInstance (projectFileName, toolsVersion);
+                       var globalPropertiesThatMakeSense = new Dictionary<string,string> ();
+                       foreach (DictionaryEntry p in globalProperties)
+                               globalPropertiesThatMakeSense [(string) p.Key] = (string) p.Value;
+                       var result = new BuildResult ();
+                       var outputs = new Dictionary<string, string> ();
+                       BuildProject (() => false, result, proj, targetNames, globalPropertiesThatMakeSense, outputs, toolsVersion);
+                       foreach (var p in outputs)
+                               targetOutputs [p.Key] = p.Value;
+                       return result.OverallResult == BuildResultCode.Success;
+               }
+
+               public bool BuildProjectFilesInParallel (string[] projectFileNames, string[] targetNames, IDictionary[] globalProperties, IDictionary[] targetOutputsPerProject, string[] toolsVersion, bool useResultsCache, bool unloadProjectsOnCompletion)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public bool IsRunningMultipleNodes {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+               
+               ProjectInstance GetProjectInstance (string projectFileName, string toolsVersion)
+               {
+                       string fullPath = Path.GetFullPath (projectFileName);
+                       if (submission.BuildRequest.ProjectFullPath == fullPath)
+                               return submission.BuildRequest.ProjectInstance;
+                       // FIXME: could also be filtered by global properties
+                       // http://msdn.microsoft.com/en-us/library/microsoft.build.evaluation.projectcollection.getloadedprojects.aspx
+                       var project = Projects.GetLoadedProjects (projectFileName).FirstOrDefault (p => p.ToolsVersion == toolsVersion);
+                       if (project == null)
+                               throw new InvalidOperationException (string.Format ("Project '{0}' is not loaded", projectFileName));
+                       return submission.BuildManager.GetProjectInstanceForBuild (project);
+               }
+
+               #endregion
+
+               #region IBuildEngine implementation
+
+               public bool BuildProjectFile (string projectFileName, string[] targetNames, IDictionary globalProperties, IDictionary targetOutputs)
+               {
+                       return BuildProjectFile (projectFileName, targetNames, globalProperties, targetOutputs, Projects.DefaultToolsVersion);
+               }
+
+               public void LogCustomEvent (CustomBuildEventArgs e)
+               {
+                       event_source.FireCustomEventRaised (this, e);
+               }
+
+               public void LogErrorEvent (BuildErrorEventArgs e)
+               {
+                       event_source.FireErrorRaised (this, e);
+               }
+
+               public void LogMessageEvent (BuildMessageEventArgs e)
+               {
+                       event_source.FireMessageRaised (this, e);
+               }
+
+               public void LogWarningEvent (BuildWarningEventArgs e)
+               {
+                       event_source.FireWarningRaised (this, e);
+               }
+
+               public int ColumnNumberOfTaskNode {
+                       get { return current_task.Location != null ? current_task.Location.Column : 0; }
+               }
+
+               public bool ContinueOnError {
+                       get { return current_task != null && project.EvaluateCondition (current_task.Condition) && EvaluateContinueOnError (current_task.ContinueOnError); }
+               }
+               
+               bool EvaluateContinueOnError (string value)
+               {
+                       switch (value) {
+                       case "WarnAndContinue":
+                       case "ErrorAndContinue":
+                               return true;
+                       case "ErrorAndStop":
+                               return false;
+                       }
+                       // empty means "stop on error", so don't pass empty string to EvaluateCondition().
+                       return !string.IsNullOrEmpty (value) && project.EvaluateCondition (value);
+               }
+
+               public int LineNumberOfTaskNode {
+                       get { return current_task.Location != null ? current_task.Location.Line : 0; }
+               }
+
+               public string ProjectFileOfTaskNode {
+                       get { return current_task.FullPath; }
+               }
+
+               #endregion
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildNodeManager.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildNodeManager.cs
new file mode 100644 (file)
index 0000000..ebfad5b
--- /dev/null
@@ -0,0 +1,209 @@
+//
+// BuildNodeManager.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using System.Threading.Tasks;
+using System.Threading;
+using System.Collections.Concurrent;
+
+namespace Microsoft.Build.Internal
+{
+       class BuildNodeManager
+       {
+               public BuildNodeManager (BuildManager buildManager)
+               {
+                       BuildManager = buildManager;
+                       new Thread (RunLoop).Start ();
+               }
+
+               ~BuildNodeManager ()
+               {
+                       run_loop = false;
+                       queue_wait_handle.Set ();
+               }
+               
+               public BuildManager BuildManager { get; private set; }
+               
+               List<BuildNode> in_proc_nodes = new List<BuildNode> ();
+               List<BuildNode> out_proc_nodes = new List<BuildNode> ();
+               AutoResetEvent queue_wait_handle = new AutoResetEvent (false);
+               ConcurrentQueue<BuildSubmission> queued_builds = new ConcurrentQueue<BuildSubmission> ();
+               // FIXME: currently it is not in use but it should be stored somewhere for cancellation.
+               Dictionary<BuildSubmission,Task> ongoing_builds = new Dictionary<BuildSubmission, Task> ();
+               bool run_loop = true;
+
+               readonly TaskFactory<BuildResult> task_factory = new TaskFactory<BuildResult> ();
+               internal TaskFactory<BuildResult> ThreadTaskFactory {
+                       get { return task_factory; }
+               }
+               
+               void RunLoop ()
+               {
+                       while (run_loop) {
+                               try {
+                                       if (queued_builds.Count == 0)
+                                               queue_wait_handle.WaitOne ();
+                                       if (!run_loop)
+                                               break;
+                                       BuildSubmission build;
+                                       if (!queued_builds.TryDequeue (out build))
+                                               continue;
+                                       StartOneBuild (build);
+                               } catch (Exception ex) {
+                                       // FIXME: I guess INodeLogger should be used instead.
+                                       Console.Error.WriteLine ("Uncaught build node exception occured");
+                                       Console.Error.WriteLine (ex);
+                               }
+                       }
+               }
+
+               public void Stop ()
+               {
+                       run_loop = false;
+                       queue_wait_handle.Set ();
+               }
+
+               public void ResetCaches ()
+               {
+                       in_proc_nodes.Clear ();
+                       out_proc_nodes.Clear ();
+               }
+               
+               public void Enqueue (BuildSubmission build)
+               {
+                       queued_builds.Enqueue (build);
+                       queue_wait_handle.Set ();
+               }
+               
+               void StartOneBuild (BuildSubmission build)
+               {
+                       var node = TakeNode (build);
+                       // FIXME: Task (non-generic) here causes NotImplementedException in somewhere in Interlocked. It does not make sense.
+                       ongoing_builds [build] = task_factory.StartNew (node.ExecuteBuild);
+                       //new Thread (() => { node.ExecuteBuild (); }).Start ();
+               }
+               
+               void EndOneBuild (BuildNode node)
+               {
+                       var task = ongoing_builds [node.Build];
+                       ongoing_builds [node.Build] = null;
+                       node.Release ();
+               }
+               
+               // FIXME: take max nodes into account here, and get throttling working.
+               BuildNode TakeNode (BuildSubmission build)
+               {
+                       var host = BuildManager.OngoingBuildParameters.HostServices;
+                       NodeAffinity affinity;
+                       if (host == null)
+                               affinity = NodeAffinity.Any;
+                       else
+                               affinity = host.GetNodeAffinity (build.BuildRequest.ProjectFullPath);
+                       BuildNode n = GetReusableNode (affinity);
+                       if (n != null)
+                               n.Assign (build);
+                       else {
+                               n = new BuildNode (this, affinity == NodeAffinity.Any ? NodeAffinity.InProc : affinity);
+                               n.Assign (build);
+                               if (n.Affinity == NodeAffinity.InProc)
+                                       in_proc_nodes.Add (n);
+                               else
+                                       out_proc_nodes.Add (n);
+                       }
+                       return n;
+               }
+               
+               BuildNode GetReusableNode (NodeAffinity affinity)
+               {
+                       if (!BuildManager.OngoingBuildParameters.EnableNodeReuse)
+                               return null;
+                       
+                       if (affinity != NodeAffinity.OutOfProc)
+                               foreach (var n in in_proc_nodes)
+                                       if (n.IsAvailable && (n.Affinity & affinity) != 0)
+                                               return n;
+                       if (affinity != NodeAffinity.InProc)
+                               foreach (var n in out_proc_nodes)
+                                       if (n.IsAvailable && (n.Affinity & affinity) != 0)
+                                               return n;
+                       return null;
+               }
+       
+               internal class BuildNode
+               {
+                       static Random rnd = new Random ();
+                       
+                       public BuildNode (BuildNodeManager manager, NodeAffinity affinity)
+                       {
+                               Manager = manager;
+                               Affinity = affinity;
+                               Id = rnd.Next ();
+                       }
+                       
+                       public bool IsAvailable { get; private set; }
+                       public int Id { get; private set; }
+                       public BuildNodeManager Manager { get; set; }
+                       public NodeAffinity Affinity { get; private set; }
+                       public BuildSubmission Build { get; private set; }
+                       
+                       public void Assign (BuildSubmission build)
+                       {
+                               IsAvailable = false;
+                               Build = build;
+                       }
+                       
+                       public void Release ()
+                       {
+                               Build = null;
+                               IsAvailable = true;
+                       }
+                       
+                       public BuildResult ExecuteBuild ()
+                       {
+                               BuildResult result;
+                               try {
+                                       // FIXME: depending on NodeAffinity, build it through another MSBuild process.
+                                       if (Affinity == NodeAffinity.OutOfProc)
+                                               throw new NotImplementedException ();
+                                       result = Build.InternalExecute ();
+                               } catch (Exception ex) {
+                                       // FIXME: I guess INodeLogger should be used instead.
+                                       Console.Error.WriteLine ("Uncaught build node exception occured");
+                                       Console.Error.WriteLine (ex);
+                                       result = null;
+                               } finally {
+                                       Manager.EndOneBuild (this);
+                               }
+                               return result;
+                       }
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildTaskDatabase.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildTaskDatabase.cs
new file mode 100644 (file)
index 0000000..0b7660b
--- /dev/null
@@ -0,0 +1,138 @@
+//
+// BuildTaskFactory.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Framework;
+using System.Reflection;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Construction;
+using System.IO;
+using System.Xml;
+
+namespace Microsoft.Build.Internal
+{
+       class BuildTaskDatabase
+       {
+               const string default_tasks_file = "Microsoft.Common.tasks";
+               static readonly Dictionary<string,BuildTaskDatabase> default_factory = new Dictionary<string, BuildTaskDatabase> ();
+
+               public static BuildTaskDatabase GetDefaultTaskDatabase (Toolset toolset)
+               {
+                       if (toolset == null)
+                               throw new ArgumentNullException ("toolset");
+                       BuildTaskDatabase defaults;
+                       if (!default_factory.TryGetValue (toolset.ToolsVersion, out defaults)) {
+                               defaults = new BuildTaskDatabase (toolset);
+                       }
+                       return defaults;
+               }
+               
+               // for 'default' tasks.
+               BuildTaskDatabase (Toolset toolset)
+               {
+                       ProjectRootElement root;
+                       using (var xml = XmlReader.Create (Path.Combine (toolset.ToolsPath, default_tasks_file)))
+                               root = ProjectRootElement.Create (xml);
+                       LoadUsingTasks (null, root);
+               }
+               
+               public BuildTaskDatabase (ProjectInstance projectInstance, ProjectRootElement projectRootElement)
+               {
+                       LoadUsingTasks (projectInstance, projectRootElement);
+               }
+               
+               internal class TaskDescription
+               {
+                       public TaskAssembly TaskAssembly { get; set; }
+                       public string Name { get; set; }
+                       public Type TaskFactoryType { get; set; }
+                       public Type TaskType { get; set; }
+                       public IDictionary<string, TaskPropertyInfo> TaskFactoryParameters { get; set; }
+                       public string TaskBody { get; set; }
+                       
+                       public bool IsMatch (string name)
+                       {
+                               int ridx = Name.LastIndexOf ('.');
+                               int tidx = name.IndexOf ('.');
+                               return string.Equals (Name, name, StringComparison.OrdinalIgnoreCase) ||
+                                       tidx < 0 && ridx > 0 && string.Equals (Name.Substring (ridx + 1), name, StringComparison.OrdinalIgnoreCase);
+                       }
+               }
+               
+               internal class TaskAssembly
+               {
+                       public string AssemblyName { get; set; }
+                       public string AssemblyFile { get; set; }
+                       public Assembly LoadedAssembly { get; set; }
+               }
+               
+               readonly List<TaskAssembly> assemblies = new List<TaskAssembly> ();
+               readonly List<TaskDescription> task_descs = new List<TaskDescription> ();
+
+               public List<TaskDescription> Tasks {
+                       get { return task_descs; }
+               }
+               
+               void LoadUsingTasks (ProjectInstance projectInstance, ProjectRootElement project)
+               {
+                       Func<string,bool> cond = s => projectInstance != null ? projectInstance.EvaluateCondition (s) : Convert.ToBoolean (s);
+                       foreach (var ut in project.UsingTasks) {
+                               var ta = assemblies.FirstOrDefault (a => a.AssemblyFile.Equals (ut.AssemblyFile, StringComparison.OrdinalIgnoreCase) || a.AssemblyName.Equals (ut.AssemblyName, StringComparison.OrdinalIgnoreCase));
+                               if (ta == null) {
+                                       ta = new TaskAssembly () { AssemblyName = ut.AssemblyName, AssemblyFile = ut.AssemblyFile };
+                                       ta.LoadedAssembly = ta.AssemblyName != null ? Assembly.Load (ta.AssemblyName) : Assembly.LoadFile (ta.AssemblyFile);
+                                       assemblies.Add (ta);
+                               }
+                               var pg = ut.ParameterGroup == null ? null : ut.ParameterGroup.Parameters.Select (p => new TaskPropertyInfo (p.Name, Type.GetType (p.ParameterType), cond (p.Output), cond (p.Required)))
+                                       .ToDictionary (p => p.Name);
+                               var task = new TaskDescription () {
+                                       TaskAssembly = ta,
+                                       Name = ut.TaskName,
+                                       TaskFactoryType = string.IsNullOrEmpty (ut.TaskFactory) ? null : LoadTypeFrom (ta.LoadedAssembly, ut.TaskName, ut.TaskFactory),
+                                       TaskType = string.IsNullOrEmpty (ut.TaskFactory) ? LoadTypeFrom (ta.LoadedAssembly, ut.TaskName, ut.TaskName) : null,
+                                       TaskFactoryParameters = pg,
+                                       TaskBody = ut.TaskBody != null && cond (ut.TaskBody.Condition) ? ut.TaskBody.Evaluate : null,
+                                       };
+                               task_descs.Add (task);
+                       }
+               }
+               
+               Type LoadTypeFrom (Assembly a, string taskName, string possiblyShortTypeName)
+               {
+                       Type type = a.GetType (possiblyShortTypeName, false, true);
+                       if (possiblyShortTypeName.IndexOf ('.') < 0)
+                               type = a.GetTypes ().FirstOrDefault (t => t.Name == possiblyShortTypeName);
+                       if (type == null)
+                               throw new InvalidOperationException (string.Format ("For task '{0}' Specified type '{1}' was not found in assembly '{2}'", taskName, possiblyShortTypeName, a.FullName));
+                       return type;
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildTaskFactory.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/BuildTaskFactory.cs
new file mode 100644 (file)
index 0000000..c587b35
--- /dev/null
@@ -0,0 +1,81 @@
+// BuildTaskFactory.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Threading;
+using System.Threading.Tasks;
+using System.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Internal;
+using System.Collections.Generic;
+using Microsoft.Build.Execution;
+
+namespace Microsoft.Build.Internal
+{
+       class BuildTaskFactory
+       {
+               public BuildTaskFactory (BuildTaskDatabase builtInDatabase, BuildTaskDatabase perProjectDatabase)
+               {
+                       this.built_in_database = builtInDatabase;
+                       this.per_project_database = perProjectDatabase;
+               }
+               
+               readonly BuildTaskDatabase built_in_database, per_project_database;
+               readonly List<ITaskFactory> task_factories = new List<ITaskFactory> ();
+               
+               public void ResetCaches ()
+               {
+                       task_factories.Clear ();
+               }
+               
+               public ITask CreateTask (string name, IDictionary<string,string> factoryIdentityParameters, IBuildEngine engine)
+               {
+                       Func<BuildTaskDatabase.TaskDescription,bool> fn = t => t.IsMatch (name);
+                       var td = per_project_database.Tasks.FirstOrDefault (fn) ?? built_in_database.Tasks.FirstOrDefault (fn);
+                       if (td == null)
+                               throw new InvalidOperationException (string.Format ("Task '{0}' could not be found", name));
+                       if (td.TaskFactoryType != null) {
+                               var tf = task_factories.FirstOrDefault (f => f.GetType () == td.TaskFactoryType);
+                               if (tf == null) {
+                                       tf = (ITaskFactory) Activator.CreateInstance (td.TaskFactoryType);
+#if NET_4_5
+                                       var tf2 = tf as ITaskFactory2;
+                                       if (tf2 != null)
+                                               tf2.Initialize (name, factoryIdentityParameters, td.TaskFactoryParameters, td.TaskBody, engine);
+                                       else
+#endif
+                                               tf.Initialize (name, td.TaskFactoryParameters, td.TaskBody, engine);
+                                       task_factories.Add (tf);
+                               }
+                               return tf.CreateTask (engine);
+                       }
+                       else
+                               return (ITask) Activator.CreateInstance (td.TaskType);
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionConstructs.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionConstructs.cs
new file mode 100644 (file)
index 0000000..358f58e
--- /dev/null
@@ -0,0 +1,197 @@
+//
+// ExpressionConstructs.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.Internal.Expressions
+{
+       
+       class Locatable
+       {
+               public ILocation Location { get; set; }         
+       }
+       
+       partial class ExpressionList : ILocation, IEnumerable<Expression>
+       {
+               public ExpressionList ()
+               {
+               }
+               
+               public ExpressionList (Expression entry)
+               {
+                       Add (entry);
+               }
+               
+               public int Count {
+                       get { return list.Count; }
+               }
+               
+               //public int Line {
+               //      get { return list.Count == 0 ? 0 : list [0].Line; }
+               //}
+               public int Column {
+                       get { return list.Count == 0 ? 0 : list [0].Column; }
+               }
+               public string File {
+                       get { return list.Count == 0 ? null : list [0].File; }
+               }
+               public string ToLocationString ()
+               {
+                       return list.Count == 0 ? null : list [0].Location.ToLocationString ();
+               }
+                       
+               public IEnumerator<Expression> GetEnumerator ()
+               {
+                       return list.GetEnumerator ();
+               }
+               
+               IEnumerator IEnumerable.GetEnumerator ()
+               {
+                       return list.GetEnumerator ();
+               }
+               
+               List<Expression> list = new List<Expression> ();
+               
+               public ExpressionList Add (Expression expr)
+               {
+                       list.Add (expr);
+                       return this;
+               }
+               
+               public ExpressionList Insert (int pos, Expression expr)
+               {
+                       list.Insert (pos, expr);
+                       return this;
+               }
+       }
+
+       abstract partial class Expression : Locatable, ILocation
+       {
+               //public int Line {
+               //      get { return Location.Line; }
+               //}
+               public int Column {
+                       get { return Location.Column; }
+               }
+               public string File {
+                       get { return Location.File; }
+               }
+               public string ToLocationString ()
+               {
+                       return Location.ToLocationString ();
+               }
+       }
+       
+       enum Operator
+       {
+               EQ,
+               NE,
+               LT,
+               LE,
+               GT,
+               GE,
+               And,
+               Or
+       }
+       
+       partial class BinaryExpression : Expression
+       {
+               public Operator Operator { get; set; }
+               public Expression Left { get; set; }
+               public Expression Right { get; set; }
+       }
+       
+       partial class BooleanLiteral : Expression
+       {
+               public bool Value { get; set; }
+       }
+
+       partial class NotExpression : Expression
+       {
+               public Expression Negated { get; set; }
+       }
+
+       partial class PropertyAccessExpression : Expression
+       {
+               public PropertyAccess Access { get; set; }
+       }
+       
+       enum PropertyTargetType
+       {
+               Object,
+               Type,
+       }
+       
+       class PropertyAccess : Locatable
+       {
+               public NameToken Name { get; set; }
+               public Expression Target { get; set; }
+               public PropertyTargetType TargetType { get; set; }
+               public ExpressionList Arguments { get; set; }
+       }
+
+       partial class ItemAccessExpression : Expression
+       {
+               public ItemApplication Application { get; set; }
+       }
+       
+       class ItemApplication : Locatable
+       {
+               public NameToken Name { get; set; }
+               public ExpressionList Expressions { get; set; }
+       }
+
+       partial class MetadataAccessExpression : Expression
+       {
+               public MetadataAccess Access { get; set; }
+       }
+       
+       class MetadataAccess : Locatable
+       {
+               public NameToken Metadata { get; set; }
+               public NameToken ItemType { get; set; }
+       }
+       
+       partial class StringLiteral : Expression
+       {
+               public NameToken Value { get; set; }
+       }
+
+       partial class RawStringLiteral : Expression
+       {
+               public NameToken Value { get; set; }
+       }
+       
+       partial class FunctionCallExpression : Expression
+       {
+               public NameToken Name { get; set; }
+               public ExpressionList Arguments { get; set; }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionEvaluator.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionEvaluator.cs
new file mode 100644 (file)
index 0000000..4aa9b25
--- /dev/null
@@ -0,0 +1,521 @@
+//
+// ExpressionEvaluator.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Linq;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Exceptions;
+using System.Collections.Generic;
+using System.Reflection;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Framework;
+using System.IO;
+
+namespace Microsoft.Build.Internal.Expressions
+{
+       class ExpressionEvaluator
+       {
+               public ExpressionEvaluator (Project project, string replacementForMissingPropertyAndItem)
+               {
+                       ReplacementForMissingPropertyAndItem = replacementForMissingPropertyAndItem;
+                       Project = project;
+                       /*
+                       GetItems = (name) => project.GetItems (name).Select (i => new KeyValuePair<string,string> (i.ItemType, i.EvaluatedInclude));
+                       GetProperty = (name) => {
+                               var prop = project.GetProperty (name);
+                               return new KeyValuePair<string,string> (prop != null ? prop.Name : null, prop != null ? prop.EvaluatedValue : null);
+                               };
+                       */
+               }
+               
+               public ExpressionEvaluator (ProjectInstance project, string replacementForMissingPropertyAndItem)
+               {
+                       ReplacementForMissingPropertyAndItem = replacementForMissingPropertyAndItem;
+                       ProjectInstance = project;
+                       /*
+                       GetItems = (name) => project.GetItems (name).Select (i => new KeyValuePair<string,string> (i.ItemType, i.EvaluatedInclude));
+                       GetProperty = (name) => {
+                               var prop = project.GetProperty (name);
+                               return new KeyValuePair<string,string> (prop != null ? prop.Name : null, prop != null ? prop.EvaluatedValue : null);
+                               };
+                       */
+               }
+               
+               EvaluationContext CreateContext (string source)
+               {
+                       return new EvaluationContext (source, this);
+               }
+               
+               public Project Project { get; private set; }
+               public ProjectInstance ProjectInstance { get; set; }
+               //public Func<string,IEnumerable<KeyValuePair<string,string>>> GetItems { get; private set; }
+               //public Func<string,KeyValuePair<string,string>> GetProperty { get; private set; }
+               
+               public string ReplacementForMissingPropertyAndItem { get; set; }
+               
+               // it is to prevent sequential property value expansion in boolean expression
+               public string Wrapper {
+                       get { return ReplacementForMissingPropertyAndItem != null ? "'" : null; }
+               }
+               
+               public string Evaluate (string source)
+               {
+                       return Evaluate (source, new ExpressionParserManual (source ?? string.Empty, ExpressionValidationType.LaxString).Parse ());
+               }
+               
+               string Evaluate (string source, ExpressionList exprList)
+               {
+                       if (exprList == null)
+                               throw new ArgumentNullException ("exprList");
+                       return string.Concat (exprList.Select (e => e.EvaluateAsString (CreateContext (source))));
+               }
+               
+               public bool EvaluateAsBoolean (string source)
+               {
+                       try {
+                               var el = new ExpressionParser ().Parse (source, ExpressionValidationType.StrictBoolean);
+                               if (el.Count () != 1)
+                                       throw new InvalidProjectFileException ("Unexpected number of tokens: " + el.Count ());
+                               return el.First ().EvaluateAsBoolean (CreateContext (source));
+                       } catch (yyParser.yyException ex) {
+                               throw new InvalidProjectFileException (string.Format ("failed to evaluate expression as boolean: '{0}': {1}", source, ex.Message), ex);
+                       }
+               }
+       }
+       
+       class EvaluationContext
+       {
+               public EvaluationContext (string source, ExpressionEvaluator evaluator)
+               {
+                       Source = source;
+                       Evaluator = evaluator;
+               }
+
+               public string Source { get; private set; }
+               
+               public ExpressionEvaluator Evaluator { get; private set; }
+               public object ContextItem { get; set; }
+               
+               Stack<object> evaluating_items = new Stack<object> ();
+               Stack<object> evaluating_props = new Stack<object> ();
+               
+               public IEnumerable<object> GetItems (string name)
+               {
+                       if (Evaluator.Project != null)
+                               return Evaluator.Project.GetItems (name);
+                       else
+                               return Evaluator.ProjectInstance.GetItems (name);
+               }
+
+               public IEnumerable<object> GetAllItems ()
+               {
+                       if (Evaluator.Project != null)
+                               return Evaluator.Project.AllEvaluatedItems;
+                       else
+                               return Evaluator.ProjectInstance.AllEvaluatedItems;
+               }
+               
+               public string EvaluateItem (string itemType, object item)
+               {
+                       if (evaluating_items.Contains (item))
+                               throw new InvalidProjectFileException (string.Format ("Recursive reference to item '{0}' was found", itemType));
+                       try {
+                               evaluating_items.Push (item);
+                               var eval = item as ProjectItem;
+                               if (eval != null)
+                                       return Evaluator.Evaluate (eval.EvaluatedInclude);
+                               else
+                                       return Evaluator.Evaluate (((ProjectItemInstance) item).EvaluatedInclude);
+                       } finally {
+                               evaluating_items.Pop ();
+                       }
+               }
+                               
+               public string EvaluateProperty (string name)
+               {
+                       if (Evaluator.Project != null) {
+                               var prop = Evaluator.Project.GetProperty (name);
+                               if (prop == null)
+                                       return null;
+                               return EvaluateProperty (prop, prop.Name, prop.EvaluatedValue);
+                       } else {
+                               var prop = Evaluator.ProjectInstance.GetProperty (name);
+                               if (prop == null)
+                                       return null;
+                               return EvaluateProperty (prop, prop.Name, prop.EvaluatedValue);
+                       }
+               }
+               
+               public string EvaluateProperty (object prop, string name, string value)
+               {
+                       if (evaluating_props.Contains (prop))
+                               throw new InvalidProjectFileException (string.Format ("Recursive reference to property '{0}' was found", name));
+                       try {
+                               evaluating_props.Push (prop);
+                               // FIXME: needs verification on whether string evaluation is appropriate or not.
+                               return Evaluator.Evaluate (value);
+                       } finally {
+                               evaluating_props.Pop ();
+                       }
+               }
+       }
+       
+       abstract partial class Expression
+       {
+               public abstract string EvaluateAsString (EvaluationContext context);
+               public abstract bool EvaluateAsBoolean (EvaluationContext context);
+               public abstract object EvaluateAsObject (EvaluationContext context);
+               
+               public bool EvaluateStringAsBoolean (EvaluationContext context, string ret)
+               {
+                       if (ret != null) {
+                               if (ret.Equals ("TRUE", StringComparison.InvariantCultureIgnoreCase))
+                                       return true;
+                               else if (ret.Equals ("FALSE", StringComparison.InvariantCultureIgnoreCase))
+                                       return false;
+                       }
+                       throw new InvalidProjectFileException (this.Location, string.Format ("Condition '{0}' is evaluated as '{1}' and cannot be converted to boolean", context.Source, ret));
+               }
+       }
+       
+       partial class BinaryExpression : Expression
+       {
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       switch (Operator) {
+                       case Operator.EQ:
+                               return string.Equals (Left.EvaluateAsString (context), Right.EvaluateAsString (context), StringComparison.OrdinalIgnoreCase);
+                       case Operator.NE:
+                               return !string.Equals (Left.EvaluateAsString (context), Right.EvaluateAsString (context), StringComparison.OrdinalIgnoreCase);
+                       case Operator.And:
+                       case Operator.Or:
+                               // evaluate first, to detect possible syntax error on right expr.
+                               var lb = Left.EvaluateAsBoolean (context);
+                               var rb = Right.EvaluateAsBoolean (context);
+                               return Operator == Operator.And ? (lb && rb) : (lb || rb);
+                       }
+                       // comparison expressions - evaluate comparable first, then compare values.
+                       var left = Left.EvaluateAsObject (context);
+                       var right = Right.EvaluateAsObject (context);
+                       if (!(left is IComparable && right is IComparable))
+                               throw new InvalidProjectFileException ("expression cannot be evaluated as boolean");
+                       var result = ((IComparable) left).CompareTo (right);
+                       switch (Operator) {
+                       case Operator.GE:
+                               return result >= 0;
+                       case Operator.GT:
+                               return result > 0;
+                       case Operator.LE:
+                               return result <= 0;
+                       case Operator.LT:
+                               return result < 0;
+                       }
+                       throw new InvalidOperationException ();
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               static readonly Dictionary<Operator,string> strings = new Dictionary<Operator, string> () {
+                       {Operator.EQ, " == "},
+                       {Operator.NE, " != "},
+                       {Operator.LT, " < "},
+                       {Operator.LE, " <= "},
+                       {Operator.GT, " > "},
+                       {Operator.GE, " >= "},
+                       {Operator.And, " And "},
+                       {Operator.Or, " Or "},
+               };
+               
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       return Left.EvaluateAsString (context) + strings [Operator] + Right.EvaluateAsString (context);
+               }
+       }
+       
+       partial class BooleanLiteral : Expression
+       {
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       return Value ? "True" : "False";
+               }
+               
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       return Value;
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       return Value;
+               }
+       }
+
+       partial class NotExpression : Expression
+       {
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       // no negation for string
+                       return "!" + Negated.EvaluateAsString (context);
+               }
+               
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       return !Negated.EvaluateAsBoolean (context);
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       return EvaluateAsString (context);
+               }
+       }
+
+       partial class PropertyAccessExpression : Expression
+       {
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       var ret = EvaluateAsString (context);
+                       return EvaluateStringAsBoolean (context, ret);
+               }
+               
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       var ret = EvaluateAsObject (context);
+                       // FIXME: this "wrapper" is kind of hack, to prevent sequential property references such as $(X)$(Y).
+                       return ret == null ? context.Evaluator.ReplacementForMissingPropertyAndItem : context.Evaluator.Wrapper + ret.ToString () + context.Evaluator.Wrapper;
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       try {
+                               return DoEvaluateAsObject (context);
+                       } catch (TargetInvocationException ex) {
+                               throw new InvalidProjectFileException ("Access to property caused an error", ex);
+                       }
+               }
+               
+               object DoEvaluateAsObject (EvaluationContext context)
+               {
+                       if (Access.Target == null) {
+                               return context.EvaluateProperty (Access.Name.Name);
+                       } else {
+                               if (this.Access.TargetType == PropertyTargetType.Object) {
+                                       var obj = Access.Target.EvaluateAsObject (context);
+                                       if (obj == null)
+                                               return null;
+                                       if (Access.Arguments != null) {
+                                               var args = Access.Arguments.Select (e => e.EvaluateAsObject (context)).ToArray ();
+                                               var method = FindMethod (obj.GetType (), Access.Name.Name, args);
+                                               if (method == null)
+                                                       throw new InvalidProjectFileException (Location, string.Format ("access to undefined method '{0}' of '{1}' at {2}", Access.Name.Name, Access.Target.EvaluateAsString (context), Location));
+                                               return method.Invoke (obj, AdjustArgsForCall (method, args));
+                                       } else {
+                                               var prop = obj.GetType ().GetProperty (Access.Name.Name);
+                                               if (prop == null)
+                                                       throw new InvalidProjectFileException (Location, string.Format ("access to undefined property '{0}' of '{1}' at {2}", Access.Name.Name, Access.Target.EvaluateAsString (context), Location));
+                                               return prop.GetValue (obj, null);
+                                       }
+                               } else {
+                                       var type = Type.GetType (Access.Target.EvaluateAsString (context));
+                                       if (type == null)
+                                               throw new InvalidProjectFileException (Location, string.Format ("specified type '{0}' was not found", Access.Target.EvaluateAsString (context)));
+                                       if (Access.Arguments != null) {
+                                               var args = Access.Arguments.Select (e => e.EvaluateAsObject (context)).ToArray ();
+                                               var method = FindMethod (type, Access.Name.Name, args);
+                                               if (method == null)
+                                                       throw new InvalidProjectFileException (Location, string.Format ("access to undefined static method '{0}' of '{1}' at {2}", Access.Name.Name, Access.Target.EvaluateAsString (context), Location));
+                                               return method.Invoke (null, AdjustArgsForCall (method, args));
+                                       } else {
+                                               var prop = type.GetProperty (Access.Name.Name);
+                                               if (prop == null)
+                                                       throw new InvalidProjectFileException (Location, string.Format ("access to undefined static property '{0}' of '{1}' at {2}", Access.Name.Name, Access.Target.EvaluateAsString (context), Location));
+                                               return prop.GetValue (null, null);
+                                       }
+                               }
+                       }
+               }
+       
+               MethodInfo FindMethod (Type type, string name, object [] args)
+               {
+                       var methods = type.GetMethods ().Where (m => {
+                               if (m.Name != name)
+                                       return false;
+                               var pl = m.GetParameters ();
+                               if (pl.Length == args.Length)
+                                       return true;
+                               // calling String.Format() with either set of arguments is valid:
+                               // - three strings (two for varargs)
+                               // - two strings (happen to be exact match)
+                               // - one string (no varargs)
+                               if (pl.Length > 0 && pl.Length - 1 <= args.Length &&
+                                   pl.Last ().GetCustomAttributesData ().Any (a => a.Constructor.DeclaringType == typeof (ParamArrayAttribute)))
+                                       return true;
+                               return false;
+                               });
+                       if (methods.Count () == 1)
+                               return methods.First ();
+                       return args.Any (a => a == null) ? 
+                               type.GetMethod (name) :
+                               type.GetMethod (name, args.Select (o => o.GetType ()).ToArray ());
+               }
+               
+               object [] AdjustArgsForCall (MethodInfo m, object[] args)
+               {
+                       if (m.GetParameters ().Length == args.Length + 1)
+                               return args.Concat (new object[] {Array.CreateInstance (m.GetParameters ().Last ().ParameterType.GetElementType (), 0)}).ToArray ();
+                       else
+                               return args;
+               }
+       }
+
+       partial class ItemAccessExpression : Expression
+       {
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       return EvaluateStringAsBoolean (context, EvaluateAsString (context));
+               }
+               
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       string itemType = Application.Name.Name;
+                       var items = context.GetItems (itemType);
+                       if (!items.Any ())
+                               return context.Evaluator.ReplacementForMissingPropertyAndItem;
+                       if (Application.Expressions == null)
+                               return string.Join (";", items.Select (item => context.EvaluateItem (itemType, item)));
+                       else
+                               return string.Join (";", items.Select (item => {
+                                       context.ContextItem = item;
+                                       var ret = string.Concat (Application.Expressions.Select (e => e.EvaluateAsString (context)));
+                                       context.ContextItem = null;
+                                       return ret;
+                                       }));
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       return EvaluateAsString (context);
+               }
+       }
+
+       partial class MetadataAccessExpression : Expression
+       {
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       return EvaluateStringAsBoolean (context, EvaluateAsString (context));
+               }
+               
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       string itemType = this.Access.ItemType != null ? this.Access.ItemType.Name : null;
+                       string metadataName = Access.Metadata.Name;
+                       IEnumerable<object> items;
+                       if (this.Access.ItemType != null)
+                               items = context.GetItems (itemType);
+                       else if (context.ContextItem != null)
+                               items = new Object [] { context.ContextItem };
+                       else
+                               items = context.GetAllItems ();
+                       
+                       var values = items.Select (i => (i is ProjectItem) ? ((ProjectItem) i).GetMetadataValue (metadataName) : ((ProjectItemInstance) i).GetMetadataValue (metadataName)).Where (s => !string.IsNullOrEmpty (s));
+                       return string.Join (";", values);
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       return EvaluateAsString (context);
+               }
+       }
+       partial class StringLiteral : Expression
+       {
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       var ret = EvaluateAsString (context);
+                       return EvaluateStringAsBoolean (context, ret);
+               }
+               
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       return context.Evaluator.Evaluate (this.Value.Name);
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       return EvaluateAsString (context);
+               }
+       }
+       partial class RawStringLiteral : Expression
+       {
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       return Value.Name;
+               }
+               
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       throw new InvalidProjectFileException ("raw string literal cannot be evaluated as boolean");
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       return EvaluateAsString (context);
+               }
+       }
+       
+       partial class FunctionCallExpression : Expression
+       {
+               public override string EvaluateAsString (EvaluationContext context)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+               public override bool EvaluateAsBoolean (EvaluationContext context)
+               {
+                       if (string.Equals (Name.Name, "Exists", StringComparison.OrdinalIgnoreCase)) {
+                               if (Arguments.Count != 1)
+                                       throw new InvalidProjectFileException (Location, "Function 'Exists' expects 1 argument");
+                               string val = Arguments.First ().EvaluateAsString (context);
+                               return Directory.Exists (val) || System.IO.File.Exists (val);
+                       }
+                       if (string.Equals (Name.Name, "HasTrailingSlash", StringComparison.OrdinalIgnoreCase)) {
+                               if (Arguments.Count != 1)
+                                       throw new InvalidProjectFileException (Location, "Function 'HasTrailingSlash' expects 1 argument");
+                               string val = Arguments.First ().EvaluateAsString (context);
+                               return val.LastOrDefault () == '\\' || val.LastOrDefault () == '/';
+                       }
+                       throw new InvalidProjectFileException (Location, string.Format ("Unsupported function '{0}'", Name));
+               }
+               
+               public override object EvaluateAsObject (EvaluationContext context)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParser.jay
new file mode 100644 (file)
index 0000000..200c96b
--- /dev/null
@@ -0,0 +1,264 @@
+//
+// ExpressionParser.jay
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Text;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Exceptions;
+using Microsoft.Build.Framework;
+
+/*
+
+Pseudo formal syntax for .NET 4.0 expression:
+
+Condition = Expression
+Include = Expression*
+
+ Expression
+       BooleanLiteral
+               TrueLiteral
+               FalseLiteral
+       BinaryExpression
+               Expression "==" Expression
+               Expression "!=" Expression
+               Expression ">" Expression
+               Expression ">=" Expression
+               Expression "<" Expression
+               Expression "<=" Expression
+               Expression "And" Expression
+               Expression "Or" Expression
+       UnaryExpression
+               "!" Expression
+       PropertyExpression
+               "$(" PropertyApplication ")"
+       ItemExpression
+               "@(" ItemApplication ")"
+       MetadataBatchingExpression
+               "%(" MetadataBatchingApplication ")"
+  StringLiteralOrFunction
+               StringLiteralOrFunctionName ( "(" FunctionArguments ")" )?
+
+.NET error messages are so detailed which is something like "you forgot '(' after '$' ?" - so
+it is likely that the MS tokenizer is hand-written.
+
+*/
+
+namespace Microsoft.Build.Internal.Expressions
+{
+       class ExpressionParser
+       {
+               static readonly int yacc_verbose_flag = Environment.GetEnvironmentVariable ("MONO_MSBUILD_PARSER_DEBUG") == "1" ? 1 : 0;
+
+               object debug_obj = yacc_verbose_flag == 0 ? null : new yydebug.yyDebugSimple ();
+               
+               public ExpressionList Parse (string source, ExpressionValidationType validationType)
+               {
+                       var tokenizer = new ExpressionTokenizer (source, validationType);
+                       return (ExpressionList) yyparse (tokenizer, debug_obj);
+               }
+               
+               BinaryExpression Binary (Operator op, object left, object right)
+               {
+                       return new BinaryExpression () { Operator = op, Left = (Expression) left, Right = (Expression) right, Location = (ILocation) left };
+               }
+%}
+
+%token TRUE_LITERAL
+%token FALSE_LITERAL
+%token STRING_LITERAL
+%token EQ // ==
+%token NE // !=
+%token GT // >
+%token GE // >=
+%token LT // <
+%token LE // <=
+%token AND // AND
+%token OR // OR
+%token NOT //!
+%token DOT //.
+%token COMMA //,
+%token PROP_OPEN // $(
+%token ITEM_OPEN // @(
+%token METADATA_OPEN // %(
+%token PAREN_OPEN // (
+%token PAREN_CLOSE // )
+%token BRACE_OPEN // [
+%token BRACE_CLOSE // ]
+%token COLON2 // ::
+%token ARROW // ->
+%token NAME
+%token ERROR
+
+%start ExpressionList
+
+%%
+
+ExpressionList
+       : /* empty */
+         { $$ = new ExpressionList (); }
+       | ExpressionList Expression
+         { $$ = ((ExpressionList) $1).Add ((Expression) $2); }
+       ;
+
+Expression
+       : LogicalExpression
+       ;
+
+LogicalExpression
+       : ComparisonExpression
+       | LogicalExpression AND LogicalExpression
+         { $$ = Binary (Operator.And, $1, $3); }
+       | LogicalExpression OR LogicalExpression
+         { $$ = Binary (Operator.Or, $1, $3); }
+       ;
+
+ComparisonExpression
+       : UnaryExpression
+       | UnaryExpression EQ UnaryExpression
+         { $$ = Binary (Operator.EQ, $1, $3); }
+       | UnaryExpression NE UnaryExpression
+         { $$ = Binary (Operator.NE, $1, $3); }
+       | UnaryExpression GT UnaryExpression
+         { $$ = Binary (Operator.GT, $1, $3); }
+       | UnaryExpression GE UnaryExpression
+         { $$ = Binary (Operator.GE, $1, $3); }
+       | UnaryExpression LT UnaryExpression
+         { $$ = Binary (Operator.LT, $1, $3); }
+       | UnaryExpression LE UnaryExpression
+         { $$ = Binary (Operator.LE, $1, $3); }
+       ;
+
+UnaryExpression
+       : PrimaryExpression
+       | NOT UnaryExpression
+         { $$ = new NotExpression () { Negated = (Expression) $2, Location = (ILocation) $1 }; }
+       ;
+
+PrimaryExpression
+       : BooleanLiteral
+       | StringLiteral
+       | UnaryExpression
+       | PropertyAccessExpression
+       | ItemAccessExpression
+       | MetadataAccessExpression
+       | RawStringLiteralOrFunction
+       | ParenthesizedExpression
+       ;
+       
+BooleanLiteral
+       : TRUE_LITERAL
+         { $$ = new BooleanLiteral () { Value = true, Location = (ILocation) $1 }; }
+       | FALSE_LITERAL
+         { $$ = new BooleanLiteral () { Value = false, Location = (ILocation) $1 }; }
+       ;
+
+PropertyAccessExpression
+       : PROP_OPEN PropertyAccess PAREN_CLOSE
+         { $$ = new PropertyAccessExpression () { Access = (PropertyAccess) $2, Location = (ILocation) $1 }; }
+       ;
+
+PropertyAccess
+       : NAME
+         { $$ = new PropertyAccess () { Name = (NameToken) $1, TargetType = PropertyTargetType.Object, Location = (NameToken) $1 }; }
+       | Expression DOT NAME
+         { $$ = new PropertyAccess () { Name = (NameToken) $3, Target = (Expression) $1, TargetType = PropertyTargetType.Object, Location = (ILocation) $1 }; }
+       | BRACE_OPEN QualifiedNameExpression BRACE_CLOSE COLON2 NAME
+         { $$ = new PropertyAccess () { Name = (NameToken) $5, Target = (Expression) $2, TargetType = PropertyTargetType.Type, Location = (ILocation) $1 }; }
+       | BRACE_OPEN QualifiedNameExpression BRACE_CLOSE COLON2 NAME PAREN_OPEN FunctionCallArguments PAREN_CLOSE
+         { $$ = new PropertyAccess () { Name = (NameToken) $5, Target = (Expression) $2, TargetType = PropertyTargetType.Type, Arguments = (ExpressionList) $7, Location = (ILocation) $1 }; }
+       ;
+
+QualifiedNameExpression
+       : QualifiedName
+         { $$ = new StringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
+       ;
+
+QualifiedName
+       : NAME
+       | QualifiedName DOT NAME
+         { $$ = new NameToken () { Name = ((NameToken) $1).Name + "." + ((NameToken) $3).Name, Column = ((ILocation) $1).Column }; }
+       ;
+
+ItemAccessExpression
+       : ITEM_OPEN ItemApplication PAREN_CLOSE
+         { $$ = new ItemAccessExpression () { Application = (ItemApplication) $2, Location = (ILocation) $1 }; }
+       ;
+
+// looking a bit messy, but gives different location
+ItemApplication
+       : NAME
+         { $$ = new ItemApplication () { Name = (NameToken) $1, Location = (ILocation) $1 }; }
+       | NAME ARROW ExpressionList
+         { $$ = new ItemApplication () { Name = (NameToken) $1, Expressions = (ExpressionList) $3, Location = (ILocation) $1 }; }
+       ;
+
+MetadataAccessExpression
+       : METADATA_OPEN MetadataAccess PAREN_CLOSE
+         { $$ = new MetadataAccessExpression () { Access = (MetadataAccess) $2, Location = (ILocation) $1 }; }
+       ;
+
+// looking a bit messy, but gives different location
+MetadataAccess
+       : NAME
+         { $$ = new MetadataAccess () { Metadata = (NameToken) $1, Location = (ILocation) $1 }; }
+       | NAME DOT NAME
+         { $$ = new MetadataAccess () { ItemType = (NameToken) $1, Metadata = (NameToken) $3, Location = (ILocation) $1 }; }
+       ;
+
+StringLiteral
+       : STRING_LITERAL
+         { $$ = new StringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
+       ;
+
+RawStringLiteralOrFunction
+       : NAME
+         { $$ = new RawStringLiteral () { Value = (NameToken) $1, Location = (ILocation) $1 }; }
+       | NAME PAREN_OPEN PAREN_CLOSE
+         { $$ = new FunctionCallExpression () { Name = (NameToken) $1, Arguments = new ExpressionList (), Location = (ILocation) $1 }; }
+       | NAME PAREN_OPEN FunctionCallArguments PAREN_CLOSE
+         { $$ = new FunctionCallExpression () { Name = (NameToken) $1, Arguments = (ExpressionList) $3, Location = (ILocation) $1 }; }
+       ;
+
+FunctionCallArguments
+       : /* empty */
+         { $$ = new ExpressionList (); }
+       | Expression
+         { $$ = new ExpressionList ().Add ((Expression) $1); }
+       | FunctionCallArguments COMMA Expression
+         { $$ = ((ExpressionList) $1).Add ((Expression) $3); }
+       ;
+
+ParenthesizedExpression
+       : PAREN_OPEN Expression PAREN_CLOSE
+         { $$ = (Expression) $2; }
+       ;
+
+%%
+
+       }
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionParserManual.cs
new file mode 100644 (file)
index 0000000..f177505
--- /dev/null
@@ -0,0 +1,271 @@
+//
+// ExpressionParserManual.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Exceptions;
+
+namespace Microsoft.Build.Internal.Expressions
+{
+       class ExpressionParserManual
+       {
+               // FIXME: we are going to not need ExpressionValidationType for this; always LaxString.
+               public ExpressionParserManual (string source, ExpressionValidationType validationType)
+               {
+                       if (source == null)
+                               throw new ArgumentNullException ("source");
+                       this.source = source;
+                       validation_type = validationType;
+               }
+               
+               string source;
+               ExpressionValidationType validation_type;
+               
+               public ExpressionList Parse ()
+               {
+                       return Parse (0, source.Length);
+               }
+               
+               ExpressionList Parse (int start, int end)
+               {
+                       if (string.IsNullOrWhiteSpace (source))
+                               return new ExpressionList ();
+
+                       var ret = new ExpressionList ();
+                       while (start < end) {
+                               int bak = start;
+                               ret.Add (ParseSingle (ref start, end));
+                               SkipSpaces (ref start);
+                               if (bak == start)
+                                       throw new Exception ("Parser failed to progress token position: " + source);
+                       }
+                       return ret;
+               }
+               
+               static readonly char [] token_starters = "$@%(),".ToCharArray ();
+               
+               Expression ParseSingle (ref int start, int end)
+               {
+                       char token = source [start];
+                       switch (token) {
+                       case '$':
+                       case '@':
+                       case '%':
+                               if (start == end || start + 1 == source.Length || source [start + 1] != '(') {
+                                       if (validation_type == ExpressionValidationType.StrictBoolean)
+                                               throw new InvalidProjectFileException (string.Format ("missing '(' after '{0}' at {1} in \"{2}\"", source [start], start, source));
+                                       else
+                                               goto default; // treat as raw literal to the section end
+                               }
+                               start += 2;
+                               int last = FindMatchingCloseParen (start, end);
+                               if (last < 0) {
+                                       if (validation_type == ExpressionValidationType.StrictBoolean)
+                                               throw new InvalidProjectFileException (string.Format ("expression did not have matching ')' since index {0} in \"{1}\"", start, source));
+                                       else {
+                                               start -= 2;
+                                               goto default; // treat as raw literal to the section end
+                                       }
+                               }
+                               Expression ret;
+                               if (token == '$')
+                                       ret = EvaluatePropertyExpression (start, last);
+                               else if (token == '%')
+                                       ret = EvaluateMetadataExpression (start, last);
+                               else
+                                       ret = EvaluateItemExpression (start, last);
+                               start = last + 1;
+                               return ret;
+                               
+                       // Below (until default) are important only for Condition evaluation
+                       case '(':
+                               if (validation_type == ExpressionValidationType.LaxString)
+                                       goto default;
+                               start++;
+                               last = FindMatchingCloseParen (start, end);
+                               if (last < 0) {
+                                       if (validation_type == ExpressionValidationType.StrictBoolean)
+                                               throw new InvalidProjectFileException (string.Format ("expression did not have matching ')' since index {0} in \"{1}\"", start, source));
+                                       else {
+                                               start--;
+                                               goto default; // treat as raw literal to the section end
+                                       }
+                               }
+                               var contents = Parse (start, last).ToArray ();
+                               if (contents.Length > 1)
+                                       throw new InvalidProjectFileException (string.Format ("unexpected continuous expression within (){0} in \"{1}\"", contents [1].Column > 0 ? " at " + contents [1].Column : null, source));
+                               return contents.First ();
+
+                       default:
+                               int idx = source.IndexOfAny (token_starters, start + 1);
+                               string name = idx < 0 ? source.Substring (start, end - start) : source.Substring (start, idx - start);
+                               var val = new NameToken () { Name = name };
+                               ret = new RawStringLiteral () { Value = val };
+                               if (idx >= 0)
+                                       start = idx;
+                               else
+                                       start = end;
+
+                               return ret;
+                       }
+               }
+               
+               int FindMatchingCloseParen (int start, int end)
+               {
+                       int n = 0;
+                       for (int i = start; i < end; i++) {
+                               if (source [i] == '(')
+                                       n++;
+                               else if (source [i] == ')') {
+                                       if (n-- == 0)
+                                               return i;
+                               }
+                       }
+                       return -1; // invalid
+               }
+               
+               static readonly string spaces = " \t\r\n";
+               
+               void SkipSpaces (ref int start)
+               {
+                       while (start < source.Length && spaces.Contains (source [start]))
+                               start++;
+               }
+               
+               PropertyAccessExpression EvaluatePropertyExpression (int start, int end)
+               {
+                       // member access
+                       int dotAt = source.LastIndexOf ('.', end, end - start);
+                       int colonsAt = source.LastIndexOf ("::", end, end - start, StringComparison.Ordinal);
+                       if (dotAt < 0 && colonsAt < 0) {
+                               // property access without member specification
+                               int parenAt = source.IndexOf ('(', start, end - start);
+                               string name = parenAt < 0 ? source.Substring (start, end - start) : source.Substring (start, parenAt - start);
+                               var access = new PropertyAccess () {
+                                       Name = new NameToken () { Name = name },
+                                       TargetType = PropertyTargetType.Object
+                                       };
+                               if (parenAt > 0) { // method arguments
+                                       start = parenAt + 1;
+                                       access.Arguments = ParseFunctionArguments (ref start, end);
+                               }
+                               return new PropertyAccessExpression () { Access = access };
+                       }
+                       if (colonsAt < 0 || colonsAt < dotAt) {
+                               // property access with member specification
+                               int mstart = dotAt + 1;
+                               int parenAt = source.IndexOf ('(', mstart, end - mstart);
+                               string name = parenAt < 0 ? source.Substring (mstart, end - mstart) : source.Substring (mstart, parenAt - mstart);
+                               var access = new PropertyAccess () {
+                                       Name = new NameToken () { Name = name },
+                                       TargetType = PropertyTargetType.Object,
+                                       Target = dotAt < 0 ? null : Parse (start, dotAt).FirstOrDefault () 
+                               };
+                               if (parenAt > 0) { // method arguments
+                                       start = parenAt + 1;
+                                       access.Arguments = ParseFunctionArguments (ref start, end);
+                               }
+                               return new PropertyAccessExpression () { Access = access };
+                       } else {
+                               // static type access
+                               string type = source.Substring (start, colonsAt - start);
+                               if (type.Length < 2 || type [0] != '[' || type [type.Length - 1] != ']')
+                                       throw new InvalidProjectFileException (string.Format ("Static function call misses appropriate type name surrounded by '[' and ']' at {0} in \"{1}\"", start, source));
+                               type = type.Substring (1, type.Length - 2);
+                               start = colonsAt + 2;
+                               int parenAt = source.IndexOf ('(', start, end - start);
+                               string member = parenAt < 0 ? source.Substring (start, end - start) : source.Substring (start, parenAt - start);
+                               if (member.Length == 0)
+                                       throw new InvalidProjectFileException ("Static member name is missing");
+                               var access = new PropertyAccess () {
+                                       Name = new NameToken () { Name = member },
+                                       TargetType = PropertyTargetType.Type,
+                                       Target = new StringLiteral () { Value = new NameToken () { Name = type } }
+                               };
+                               if (parenAt > 0) { // method arguments
+                                       start = parenAt + 1;
+                                       access.Arguments = ParseFunctionArguments (ref start, end);
+                               }
+                               return new PropertyAccessExpression () { Access = access };
+                       }
+               }
+               
+               ExpressionList ParseFunctionArguments (ref int start, int end)
+               {
+                       var args = new ExpressionList ();
+                       do {
+                               SkipSpaces (ref start);
+                               if (start == source.Length)
+                                       throw new InvalidProjectFileException ("unterminated function call arguments.");
+                               if (source [start] == ')')
+                                       break;
+                               else if (args.Any ()) {
+                                       if (source [start] != ',')
+                                               throw new InvalidProjectFileException (string.Format ("invalid function call arguments specification. ',' is expected, got '{0}'", source [start]));
+                                       start++;
+                               }
+                               args.Add (ParseSingle (ref start, end));
+                       } while (true);
+                       start++;
+                       return args;
+               }
+               
+               ItemAccessExpression EvaluateItemExpression (int start, int end)
+               {
+                       // using property as context and evaluate
+                       int idx = source.IndexOf ("->", start, StringComparison.Ordinal);
+                       if (idx > 0) {
+                               string name = source.Substring (start, idx - start);
+                               return new ItemAccessExpression () {
+                                       Application = new ItemApplication () {
+                                               Name = new NameToken () { Name = name },
+                                               Expressions = Parse (idx, end - idx)
+                                               }
+                                       };
+                       } else {
+                               string name = source.Substring (start, end - start);
+                               return new ItemAccessExpression () {
+                                       Application = new ItemApplication () { Name = new NameToken () { Name = name } }
+                                       };
+                       }
+               }
+               
+               MetadataAccessExpression EvaluateMetadataExpression (int start, int end)
+               {
+                       int idx = source.IndexOf ('.', start, end - start);
+                       string item = idx < 0 ? null : source.Substring (start, idx);
+                       string meta = idx < 0 ? source.Substring (start, end - start) : source.Substring (idx + 1, end - idx - 1);
+                       var access = new MetadataAccess () {
+                                       ItemType = item == null ? null : new NameToken () { Column = start, Name = item },
+                                       Metadata = new NameToken () { Column = idx < 0 ? start : idx + 1, Name = meta }
+                                       };
+                       return new MetadataAccessExpression () { Access = access };
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ExpressionTokenizer.cs
new file mode 100644 (file)
index 0000000..9760ad2
--- /dev/null
@@ -0,0 +1,309 @@
+//
+// ExpressionTokenizer.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Collections.Generic;
+using Microsoft.Build.Evaluation;
+
+namespace Microsoft.Build.Internal.Expressions
+{
+       enum ExpressionValidationType
+       {
+               LaxString,
+               StrictBoolean,
+       }
+       
+       enum TokenizerMode
+       {
+               Default,
+               InsideItemOrProperty,
+       }
+       
+       class ExpressionTokenizer : yyParser.yyInput
+       {
+               public ExpressionTokenizer (string source, ExpressionValidationType validationType)
+               {
+                       this.source = source;
+                       current_token_position = -1;
+                       validation_type = validationType;
+                       modes.Push (TokenizerMode.Default);
+               }
+               
+               string source;
+               ExpressionValidationType validation_type;
+               
+               int current_token;
+               string error;
+               int pos, current_token_position;
+               object token_value;
+               Stack<TokenizerMode> modes = new Stack<TokenizerMode> ();
+
+               TokenizerMode CurrentTokenizerMode {
+                       get { return modes.Peek (); }
+               }
+
+               public bool advance ()
+               {
+                       if (pos == source.Length)
+                               return false;
+
+                       error = null;
+                       token_value = null;
+
+                       while (pos < source.Length) {
+                               if (spaces.IndexOf (source [pos]) >= 0)
+                                       pos++;
+                               else
+                                       break;
+                       }
+                       if (pos == source.Length)
+                               return false;
+                       current_token_position = pos;
+
+                       switch (source [pos++]) {
+                       case '.':
+                               TokenForItemPropertyValue (".", Token.DOT);
+                               break;
+                       case ',':
+                               TokenForItemPropertyValue (",", Token.COMMA);
+                               break;
+                       case '[':
+                               TokenForItemPropertyValue ("[", Token.BRACE_OPEN);
+                               break;
+                       case ']':
+                               TokenForItemPropertyValue ("]", Token.BRACE_CLOSE);
+                               break;
+                       case '(':
+                               modes.Push (TokenizerMode.Default);
+                               TokenForItemPropertyValue ("(", Token.PAREN_OPEN);
+                               break;
+                       case ')':
+                               if (modes.Count > 0) {
+                                       modes.Pop ();
+                                       current_token = Token.PAREN_CLOSE;
+                               } else {
+                                       token_value = ")";
+                                       current_token = Token.NAME;
+                               }
+                               break;
+                       case '-':
+                               if (pos < source.Length && source [pos] == '>') {
+                                       current_token = Token.ARROW;
+                                       pos++;
+                               } else
+                                       ErrorOnStrictBoolean ("-", "'-' is not followed by '>'.");
+                               break;
+                       case '=':
+                               if (pos < source.Length && source [pos] == '=') {
+                                       current_token = Token.EQ;
+                                       pos++;
+                               } else
+                                       ErrorOnStrictBoolean ("=", "'=' is not followed by '='.");
+                               break;
+                       case ':':
+                               if (pos < source.Length && source [pos] == ':') {
+                                       current_token = Token.COLON2;
+                               } else
+                                       ErrorOnStrictBoolean (":", "':' is not followed by ':'.");
+                               pos++;
+                               break;
+                       case '!':
+                               if (pos < source.Length && source [pos] == '=') {
+                                       pos++;
+                                       current_token = Token.NE;
+                               } else
+                                       TokenForItemPropertyValue ("!", Token.NOT);
+                               break;
+                       case '>':
+                               if (pos < source.Length && source [pos] == '=') {
+                                       pos++;
+                                       current_token = Token.GE;
+                               } else
+                                       current_token = Token.GT;
+                               break;
+                       case '<':
+                               if (pos < source.Length && source [pos] == '=') {
+                                       pos++;
+                                       current_token = Token.LE;
+                               } else
+                                       current_token = Token.LT;
+                               break;
+                       case '$':
+                               if (pos < source.Length && source [pos] == '(') {
+                                       modes.Push (TokenizerMode.InsideItemOrProperty);
+                                       current_token = Token.PROP_OPEN;
+                                       pos++;
+                               } else
+                                       ErrorOnStrictBoolean ("$", "property reference '$' is not followed by '('.");
+                               break;
+                       case '@':
+                               if (pos < source.Length && source [pos] == '(') {
+                                       modes.Push (TokenizerMode.InsideItemOrProperty);
+                                       current_token = Token.ITEM_OPEN;
+                                       pos++;
+                               } else
+                                       ErrorOnStrictBoolean ("@", "item reference '@' is not followed by '('.");
+                               break;
+                       case '%':
+                               if (pos < source.Length && source [pos] == '(') {
+                                       modes.Push (TokenizerMode.InsideItemOrProperty);
+                                       current_token = Token.METADATA_OPEN;
+                                       pos++;
+                               } else
+                                       ErrorOnStrictBoolean ("%", "metadata reference '%' is not followed by '('.");
+                               break;
+                       case '"':
+                       case '\'':
+                               pos = source.IndexOf (source [pos - 1], pos);
+                               if (pos < 0) {
+                                       ErrorOnStrictBoolean ("'", "unterminated string literal");
+                                       pos = source.Length;
+                               }
+                               token_value = source.Substring (current_token_position + 1, pos - current_token_position - 1);
+                               current_token = Token.STRING_LITERAL;
+                               pos++;
+                               break;
+                       default:
+                               pos = source.IndexOfAny (token_starter_chars, pos);
+                               if (pos < 0)
+                                       pos = source.Length;
+                               var val = source.Substring (current_token_position, pos - current_token_position);
+                               if (val.Equals ("AND", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.AND;
+                               else if (val.Equals ("OR", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.OR;
+                               else if (val.Equals ("TRUE", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.TRUE_LITERAL;
+                               else if (val.Equals ("FALSE", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.FALSE_LITERAL;
+                               else if (val.Equals ("YES", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.TRUE_LITERAL;
+                               else if (val.Equals ("NO", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.FALSE_LITERAL;
+                               else if (val.Equals ("ON", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.TRUE_LITERAL;
+                               else if (val.Equals ("OFF", StringComparison.OrdinalIgnoreCase))
+                                       current_token = Token.FALSE_LITERAL;
+                               else {
+                                       current_token = Token.NAME;
+                                       token_value = ProjectCollection.Unescape (val);
+                                       break;
+                               }
+                               break;
+                       }
+                       return true;
+               }
+               string spaces = " \t\r\n";
+
+               static readonly char [] token_starter_chars = ".,[]()-=:!><$@%\"' ".ToCharArray ();
+               
+               void ReadStringLiteral (string source, char c)
+               {
+                       while (pos < source.Length && source [pos] != c)
+                               pos++;
+                       if (source [pos - 1] != c)
+                               ErrorOnStrictBoolean (c.ToString (), string.Format ("missing string literal terminator [{0}]", c));
+                       else {
+                               current_token = Token.NAME;
+                               token_value = source.Substring (current_token_position + 1, pos - current_token_position - 2);
+                               token_value = ProjectCollection.Unescape ((string) token_value);
+                       }
+               }
+               
+               void TokenForItemPropertyValue (string value, int token)
+               {
+                       if (true)//CurrentTokenizerMode == TokenizerMode.InsideItemOrProperty)
+                               current_token = token;
+                       else {
+                               current_token = Token.NAME;
+                               token_value = value;
+                       }
+               }
+               
+               void ErrorOnStrictBoolean (string value, string message)
+               {
+                       if (validation_type == ExpressionValidationType.StrictBoolean) {
+                               current_token = Token.ERROR;
+                               error = message;
+                       } else {
+                               current_token = Token.NAME;
+                               token_value = value;
+                       }
+               }
+               
+               public int token ()
+               {
+                       return current_token;
+               }
+               
+               public object value ()
+               {
+                       if (current_token == Token.NAME || current_token == Token.STRING_LITERAL)
+                               return new NameToken () { Name = (string) token_value, Column = current_token_position };
+                       else if (error != null)
+                               return new ErrorToken () { Message = error, Column = current_token_position };
+                       else
+                               return new Location () { Column = current_token_position };
+               }
+       }       
+
+       class NameToken : Location
+       {
+               public string Name { get; set; }
+               
+               public override string ToString ()
+               {
+                       return string.Format ("[NameToken: Value={0}]", Name);
+               }
+       }
+
+       class ErrorToken : Location
+       {
+               public string Message { get; set; }
+       }
+
+       interface ILocation
+       {
+               //int Line { get; }
+               int Column { get; }
+               string File { get; }
+               
+               string ToLocationString ();
+       }
+
+       class Location : ILocation
+       {
+               //public int Line { get; set; }
+               public int Column { get; set; }
+               public string File { get; set; }
+               
+               public string ToLocationString ()
+               {
+                       return "at " + Column;
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ProjectTaskItem.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/ProjectTaskItem.cs
new file mode 100644 (file)
index 0000000..98d4bb2
--- /dev/null
@@ -0,0 +1,92 @@
+//
+// ProjectTaskItem.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using System.IO;
+
+namespace Microsoft.Build.Internal
+{
+       class ProjectTaskItem : ITaskItem
+       {
+               ProjectItemElement item;
+               string evaluated_include_part;
+               
+               public ProjectTaskItem (ProjectItemElement item, string evaluatedIncludePart)
+               {
+                       this.item = item;
+                       this.evaluated_include_part = WindowsCompatibilityExtensions.NormalizeFilePath (evaluatedIncludePart);
+               }
+               #region ITaskItem implementation
+               System.Collections.IDictionary ITaskItem.CloneCustomMetadata ()
+               {
+                       var ret = new System.Collections.Hashtable ();
+                       foreach (var p in item.Metadata)
+                               ret [p.Name] = p;
+                       return ret;
+               }
+               void ITaskItem.CopyMetadataTo (ITaskItem destinationItem)
+               {
+                       throw new NotImplementedException ();
+               }
+               string ITaskItem.GetMetadata (string metadataName)
+               {
+                       var wk = ProjectCollection.GetWellKnownMetadata (metadataName, evaluated_include_part, Path.GetFullPath, null);
+                       if (wk != null)
+                               return wk;
+                       var mde = item.Metadata.FirstOrDefault (m => m.Name == metadataName);
+                       return mde != null ? mde.Value : null;
+               }
+               void ITaskItem.RemoveMetadata (string metadataName)
+               {
+                       throw new NotImplementedException ();
+               }
+               void ITaskItem.SetMetadata (string metadataName, string metadataValue)
+               {
+                       throw new NotImplementedException ();
+               }
+               string ITaskItem.ItemSpec {
+                       get { return evaluated_include_part; }
+                       set { throw new NotImplementedException (); }
+               }
+               int ITaskItem.MetadataCount {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+               System.Collections.ICollection ITaskItem.MetadataNames {
+                       get {
+                               throw new NotImplementedException ();
+                       }
+               }
+               #endregion
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Internal/WindowsCompatibilityExtensions.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Internal/WindowsCompatibilityExtensions.cs
new file mode 100644 (file)
index 0000000..38f9d6b
--- /dev/null
@@ -0,0 +1,41 @@
+//
+// WindowsCompatibilityExtensions.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// (C) 2013 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.IO;
+
+namespace Microsoft.Build.Internal
+{
+       static class WindowsCompatibilityExtensions
+       {
+               public static string NormalizeFilePath (string path)
+               {
+                       return path.Replace ('\\', Path.DirectorySeparatorChar);
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Logging/ConfigurableForwardingLogger.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Logging/ConfigurableForwardingLogger.cs
new file mode 100644 (file)
index 0000000..077a1bb
--- /dev/null
@@ -0,0 +1,43 @@
+using System;
+using Microsoft.Build.Framework;
+
+namespace Microsoft.Build.Logging
+{
+       public class ConfigurableForwardingLogger : IForwardingLogger
+       {
+               #region INodeLogger implementation
+
+               public void Initialize (IEventSource eventSource, int nodeCount)
+               {
+                       Initialize (eventSource);
+               }
+
+               #endregion
+
+               #region ILogger implementation
+
+               public void Initialize (IEventSource eventSource)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void Shutdown ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public string Parameters { get; set; }
+
+               public LoggerVerbosity Verbosity { get; set; }
+
+               #endregion
+
+               #region IForwardingLogger implementation
+
+               public IEventRedirector BuildEventRedirector { get; set; }
+
+               public int NodeId { get; set; }
+
+               #endregion
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Microsoft.Build.Logging/DistributedFileLogger.cs b/mcs/class/Microsoft.Build/Microsoft.Build.Logging/DistributedFileLogger.cs
new file mode 100644 (file)
index 0000000..04c41f3
--- /dev/null
@@ -0,0 +1,44 @@
+using System;
+using Microsoft.Build.Framework;
+
+namespace Microsoft.Build.Logging
+{
+       public class DistributedFileLogger : IForwardingLogger
+       {
+               #region INodeLogger implementation
+
+               public void Initialize (IEventSource eventSource, int nodeCount)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               #endregion
+
+               #region ILogger implementation
+
+               public void Initialize (IEventSource eventSource)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void Shutdown ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public string Parameters { get; set; }
+
+               public LoggerVerbosity Verbosity { get; set; }
+
+               #endregion
+
+               #region IForwardingLogger implementation
+
+               public IEventRedirector BuildEventRedirector { get; set; }
+
+               public int NodeId { get; set; }
+
+               #endregion
+       }
+}
+
index 5115402c677cf439bf0b275c383a24e84f8d3f46..4e7b72f1a7b6fa01e9ed69996efbd4814d853a90 100644 (file)
 //
 
 using System;
+using System.Reflection;
 using Microsoft.Build.Framework;
 
 namespace Microsoft.Build.Logging
 {
-        public class LoggerDescription
-        {
-                public LoggerDescription (string loggerClassName, string loggerAssemblyName,
-                        string loggerAssemblyFile, string loggerSwitchParameters,
-                        LoggerVerbosity verbosity)
-                {
-                        throw new NotImplementedException ();
-                }
-        }
+       public class LoggerDescription
+       {
+               public LoggerDescription (string loggerClassName, string loggerAssemblyName,
+                               string loggerAssemblyFile, string loggerSwitchParameters,
+                               LoggerVerbosity verbosity)
+               {
+                       if (loggerAssemblyName != null && loggerAssemblyFile != null)
+                               throw new InvalidOperationException ("Cannot specify both loggerAssemblyName and loggerAssemblyFile at the same time.");
+                       if (loggerAssemblyName == null && loggerAssemblyFile == null)
+                               throw new InvalidOperationException ("Either loggerAssemblyName or loggerAssemblyFile must be specified");
+                       class_name = loggerClassName;
+                       assembly_name = loggerAssemblyName;
+                       assembly_file = loggerAssemblyFile;
+                       LoggerSwitchParameters = loggerSwitchParameters;
+                       Verbosity = verbosity;
+               }
+
+               string class_name, assembly_name, assembly_file;
+
+               public string LoggerSwitchParameters { get; private set; }
+               public LoggerVerbosity Verbosity { get; private set; }
+
+               public ILogger CreateLogger ()
+               {
+                       var assembly = assembly_name != null ? AppDomain.CurrentDomain.Load (assembly_name) : Assembly.LoadFile (assembly_file);
+                       var type = assembly.GetType (class_name);
+                       return (ILogger) Activator.CreateInstance (type, Verbosity);
+               }
+       }
 }
 
index 37c1f480c114eb92ab2790afa5186b02b5970525..56d864cac2761cf02364bf1cfe587b13bafe56fa 100644 (file)
@@ -1,6 +1,18 @@
 Assembly/AssemblyInfo.cs
 ../../build/common/Consts.cs
 ../../build/common/MonoTODOAttribute.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/DirectoryScanner.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/EventSource.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ColorSetter.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ColorResetter.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/ConsoleLogger.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/FileLogger.cs
+../Microsoft.Build.Engine/Microsoft.Build.BuildEngine/WriteHandler.cs
+../Microsoft.Build.Utilities/Mono.XBuild.Utilities/MSBuildUtils.cs
+../Microsoft.Build.Utilities/Mono.XBuild.Utilities/ReservedNameUtils.cs
+../Microsoft.Build.Utilities/Microsoft.Build.Utilities/TaskItem.cs
+../Microsoft.Build.Utilities/Microsoft.Build.Utilities/ToolLocationHelper.cs
+../Microsoft.Build.Utilities/Microsoft.Build.Utilities/TargetDotNetFrameworkVersion.cs
 Microsoft.Build.Construction/ElementLocation.cs
 Microsoft.Build.Construction/ProjectChooseElement.cs
 Microsoft.Build.Construction/ProjectCommentElement.cs
@@ -28,16 +40,24 @@ Microsoft.Build.Construction/ProjectUsingTaskParameterElement.cs
 Microsoft.Build.Construction/ProjectWhenElement.cs
 Microsoft.Build.Construction/UsingTaskParameterGroupElement.cs
 Microsoft.Build.Evaluation/Project.cs
+Microsoft.Build.Evaluation/ProjectChangedEventArgs.cs
 Microsoft.Build.Evaluation/ProjectCollection.cs
+Microsoft.Build.Evaluation/ProjectCollectionChangedEventArgs.cs
+Microsoft.Build.Evaluation/ProjectCollectionChangedState.cs
 Microsoft.Build.Evaluation/ProjectItem.cs
 Microsoft.Build.Evaluation/ProjectItemDefinition.cs
 Microsoft.Build.Evaluation/ProjectLoadSettings.cs 
 Microsoft.Build.Evaluation/ProjectMetadata.cs
 Microsoft.Build.Evaluation/ProjectProperty.cs
+Microsoft.Build.Evaluation/ProjectXmlChangedEventArgs.cs
 Microsoft.Build.Evaluation/ResolvedImport.cs
+Microsoft.Build.Evaluation/SubToolset.cs
 Microsoft.Build.Evaluation/Toolset.cs
 Microsoft.Build.Evaluation/ToolsetDefinitionLocations.cs
+Microsoft.Build.Exceptions/BuildAbortedException.cs
+Microsoft.Build.Exceptions/InternalLoggerException.cs
 Microsoft.Build.Exceptions/InvalidProjectFileException.cs
+Microsoft.Build.Exceptions/InvalidToolsetDefinitionException.cs
 Microsoft.Build.Execution/BuildManager.cs
 Microsoft.Build.Execution/BuildParameters.cs
 Microsoft.Build.Execution/BuildRequestData.cs
@@ -45,24 +65,44 @@ Microsoft.Build.Execution/BuildRequestDataFlags.cs
 Microsoft.Build.Execution/BuildResult.cs
 Microsoft.Build.Execution/BuildResultCode.cs 
 Microsoft.Build.Execution/BuildSubmission.cs
+Microsoft.Build.Execution/BuildSubmissionCompleteCallback.cs
 Microsoft.Build.Execution/HostServices.cs
 Microsoft.Build.Execution/ITargetResult.cs
 Microsoft.Build.Execution/NodeAffinity.cs
+Microsoft.Build.Execution/NodeEngineShutdownReason.cs
+Microsoft.Build.Execution/OutOfProcNode.cs
 Microsoft.Build.Execution/ProjectInstance.cs
 Microsoft.Build.Execution/ProjectItemDefinitionInstance.cs
+Microsoft.Build.Execution/ProjectItemGroupTaskInstance.cs
+Microsoft.Build.Execution/ProjectItemGroupTaskItemInstance.cs
+Microsoft.Build.Execution/ProjectItemGroupTaskMetadataInstance.cs
 Microsoft.Build.Execution/ProjectItemInstance.cs
 Microsoft.Build.Execution/ProjectMetadataInstance.cs
+Microsoft.Build.Execution/ProjectOnErrorInstance.cs
+Microsoft.Build.Execution/ProjectPropertyGroupTaskInstance.cs
+Microsoft.Build.Execution/ProjectPropertyGroupTaskPropertyInstance.cs
 Microsoft.Build.Execution/ProjectPropertyInstance.cs
 Microsoft.Build.Execution/ProjectTargetInstance.cs
+Microsoft.Build.Execution/ProjectTaskInstance.cs
+Microsoft.Build.Execution/ProjectTaskInstanceChild.cs
+Microsoft.Build.Execution/ProjectTaskOutputItemInstance.cs
+Microsoft.Build.Execution/ProjectTaskOutputPropertyInstance.cs
+Microsoft.Build.Execution/ProjectTargetInstanceChild.cs
 Microsoft.Build.Execution/TargetResult.cs                           
 Microsoft.Build.Execution/TargetResultCode.cs
+Microsoft.Build.Internal/BuildEngine4.cs
+Microsoft.Build.Internal/BuildNodeManager.cs
+Microsoft.Build.Internal/BuildTaskDatabase.cs
+Microsoft.Build.Internal/BuildTaskFactory.cs
 Microsoft.Build.Internal/CollectionFromEnumerable.cs
+Microsoft.Build.Internal/ExpressionConstructs.cs
+Microsoft.Build.Internal/ExpressionEvaluator.cs
+Microsoft.Build.Internal/ExpressionParserManual.cs
+Microsoft.Build.Internal/ExpressionTokenizer.cs
 Microsoft.Build.Internal/FilteredEnumerable.cs
+Microsoft.Build.Internal/ProjectTaskItem.cs
 Microsoft.Build.Internal/ReverseEnumerable.cs
-Microsoft.Build.Logging/ColorResetter.cs
-Microsoft.Build.Logging/ColorSetter.cs
-Microsoft.Build.Logging/ConsoleLogger.cs
-Microsoft.Build.Logging/FileLogger.cs
+Microsoft.Build.Internal/WindowsCompatibilityExtensions.cs
+Microsoft.Build.Logging/ConfigurableForwardingLogger.cs
 Microsoft.Build.Logging/ForwardingLoggerRecord.cs
 Microsoft.Build.Logging/LoggerDescription.cs
-Microsoft.Build.Logging/WriteHandler.cs
index 0c25ab811243d908f8eec34d32a72954a3537889..86971873d06ef2ccc29dab3e47b1b8d80c134ab2 100644 (file)
@@ -1,3 +1,21 @@
 FunctionalTest.cs
+Microsoft.Build.Construction/ProjectItemElementTest.cs
+Microsoft.Build.Construction/ProjectRootElementTest.cs
+Microsoft.Build.Evaluation/ProjectCollectionTest.cs
+Microsoft.Build.Evaluation/ProjectItemDefinitionTest.cs
+Microsoft.Build.Evaluation/ProjectItemTest.cs
+Microsoft.Build.Evaluation/ProjectTest.cs
+Microsoft.Build.Evaluation/ProjectPropertyTest.cs
+Microsoft.Build.Evaluation/ResolvedImportTest.cs
+Microsoft.Build.Evaluation/ToolsetTest.cs
+Microsoft.Build.Execution/BuildParametersTest.cs
+Microsoft.Build.Execution/BuildManagerTest.cs
+Microsoft.Build.Execution/BuildSubmissionTest.cs
+Microsoft.Build.Execution/ProjectInstanceTest.cs
+Microsoft.Build.Execution/ProjectMetadataInstanceTest.cs
+Microsoft.Build.Execution/ProjectTargetInstanceTest.cs
 Microsoft.Build.Internal/CollectionFromEnumerableTest.cs
+Microsoft.Build.Internal/ExpressionParserTest.cs
 Microsoft.Build.Logging/ConsoleLoggerTest.cs
+Microsoft.Build.Logging/LoggerDescriptionTest.cs
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectItemElementTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectItemElementTest.cs
new file mode 100644 (file)
index 0000000..caa93f1
--- /dev/null
@@ -0,0 +1,42 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using NUnit.Framework;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Exceptions;
+
+namespace MonoTests.Microsoft.Build.Construction
+{
+       [TestFixture]
+       public class ProjectItemElementTest
+       {
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void EmptyInclude ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Include='' />
+  </ItemGroup>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            ProjectRootElement.Create (xml);
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void MissingInclude ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo />
+  </ItemGroup>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            ProjectRootElement.Create (xml);
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectRootElementTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Construction/ProjectRootElementTest.cs
new file mode 100644 (file)
index 0000000..e864f4d
--- /dev/null
@@ -0,0 +1,222 @@
+using System;
+using System.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using NUnit.Framework;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Exceptions;
+
+namespace MonoTests.Microsoft.Build.Construction
+{
+       [TestFixture]
+       public class ProjectRootElementTest
+       {
+               const string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+
+               [Test]
+               [ExpectedException (typeof (UriFormatException))]
+               [Category ("NotWorking")] // URL is constructed for ElementLocation, which we don't support yet.
+               public void CreateExpectsAbsoluteUri ()
+               {
+                       var xml = XmlReader.Create (new StringReader (empty_project_xml), null, "foo.xml");
+                       ProjectRootElement.Create (xml);
+               }
+
+               [Test]
+               public void CreateAndPaths ()
+               {
+                       Assert.IsNull (ProjectRootElement.Create ().FullPath, "#1");
+                       var xml = XmlReader.Create (new StringReader (empty_project_xml), null, "file:///foo.xml");
+                       // This creator does not fill FullPath...
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.IsNull (root.FullPath, "#2");
+                       Assert.AreEqual (Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath), root.DirectoryPath, "#3");
+               }
+
+               [Test]
+               public void FullPathSetter ()
+               {
+                       var root = ProjectRootElement.Create ();
+                       root.FullPath = "test" + Path.DirectorySeparatorChar + "foo.xml";
+                       var full = Path.Combine (Path.GetDirectoryName (new Uri (GetType ().Assembly.CodeBase).LocalPath), "test", "foo.xml");
+                       Assert.AreEqual (full, root.FullPath, "#1");
+                       Assert.AreEqual (Path.GetDirectoryName (full), root.DirectoryPath, "#1");
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void FullPathSetNull ()
+               {
+                       ProjectRootElement.Create ().FullPath = null;
+               }
+
+               [Test]
+               public void InvalidProject ()
+               {
+                       try {
+                               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
+                       }
+               }
+
+               [Test]
+               public void CreateWithXmlLoads ()
+               {
+                       string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><ItemGroup><None Include='bar.txt' /></ItemGroup></Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual (1, root.Items.Count, "#1");
+               }
+               
+               [Test]
+               public void ToolsVersionDefault ()
+               {
+                       var g = ProjectCollection.GlobalProjectCollection;
+                       var root = ProjectRootElement.Create ();
+                       // this will be wrong in the future version, but since .NET 4.5 still expects "4.0" we can't say for sure.
+                       Assert.AreEqual ("4.0", root.ToolsVersion, "#1");
+               }
+               
+               [Test]
+               public void ToolsVersionIsEmptyWithXml ()
+               {
+                       string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><ItemGroup><None Include='bar.txt' /></ItemGroup></Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual (string.Empty, root.ToolsVersion, "#1");
+               }
+
+               [Test]
+               public void LoadUnknownChild ()
+               {
+                       string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><Unknown /></Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
+                       try {
+                               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
+                       }
+               }
+
+               [Test]
+               public void LoadUnregisteredItem ()
+               {
+                       string project_xml_1 = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'><ItemGroup><UnregisteredItem Include='bar.txt' /></ItemGroup></Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml_1), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual (1, root.Items.Count, "#1");
+               }
+               
+               [Test]
+               public void LoadInvalidProjectForBadCondition ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <Foo>What are 'ESCAPE' &amp; ""EVALUATE"" ? $ # % ^</Foo>
+    <!-- Note that this contains invalid Condition expression. Project.ctor() fails to load. -->
+    <Baz Condition=""$(Void)=="">$(FOO)</Baz>
+  </PropertyGroup>
+</Project>";
+                       var path = "file://localhost/foo.xml";
+                       var reader = XmlReader.Create (new StringReader (xml), null, path);
+                       var root = ProjectRootElement.Create (reader);
+                       Assert.AreEqual (2, root.Properties.Count, "#1");
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void LoadInvalidProjectGroupInProjectGroup ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
+  <PropertyGroup>
+    <Foo>Bar</Foo>
+    <PropertyGroup>
+      <X>x</X>
+      <Y>y</Y>
+      <Z>z</Z>
+    </PropertyGroup>
+  </PropertyGroup>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            ProjectRootElement.Create (xml);
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void LoadInvalidItemGroupInProjectGroup ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
+  <PropertyGroup>
+    <Foo>Bar</Foo>
+    <ItemGroup/>
+  </PropertyGroup>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            ProjectRootElement.Create (xml);
+               }
+               
+               [Test]
+               public void ChildAndAllChildren ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
+  <PropertyGroup>
+    <Foo>Bar</Foo>
+    <Item/>
+  </PropertyGroup>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual (2, root.Children.Count, "#1");
+                       // AllChildren expands descendants
+                       Assert.AreEqual (4, root.AllChildren.Count (), "#2");
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void SaveWithoutFullPath ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       root.Save ();
+               }
+               
+               [Test]
+               public void SaveToWriter ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       var sw = new StringWriter ();
+                       root.Save (sw);
+                       // CRLF? mmm, k...
+                       Assert.AreEqual ("<?xml version=\"1.0\" encoding=\"utf-16\"?>\r\n" + project_xml.Replace ('\'', '"'), sw.ToString (), "#1");
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void ImportsMissingProject ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='' />
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       ProjectRootElement.Create (xml);
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectCollectionTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectCollectionTest.cs
new file mode 100644 (file)
index 0000000..700a416
--- /dev/null
@@ -0,0 +1,150 @@
+//
+// ProjectCollectionTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using NUnit.Framework;
+using Microsoft.Build.Execution;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ProjectCollectionTest
+       {
+               [Test]
+               public void GlobalProperties ()
+               {
+                       var g = ProjectCollection.GlobalProjectCollection;
+                       Assert.AreEqual (0, g.GlobalProperties.Count, "#1");
+                       Assert.IsTrue (g.GlobalProperties.IsReadOnly, "#2");
+               }
+               
+               [Test]
+               public void DefaultToolsVersion ()
+               {
+                       var pc = ProjectCollection.GlobalProjectCollection;
+                       Assert.AreEqual (pc.Toolsets.First ().ToolsVersion, pc.DefaultToolsVersion, "#1");
+               }
+               
+               [Test]
+               public void Toolsets ()
+               {
+                       var pc = ProjectCollection.GlobalProjectCollection;
+                       Assert.IsNotNull (pc.Toolsets, "#1-1");
+                       Assert.IsTrue (pc.Toolsets.Any (), "#1-2");
+                       pc = new ProjectCollection ();
+                       Assert.IsNotNull (pc.Toolsets, "#2-1");
+                       Assert.IsTrue (pc.Toolsets.Any (), "#2-2");
+               }
+               
+               [Test]
+               public void BuildDoesNotIncreaseCollectionContent ()
+               {
+                       string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (empty_project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var coll = new ProjectCollection ();
+                       var inst = new ProjectInstance (root, null, null, coll);
+                       root.FullPath = "ProjectCollectionTest.BuildDoesNotIncreaseCollectionContent.proj";
+                       Assert.AreEqual (0, coll.Count, "#1");
+                       inst.Build ();
+                       Assert.AreEqual (0, coll.Count, "#2");
+               }
+               
+               [Test]
+               public void GetLoadedProjectsWithoutFullPath ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       string path = Path.GetFullPath ("foo.xml");
+                       var pc = new ProjectCollection ();
+                       
+                       pc.LoadProject (XmlReader.Create (new StringReader (project_xml), null, path));
+                       Assert.AreEqual (0, pc.GetLoadedProjects (path).Count, "#1"); // huh?
+                       Assert.AreEqual (0, pc.LoadedProjects.Count, "#1.1");
+                       
+                       new Project (root, null, null, pc);
+                       Assert.AreEqual (0, pc.GetLoadedProjects (path).Count, "#2"); // huh?
+               }
+                       
+               [Test]
+               public void GetLoadedProjectsSuccess ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       string path = Path.GetFullPath ("foo.xml");
+                       var pc = new ProjectCollection ();
+                       
+                       var proj = new Project (root, null, null, pc);
+                       // this order also matters for test; It sets FullPath after Project.ctor(), and should still work.
+                       root.FullPath = "foo.xml";
+                       
+                       Assert.AreEqual (1, pc.GetLoadedProjects (path).Count, "#1"); // wow ok...
+                       Assert.AreEqual (proj, pc.GetLoadedProjects (path).First (), "#2");
+               }
+                       
+               [Test]
+               public void GetLoadedProjectsSuccess2 ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       string path = Path.GetFullPath ("GetLoadedProjectsSuccess2.xml");
+                       var pc = new ProjectCollection ();
+                       
+                       using (var fs = File.CreateText (path))
+                               fs.Write (project_xml);
+                       try {
+                               var proj = pc.LoadProject (path);
+                               
+                               Assert.AreEqual (1, pc.GetLoadedProjects (path).Count, "#1"); // ok... LoadProject (with filename) adds it to the collection.
+                               Assert.AreEqual (proj, pc.GetLoadedProjects (path).First (), "#2");
+                       } finally {
+                               File.Delete (path);
+                       }
+               }
+                       
+               [Test]
+               public void GetLoadedProjectsForProjectInstance ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       string path = Path.GetFullPath ("foo.xml");
+                       var pc = new ProjectCollection ();
+                       root.FullPath = "foo.xml";
+                       
+                       new ProjectInstance (root, null, null, pc);                     
+                       Assert.AreEqual (0, pc.GetLoadedProjects (path).Count, "#1"); // so, ProjectInstance does not actually load Project...
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectItemDefinitionTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectItemDefinitionTest.cs
new file mode 100644 (file)
index 0000000..cd86873
--- /dev/null
@@ -0,0 +1,104 @@
+//
+// ProjectItemDefinitionTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using System.Collections.Generic;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ProjectItemDefinitionTest
+       {
+               [Test]
+               public void Properties ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemDefinitionGroup>
+    <Foo>
+       <prop1>value1</prop1>
+       <prop2>value1</prop2>
+    </Foo>
+    <!-- This one is merged into existing Foo definition above. -->
+    <Foo>
+       <prop1>valueX1</prop1><!-- this one overrides value1. -->
+       <prop3>value3</prop3>
+    </Foo>
+  </ItemDefinitionGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       Assert.AreEqual (1, proj.ItemDefinitions.Count, "#1"); // Foo
+                       var def = proj.ItemDefinitions ["Foo"];
+                       Assert.AreEqual ("Foo", def.ItemType, "#1x");
+                       Assert.AreEqual (3, def.MetadataCount, "#2");
+                       var md1 = def.Metadata.First (m => m.Name == "prop1");
+                       Assert.AreEqual ("Foo", md1.ItemType, "#2x");
+                       Assert.AreEqual ("valueX1", md1.UnevaluatedValue, "#3");
+                       // FIXME: enable it once we implemented it.
+                       //Assert.AreEqual ("valueX1", md1.EvaluatedValue, "#4");
+                       Assert.IsNotNull (md1.Predecessor, "#5");
+                       Assert.AreEqual ("value1", md1.Predecessor.UnevaluatedValue, "#6");
+                       // FIXME: enable it once we implemented it.
+                       //Assert.AreEqual ("value1", md1.Predecessor.EvaluatedValue, "#7");
+               }
+               
+               [Test]
+               public void Condition ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemDefinitionGroup>
+    <I Condition='{0}'>
+      <DefinedMetadata>X</DefinedMetadata>
+    </I>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+   <I Include='foo' />
+  </ItemGroup>
+</Project>";
+                       var reader = XmlReader.Create (new StringReader (string.Format (xml, "True")));
+                       var root = ProjectRootElement.Create (reader);
+                       var proj = new Project (root);
+                       var i = proj.GetItems ("I").First ();
+                       Assert.AreEqual ("X", i.GetMetadataValue ("DefinedMetadata"), "#1");
+                       
+                       reader = XmlReader.Create (new StringReader (string.Format (xml, "False")));
+                       root = ProjectRootElement.Create (reader);
+                       proj = new Project (root);
+                       i = proj.GetItems ("I").First ();
+                       Assert.AreEqual (string.Empty, i.GetMetadataValue ("DefinedMetadata"), "#2");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectItemTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectItemTest.cs
new file mode 100644 (file)
index 0000000..61973b7
--- /dev/null
@@ -0,0 +1,212 @@
+//
+// ProjectItemTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using System.Collections.Generic;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ProjectItemTest
+       {
+               [Test]
+               public void SetUnevaluatedInclude ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Include='foo/bar.txt' />
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual (1, root.ItemGroups.Count, "#1");
+                       var g = root.ItemGroups.First ();
+                       Assert.AreEqual (1, g.Items.Count, "#2");
+                       var xitem = g.Items.First ();
+                       var proj = new Project (root);
+                       var item = proj.ItemsIgnoringCondition.First ();
+                       string inc = "foo/bar.txt";
+                       Assert.AreEqual (inc, xitem.Include, "#3");
+                       Assert.AreEqual (inc, item.UnevaluatedInclude, "#4");
+                       string inc2 = "foo/bar.ext.txt";
+                       item.UnevaluatedInclude = inc2;
+                       Assert.AreEqual (inc2, xitem.Include, "#5");
+                       Assert.AreEqual (inc2, item.UnevaluatedInclude, "#6");
+               }
+               
+               void SetupTemporaryDirectoriesAndFiles ()
+               {
+                       Directory.CreateDirectory ("Test/ProjectItemTestTemporary");
+                       Directory.CreateDirectory ("Test/ProjectItemTestTemporary/parent");
+                       Directory.CreateDirectory ("Test/ProjectItemTestTemporary/parent/dir1");
+                       Directory.CreateDirectory ("Test/ProjectItemTestTemporary/parent/dir2");
+                       File.CreateText ("Test/ProjectItemTestTemporary/x.cs").Close ();
+                       File.CreateText ("Test/ProjectItemTestTemporary/parent/dir1/a.cs").Close ();
+                       File.CreateText ("Test/ProjectItemTestTemporary/parent/dir1/a1.cs").Close ();
+                       File.CreateText ("Test/ProjectItemTestTemporary/parent/dir1/b.cs").Close ();
+                       File.CreateText ("Test/ProjectItemTestTemporary/parent/dir2/a2.cs").Close ();
+                       File.CreateText ("Test/ProjectItemTestTemporary/parent/dir2/a.cs").Close ();
+                       File.CreateText ("Test/ProjectItemTestTemporary/parent/dir2/b.cs").Close ();
+               }
+               
+               void CleanupTemporaryDirectories ()
+               {
+                       Directory.Delete ("Test/ProjectItemTestTemporary", true);
+               }
+               
+               [Test]
+               public void WildcardExpansion ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Include='Test/ProjectItemTestTemporary/parent/dir*/a*.cs;Test/ProjectItemTestTemporary/x.cs' />
+  </ItemGroup>
+</Project>";
+                       try {
+                               SetupTemporaryDirectoriesAndFiles ();
+                               WildcardExpansionCommon (project_xml, false);
+                       } finally {
+                               CleanupTemporaryDirectories ();
+                       }
+               }
+               
+               [Test]
+               public void WildcardExpansionRecursive ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Include='Test/ProjectItemTestTemporary/parent/**/a*.cs;Test/ProjectItemTestTemporary/x.cs' />
+  </ItemGroup>
+</Project>";
+                       try {
+                               SetupTemporaryDirectoriesAndFiles ();
+                               WildcardExpansionCommon (project_xml, true);
+                       } finally {
+                               CleanupTemporaryDirectories ();
+                       }
+               }
+               
+               void WildcardExpansionCommon (string xmlString, bool hasRecursiveDir)
+               {
+                       char sep = Path.DirectorySeparatorChar;
+                       var xml = XmlReader.Create (new StringReader (xmlString));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       var xitem = proj.Xml.Items.First ();
+                       // sort is needed because they are only sorted by ItemType.
+                       var items = proj.Items.OrderBy (p => p.EvaluatedInclude).ToArray ();
+                       Assert.AreEqual (5, items.Length, "#1");
+                       Assert.AreEqual (string.Format ("Test/ProjectItemTestTemporary/parent/dir1{0}a.cs", Path.DirectorySeparatorChar), items [0].EvaluatedInclude, "#2");
+                       Assert.AreEqual ("a", items [0].GetMetadataValue ("Filename"), "#3");
+                       if (hasRecursiveDir)
+                               Assert.AreEqual ("dir1" + sep, items [0].GetMetadataValue ("RecursiveDir"), "#3.2");
+                       Assert.AreEqual (string.Format ("Test/ProjectItemTestTemporary/parent/dir1{0}a1.cs", Path.DirectorySeparatorChar), items [1].EvaluatedInclude, "#4");
+                       Assert.AreEqual ("a1", items [1].GetMetadataValue ("Filename"), "#5");
+                       if (hasRecursiveDir)
+                               Assert.AreEqual ("dir1" + sep, items [1].GetMetadataValue ("RecursiveDir"), "#5.2");
+                       Assert.AreEqual (string.Format ("Test/ProjectItemTestTemporary/parent/dir2{0}a.cs", Path.DirectorySeparatorChar), items [2].EvaluatedInclude, "#6");
+                       Assert.AreEqual ("a", items [2].GetMetadataValue ("Filename"), "#7");
+                       if (hasRecursiveDir)
+                               Assert.AreEqual ("dir2" + sep, items [2].GetMetadataValue ("RecursiveDir"), "#7.2");
+                       Assert.AreEqual (string.Format ("Test/ProjectItemTestTemporary/parent/dir2{0}a2.cs", Path.DirectorySeparatorChar), items [3].EvaluatedInclude, "#8");
+                       Assert.AreEqual ("a2", items [3].GetMetadataValue ("Filename"), "#9");
+                       if (hasRecursiveDir)
+                               Assert.AreEqual ("dir2" + sep, items [3].GetMetadataValue ("RecursiveDir"), "#9.2");
+                       Assert.AreEqual ("Test/ProjectItemTestTemporary/x.cs", items [4].EvaluatedInclude, "#10");
+                       for (int i = 0; i < items.Length; i++)
+                               Assert.AreEqual (xitem, items [i].Xml, "#11:" + i);
+               }
+               
+               [Test]
+               public void Metadata ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemDefinitionGroup>
+    <Foo>
+      <prop1>value1</prop1>
+    </Foo>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <Foo Include='foo/bar.txt'>
+      <prop1>valueX1</prop1>
+    </Foo>
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual (1, root.ItemGroups.Count, "#1");
+                       var g = root.ItemGroups.First ();
+                       Assert.AreEqual (1, g.Items.Count, "#2");
+                       var proj = new Project (root);
+                       var item = proj.ItemsIgnoringCondition.First ();
+                       var meta = item.GetMetadata ("prop1");
+                       Assert.IsNotNull (meta, "#3");
+                       Assert.AreEqual ("valueX1", meta.UnevaluatedValue, "#4");
+                       Assert.IsNotNull (meta.Predecessor, "#5");
+                       Assert.AreEqual ("value1", meta.Predecessor.UnevaluatedValue, "#6");
+                       
+                       // Well-known metadata don't show up via GetMetadata(), but does show up via GetMetadataValue().
+                       Assert.AreEqual (null, item.GetMetadata ("Filename"), "#7");
+                       Assert.AreEqual ("bar", item.GetMetadataValue ("Filename"), "#8");
+               }
+               
+               [Test]
+               public void ExpandPropertyThenTrim ()
+               {
+                       string test = @"A
+B
+C
+    ";
+                       string project_xml = string.Format (@"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <Test>{0}</Test>
+    <Test2>$(TEST)</Test2>
+  </PropertyGroup>
+  <ItemGroup>
+    <X Include='$(TEST)' />
+    <X2 Include='$(TEST)z' />
+  </ItemGroup>
+</Project>", test);
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "ProjectItemTest.ExpandPropertyThenTrim.proj";
+                       var proj = new ProjectInstance (root);
+                       Assert.AreEqual (test, proj.GetPropertyValue ("TEST"), "#1");
+                       Assert.AreEqual (test, proj.GetPropertyValue ("TEST2"), "#2");
+                       Assert.AreEqual (test.Trim (), proj.GetItems ("X").First ().EvaluatedInclude, "#3");                    
+                       Assert.AreEqual (test + "z", proj.GetItems ("X2").First ().EvaluatedInclude, "#4");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectPropertyTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectPropertyTest.cs
new file mode 100644 (file)
index 0000000..9c89ef0
--- /dev/null
@@ -0,0 +1,130 @@
+//
+// ProjectPropertyTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using System.Collections.Generic;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ProjectPropertyTest
+       {
+               [Test]
+               public void SetUnevaluatedValueOverwritesElementValue ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <Foo>Bar</Foo>
+    <Item/>
+    <X>1</X>
+    <X>2</X>
+    <PATH>overriden</PATH>
+  </PropertyGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var pe = root.Properties.First ();
+                       Assert.AreEqual ("Bar", pe.Value, "#1");
+                       var proj = new Project (root);
+                       var prop = proj.Properties.First (p => p.Name == "Foo");
+                       Assert.AreEqual ("Bar", prop.UnevaluatedValue, "#2");
+                       prop.UnevaluatedValue = "x";
+                       Assert.AreEqual ("x", pe.Value, "#3");
+                       
+                       prop = proj.Properties.First (p => p.Name == "X");
+                       Assert.AreEqual ("2", prop.UnevaluatedValue, "#4");
+                       Assert.IsNotNull (prop.Predecessor, "#5");
+                       Assert.AreEqual ("1", prop.Predecessor.UnevaluatedValue, "#6");
+                       
+                       // environment property could also be Predecessor (and removed...maybe.
+                       // I could reproduce only NRE = .NET bug with environment property so far.)
+                       prop = proj.Properties.First (p => p.Name == "PATH");
+                       Assert.AreEqual ("overriden", prop.UnevaluatedValue, "#7");
+                       Assert.IsNotNull (prop.Predecessor, "#8");
+               }
+
+               [Test]
+               [ExpectedException (typeof(InvalidOperationException))]
+               public void UpdateGlobalPropertyValue ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var props = new Dictionary<string, string> ();
+                       props.Add ("GP", "GV");
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root, props, null);
+                       var pe = proj.Properties.First (p => p.IsGlobalProperty);
+                       pe.UnevaluatedValue = "UPDATED";
+               }
+
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void UpdateEnvironmentPropertyValue ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       var pe = proj.Properties.First (p => p.IsEnvironmentProperty);
+                       pe.UnevaluatedValue = "UPDATED";
+               }
+
+               [Test]
+               public void DeepReferences ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <A>1</A>
+    <B>$(A)+1</B>
+    <C>$(B)+2</C>
+  </PropertyGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       Assert.AreEqual ("1+1+2", new Project (root).GetProperty ("C").EvaluatedValue, "#1");
+                       Assert.AreEqual ("1+1+2", new ProjectInstance (root).GetProperty ("C").EvaluatedValue, "#1");
+               }
+               
+               [Test]
+               public void PlatformPropertyEmptyByDefault ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       Assert.IsNull (proj.GetProperty ("PLATFORM"), "#1");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ProjectTest.cs
new file mode 100644 (file)
index 0000000..4ea4551
--- /dev/null
@@ -0,0 +1,253 @@
+//
+// ProjectTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using NUnit.Framework;
+using Microsoft.Build.Exceptions;
+using Microsoft.Build.Logging;
+using Microsoft.Build.Framework;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ProjectTest
+       {
+               [Test]
+               public void EscapeDoesWTF ()
+               {
+                       string value_xml = "What are 'ESCAPE' &amp; \"EVALUATE\" ? $ # % ^";
+                       string value = "What are 'ESCAPE' & \"EVALUATE\" ? $ # % ^";
+                       string escaped = "What are %27ESCAPE%27 & \"EVALUATE\" %3f %24 # %25 ^";
+                       string xml = string.Format (@"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <PropertyGroup>
+               <Foo>{0}</Foo>
+               <Baz>$(FOO)</Baz>
+       </PropertyGroup>
+</Project>", value_xml);
+                       var path = "file://localhost/foo.xml";
+                       var reader = XmlReader.Create (new StringReader (xml), null, path);
+                       var root = ProjectRootElement.Create (reader);
+                       var proj = new Project (root);
+                       var prop = proj.Properties.First (p => p.Name == "Foo");
+                       Assert.AreEqual (value, prop.UnevaluatedValue, "#1");
+                       Assert.AreEqual (value, prop.EvaluatedValue, "#2");
+                       // eh?
+                       Assert.AreEqual (value, Project.GetPropertyValueEscaped (prop), "#3");
+                       prop = proj.Properties.First (p => p.Name == "Baz");
+                       Assert.AreEqual ("$(FOO)", prop.UnevaluatedValue, "#4");
+                       Assert.AreEqual (value, prop.EvaluatedValue, "#5");
+                       // eh?
+                       Assert.AreEqual (value, Project.GetPropertyValueEscaped (prop), "#6");
+                       
+                       // OK you are fine.
+                       Assert.AreEqual (escaped, ProjectCollection.Escape (value), "#7");
+               }
+               
+               [Test]
+               public void FullPath ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       proj.FullPath = "ABC";
+                       Assert.IsTrue (proj.FullPath.EndsWith (Path.DirectorySeparatorChar + "ABC"), "#1");
+                       Assert.AreEqual (root.FullPath, proj.FullPath, "#2");
+               }
+               
+               [Test]
+               public void BuildEmptyProject ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "ProjectTest.BuildEmptyProject.proj";
+            
+                       // This seems to do nothing and still returns true
+                       Assert.IsTrue (new Project (root) { FullPath = "ProjectTest.BuildEmptyProject.1.proj" }.Build (), "#1");
+                       // This seems to fail to find the appropriate target
+                       Assert.IsFalse (new Project (root) { FullPath = "ProjectTest.BuildEmptyProject.2.proj" }.Build ("Build", null), "#2");
+                       // Thus, this tries to build all the targets (empty) and no one failed, so returns true(!)
+                       Assert.IsTrue (new Project (root) { FullPath = "ProjectTest.BuildEmptyProject.3.proj" }.Build (new string [0], null), "#3");
+                       // Actially null "targets" is accepted and returns true(!!)
+                       Assert.IsTrue (new Project (root) { FullPath = "ProjectTest.BuildEmptyProject.4.proj" }.Build ((string []) null, null), "#4");
+                       // matching seems to be blindly done, null string also results in true(!!)
+                       Assert.IsTrue (new Project (root) { FullPath = "ProjectTest.BuildEmptyProject.5.proj" }.Build ((string) null, null), "#5");
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void LoadInvalidProjectForBadCondition ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <Foo>What are 'ESCAPE' &amp; ""EVALUATE"" ? $ # % ^</Foo>
+    <!-- Note that this contains invalid Condition expression, yet ProjectElement.Create() does NOT fail. -->
+    <Baz Condition=""$(Void)=="">$(FOO)</Baz>
+  </PropertyGroup>
+</Project>";
+                       var reader = XmlReader.Create (new StringReader (xml));
+                       var root = ProjectRootElement.Create (reader);
+                       new Project (root);
+               }
+               
+               [Test]
+               public void ExpandString ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <Foo>What are 'ESCAPE' &amp; ""EVALUATE"" ? $ # % ^</Foo>
+    <Bar>y</Bar>
+    <Baz Condition=""$(Void)==''"">$(FOO)</Baz>
+  </PropertyGroup>
+</Project>";
+                       var reader = XmlReader.Create (new StringReader (xml));
+                       var root = ProjectRootElement.Create (reader);
+                       var proj = new Project (root);
+                       root.FullPath = "ProjectTest.ExpandString.proj";
+                       Assert.AreEqual ("xyz", proj.ExpandString ("x$(BAR)z"), "#1");
+                       Assert.AreEqual ("x$(BARz", proj.ExpandString ("x$(BARz"), "#2"); // incomplete
+                       Assert.AreEqual ("xz", proj.ExpandString ("x@(BAR)z"), "#3"); // not an item
+               }
+               
+               [Test]
+               public void BuildCSharpTargetGetFrameworkPaths ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new Project (root);
+                       root.FullPath = "ProjectTest.BuildCSharpTargetGetFrameworkPaths.proj";
+                       Assert.IsTrue (proj.Build ("GetFrameworkPaths", new ILogger [] {/*new ConsoleLogger ()*/}));
+               }
+               
+               [Test]
+               public void BuildCSharpTargetBuild ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <AssemblyName>Foo</AssemblyName>
+  </PropertyGroup>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "ProjectTest.BuildCSharpTargetBuild.proj";
+                       var proj = new Project (root, null, "4.0");
+                       Assert.IsFalse (proj.Build ("Build", new ILogger [] {/*new ConsoleLogger (LoggerVerbosity.Diagnostic)*/})); // missing mandatory properties
+               }
+               
+               [Test]
+               public void EvaluateItemConditionThenIgnored ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <P></P>
+  </PropertyGroup>
+  <ItemGroup>
+    <Foo Condition='' Include='x' />
+    <Bar Include='$(P)' />
+    <Baz Include='z' />
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       // note that Foo is ignored BUT Bar is NOT ignored.
+                       Assert.AreEqual (2, proj.ItemsIgnoringCondition.Count, "#1");
+                       Assert.IsNotNull ("Bar", proj.ItemsIgnoringCondition.First ().ItemType, "#2");
+                       Assert.IsNotNull ("Baz", proj.ItemsIgnoringCondition.Last ().ItemType, "#3");
+               }
+               
+               [Test]
+               public void EvaluateSamePropertiesInOrder ()
+               {
+                       // used in Microsoft.Common.targets
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <BaseIntermediateOutputPath Condition=""'$(BaseIntermediateOutputPath)' == ''"">obj\</BaseIntermediateOutputPath>
+  </PropertyGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       Assert.AreEqual ("obj\\", proj.GetPropertyValue ("BaseIntermediateOutputPath"), "#1");
+               }
+               
+               [Test]
+               public void DirtyMarking ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       Assert.IsFalse (proj.IsDirty, "#1");
+                       proj.MarkDirty ();
+                       Assert.IsTrue (proj.IsDirty, "#2");
+               }
+               
+               [Test]
+               public void DirtyMarking2 ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root);
+                       proj.DisableMarkDirty = true;
+                       proj.MarkDirty ();
+                       Assert.IsFalse (proj.IsDirty, "#1"); // not rejected, just ignored.
+                       proj.DisableMarkDirty = false;
+                       Assert.IsFalse (proj.IsDirty, "#2"); // not like status pending
+                       proj.MarkDirty ();
+                       Assert.IsTrue (proj.IsDirty, "#3");
+               }
+               
+               [Test]
+               public void CreateProjectInstance ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <AssemblyName>Foo</AssemblyName>
+  </PropertyGroup>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.CSharp.targets' />
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root, null, "4.0");
+                       var inst = proj.CreateProjectInstance ();
+                       Assert.AreEqual ("4.0", inst.ToolsVersion, "#1");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ResolvedImportTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ResolvedImportTest.cs
new file mode 100644 (file)
index 0000000..9c4359e
--- /dev/null
@@ -0,0 +1,181 @@
+//
+// ResolvedImportTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using NUnit.Framework;
+using Microsoft.Build.Exceptions;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Execution;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ResolvedImportTest
+       {
+               const string temp_file_name = "test_imported.proj";
+               
+               [Test]
+               public void SimpleImportAndSemanticValues ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='test_imported.proj' />
+</Project>";
+                       string imported = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <A>x</A>
+    <B>y</B>
+  </PropertyGroup>
+  <ItemGroup>
+    <X Include=""included.txt"" />
+  </ItemGroup>
+</Project>";
+                       using (var ts = File.CreateText (temp_file_name))
+                               ts.Write (imported);
+                       try {
+                               var reader = XmlReader.Create (new StringReader (xml));
+                               var root = ProjectRootElement.Create (reader);
+                               Assert.AreEqual (temp_file_name, root.Imports.First ().Project, "#1");
+                               var proj = new Project (root);
+                               var prop = proj.GetProperty ("A");
+                               Assert.IsNotNull (prop, "#2");
+                               Assert.IsTrue (prop.IsImported, "#3");
+                               var item = proj.GetItems ("X").FirstOrDefault ();
+                               Assert.IsNotNull (item, "#4");
+                               Assert.AreEqual ("included.txt", item.EvaluatedInclude, "#5");
+                       } finally {
+                               File.Delete (temp_file_name);
+                       }
+               }
+
+                       string import_overrides_test_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <A>X</A>
+  </PropertyGroup>
+  <Import Condition=""{0}"" Project='test_imported.proj' />
+  <PropertyGroup>
+    <B>Y</B>
+  </PropertyGroup>
+</Project>";
+                       string import_overrides_test_imported = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <C Condition='$(A)==x'>c</C>
+    <A>a</A>
+    <B>b</B>
+  </PropertyGroup>
+  <ItemGroup>
+    <X Include=""included.txt"" />
+  </ItemGroup>
+</Project>";
+
+               void ImportAndPropertyOverrides (string label, string condition, string valueA, string valueB, string valueAPredecessor, bool existsC)
+               {
+                       using (var ts = File.CreateText (temp_file_name))
+                               ts.Write (import_overrides_test_imported);
+                       try {
+                               string xml = string.Format (import_overrides_test_xml, condition);
+                               var reader = XmlReader.Create (new StringReader (xml));
+                               var root = ProjectRootElement.Create (reader);
+                               var proj = new Project (root);
+                               var a = proj.GetProperty ("A");
+                               Assert.IsNotNull (a, label + "#2");
+                               Assert.AreEqual (valueA, a.EvaluatedValue, label + "#3");
+                               if (valueAPredecessor == null)
+                                       Assert.IsNull (a.Predecessor, label + "#3.1");
+                               else {
+                                       Assert.IsNotNull (a.Predecessor, label + "#3.2");
+                                       Assert.AreEqual (valueAPredecessor, a.Predecessor.EvaluatedValue, label + "#3.3");
+                               }
+                               var b = proj.GetProperty ("B");
+                               Assert.IsNotNull (b, label + "#4");
+                               Assert.AreEqual (valueB, b.EvaluatedValue, label + "#5");
+                               var c = proj.GetProperty ("C"); // yes it can be retrieved.
+                               if (existsC) {
+                                       Assert.IsNotNull (c, label + "#6");
+                                       Assert.AreEqual ("c", c.EvaluatedValue, label + "#7");
+                               }
+                               else
+                                       Assert.IsNull (c, label + "#8");
+                       } finally {
+                               File.Delete (temp_file_name);
+                       }
+               }
+
+               [Test]
+               public void ImportAndPropertyOverrides ()
+               {
+                       ImportAndPropertyOverrides ("[1]", "'True'", "a", "Y", "X", true);
+                       ImportAndPropertyOverrides ("[2]", "$(A)=='X'", "a", "Y", "X", true); // evaluated as true
+                       ImportAndPropertyOverrides ("[3]", "$(B)=='Y'", "X", "Y", null, false); // evaluated as false
+                       ImportAndPropertyOverrides ("[4]", "$(B)=='b'", "X", "Y", null, false); // of course not evaluated with imported value
+               }
+
+               // FIXME:
+               // Looks like $(MSBuildThisFile) is available only within property value, not via .NET MSBuild API.
+               // Right now our variable is added as a Reserved property, but we will have to hide it.
+               //
+               [Test]
+               public void EvaluateMSBuildThisFileProperty ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <A>$(MSBuildThisFile)</A>
+  </PropertyGroup>
+  <Import Project='test_imported.proj' />
+</Project>";
+                       string imported = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <B>$(MSBuildThisFile)</B>
+  </PropertyGroup>
+</Project>";
+                       using (var ts = File.CreateText (temp_file_name))
+                               ts.Write (imported);
+                       try {
+                               var reader = XmlReader.Create (new StringReader (xml));
+                               var root = ProjectRootElement.Create (reader);
+                               var proj = new Project (root);
+                               var a = proj.GetProperty ("A");
+                               Assert.AreEqual (string.Empty, a.EvaluatedValue, "#1");
+                               var b = proj.GetProperty ("B");
+                               Assert.AreEqual (temp_file_name, b.EvaluatedValue, "#2");
+
+                               var pi  = new ProjectInstance (root);
+                               var ai = pi.GetProperty ("A");
+                               Assert.AreEqual (string.Empty, ai.EvaluatedValue, "#3");
+                               var bi = pi.GetProperty ("B");
+                               Assert.AreEqual (temp_file_name, bi.EvaluatedValue, "#4");
+                       } finally {
+                               File.Delete (temp_file_name);
+                       }
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ToolsetTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Evaluation/ToolsetTest.cs
new file mode 100644 (file)
index 0000000..ac4e2d6
--- /dev/null
@@ -0,0 +1,53 @@
+//
+// ToolSetTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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 Microsoft.Build.Evaluation;
+using NUnit.Framework;
+
+namespace MonoTests.Microsoft.Build.Evaluation
+{
+       [TestFixture]
+       public class ToolsetTest
+       {
+               [Test]
+               public void Constructor ()
+               {
+                       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");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildManagerTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildManagerTest.cs
new file mode 100644 (file)
index 0000000..0fcbdf7
--- /dev/null
@@ -0,0 +1,201 @@
+//
+// BuildManagerTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using System.Collections.Generic;
+using System.Linq;
+using Microsoft.Build.Framework;
+using Microsoft.Build.Logging;
+
+namespace MonoTests.Microsoft.Build.Execution
+{
+       [TestFixture]
+       public class BuildManagerTest
+       {
+               Project GetDummyProject ()
+               {
+                       string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var path = "file://localhost/foo.xml";
+                       var xml = XmlReader.Create (new StringReader (empty_project_xml), null, path);
+                       var root = ProjectRootElement.Create (xml);
+                       return new Project (root);
+               }
+               
+               [Test]
+               [ExpectedException (typeof (ArgumentNullException))]
+               public void GetProjectInstanceForBuildNullFullPath ()
+               {
+                       var manager = new BuildManager ();
+                       manager.GetProjectInstanceForBuild (GetDummyProject ());
+               }
+               
+               [Test]
+               [ExpectedException (typeof (ArgumentException))]
+               public void GetProjectInstanceForBuildEmptyFullPath ()
+               {
+                       var proj = GetDummyProject ();
+                       proj.FullPath = "";
+                       var manager = new BuildManager ();
+                       manager.GetProjectInstanceForBuild (proj);
+               }
+               
+               [Test]
+               public void GetProjectInstanceForBuild ()
+               {
+            string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+            var path = "file://localhost/foo.xml";
+            var xml = XmlReader.Create (new StringReader(empty_project_xml), null, path);
+            var root = ProjectRootElement.Create (xml);
+            root.FullPath = path;
+            var proj = new Project (root);
+            var manager = new BuildManager ();
+            var inst = manager.GetProjectInstanceForBuild (proj);
+            Assert.AreEqual (inst, manager.GetProjectInstanceForBuild (proj), "#1");
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void PendBuildRequestBeforeBeginBuild ()
+               {
+                       string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var path = "file://localhost/foo.xml";
+                       var xml = XmlReader.Create (new StringReader (empty_project_xml), null, path);
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root);
+            new BuildManager ().PendBuildRequest (new BuildRequestData (proj, new string [0]));
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidOperationException))]
+               public void ResetCachesDuringBuildIsInvalid ()
+               {
+                       // Windows does not have useful sleep or alternative, so skip it
+                       bool is_windows = true;
+                       switch (Environment.OSVersion.Platform) {
+                       case PlatformID.Unix:
+                       case PlatformID.MacOSX:
+                               is_windows = false;
+                               break;
+                       }
+                       string project_xml = string.Format (@"<Project DefaultTargets='Wait1Sec' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Target Name='Wait1Sec'>
+    <Exec Command='{0}' />
+  </Target>
+</Project>", is_windows ? "powershell -command \"Start-Sleep -s 1\"" : "/bin/sleep 1");
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root);
+                       var bm = new BuildManager ();
+                       bm.BeginBuild (new BuildParameters ());
+                       var sub = bm.PendBuildRequest (new BuildRequestData (proj, new string [] { "Wait1Sec" }));
+                       sub.ExecuteAsync (delegate {}, null);
+                       try {
+                               bm.ResetCaches ();
+                       } finally {
+                               bm.EndBuild (); // yes, it should work even after invalid ResetCaches call... at least on .NET it does.
+                       }
+               }
+
+               [Test]
+               public void BasicManualParallelBuilds ()
+               {
+                       string project_xml = @"<Project DefaultTargets='Wait1Sec' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Target Name='Wait1Sec'>
+    <!-- Exec Command='ping 10.1.1.1 -n 1 -w 1' /-->
+    <Exec Command='/bin/sleep 1' />
+  </Target>
+</Project>";
+                       switch (Environment.OSVersion.Platform) {
+                       case PlatformID.MacOSX:
+                       case PlatformID.Unix:
+                               break;
+                       default:
+                               return; // ignore, cannot run it
+                       }
+                       
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root);
+                       var bm = new BuildManager ();
+                       bm.BeginBuild (new BuildParameters () { Loggers = new ILogger [] {new ConsoleLogger (LoggerVerbosity.Diagnostic, TextWriter.Null.WriteLine, null, null)} });
+                       DateTime waitDone = DateTime.MinValue;
+                       DateTime beforeExec = DateTime.Now;
+                       var l = new List<BuildSubmission> ();
+                       for (int i = 0; i < 10; i++) {
+                               var sub = bm.PendBuildRequest (new BuildRequestData (proj, new string [] { "Wait1Sec" }));
+                               l.Add (sub);
+                               sub.ExecuteAsync (delegate { waitDone = DateTime.Now; }, null);
+                       }
+                       bm.EndBuild ();
+                       Assert.IsTrue (l.All (s => s.BuildResult.OverallResult == BuildResultCode.Success), "#1");
+                       DateTime endBuildDone = DateTime.Now;
+                       Assert.IsTrue (endBuildDone - beforeExec >= TimeSpan.FromSeconds (1), "#2");
+                       Assert.IsTrue (endBuildDone > waitDone, "#3");
+               }
+               
+               [Test]
+               public void BuildCommonResolveAssemblyReferences ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+  <ItemGroup>
+    <Reference Include='System.Core' />
+    <Reference Include='System.Xml' />
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "BuildManagerTest.BuildCommonResolveAssemblyReferences.proj";
+                       var proj = new ProjectInstance (root);
+                       var manager = new BuildManager ();
+                       var parameters = new BuildParameters () { Loggers = new ILogger [] {new ConsoleLogger (LoggerVerbosity.Diagnostic)} };
+                       var request = new BuildRequestData (proj, new string [] {"ResolveAssemblyReferences"});
+                       Assert.AreEqual (string.Empty, proj.GetPropertyValue ("TargetFrameworkDirectory"), "#1-1");
+                       var result = manager.Build (parameters, request);
+                       Assert.AreNotEqual (string.Empty, proj.GetPropertyValue ("TargetFrameworkDirectory"), "#1-2"); // filled during build.
+                       Assert.IsTrue (result.ResultsByTarget.ContainsKey ("GetFrameworkPaths"), "#2-1");
+                       Assert.IsTrue (result.ResultsByTarget.ContainsKey ("PrepareForBuild"), "#2-2");
+                       Assert.IsTrue (result.ResultsByTarget.ContainsKey ("ResolveAssemblyReferences"), "#2-3");
+                       var items = proj.GetItems ("ReferencePath");
+                       Assert.AreEqual (2, items.Count (), "#3");
+                       var syscore = items.FirstOrDefault (i => Path.GetFileName (i.EvaluatedInclude) == "System.Core.dll");
+                       var sysxml = items.FirstOrDefault (i => Path.GetFileName (i.EvaluatedInclude) == "System.Xml.dll");
+                       Assert.IsNotNull (syscore, "#4-1");
+                       Assert.IsNotNull (sysxml, "#4-2");
+                       Assert.IsTrue (File.Exists (syscore.EvaluatedInclude), "#5-1");
+                       Assert.IsTrue (File.Exists (sysxml.EvaluatedInclude), "#5-1");
+                       Assert.AreEqual (BuildResultCode.Success, result.OverallResult, "#6");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildParametersTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildParametersTest.cs
new file mode 100644 (file)
index 0000000..47cd5f9
--- /dev/null
@@ -0,0 +1,66 @@
+//
+// BuildParametersTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.Globalization;
+using System.IO;
+using System.Linq;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+
+namespace MonoTests.Microsoft.Build.Execution
+{
+       [TestFixture]
+       public class BuildParametersTest
+       {
+               [Test]
+               public void GetToolset ()
+               {
+                       var bp = new BuildParameters (ProjectCollection.GlobalProjectCollection);
+                       Assert.IsNull (bp.GetToolset ("0.1"), "#1");
+                       var ts = bp.GetToolset ("2.0");
+                       // They are equal
+                       Assert.AreEqual (ProjectCollection.GlobalProjectCollection.Toolsets.First (t => t.ToolsVersion == "2.0"), ts, "#2");
+
+                       bp = new BuildParameters ();
+                       Assert.IsNull (bp.GetToolset ("0.1"), "#1");
+                       ts = bp.GetToolset ("2.0");
+                       // They are NOT equal, because ProjectCollection seems to be different.
+                       Assert.AreNotEqual (ProjectCollection.GlobalProjectCollection.Toolsets.First (t => t.ToolsVersion == "2.0"), ts, "#2");                 
+               }
+               
+               [Test]
+               public void PropertiesDefault ()
+               {
+                       var bp = new BuildParameters ();
+                       Assert.IsTrue (bp.EnableNodeReuse, "#1");
+                       Assert.IsTrue (bp.EnvironmentProperties.Count > 0, "#2");
+                       Assert.AreEqual (CultureInfo.CurrentCulture, bp.Culture, "#3");
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildSubmissionTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/BuildSubmissionTest.cs
new file mode 100644 (file)
index 0000000..df2febc
--- /dev/null
@@ -0,0 +1,115 @@
+//
+// BuildSubmissionTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using Microsoft.Build.Logging;
+using Microsoft.Build.Framework;
+using System.Collections.Generic;
+
+namespace MonoTests.Microsoft.Build.Execution
+{
+       [TestFixture]
+       public class BuildSubmissionTest
+       {
+               [Test]
+               public void ResultBeforeExecute ()
+               {
+                       string empty_project_xml = "<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var path = "file://localhost/foo.xml";
+                       var xml = XmlReader.Create (new StringReader (empty_project_xml), null, path);
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root);
+                       var bm = new BuildManager ();
+                       bm.BeginBuild (new BuildParameters ());
+                       var sub = bm.PendBuildRequest (new BuildRequestData (proj, new string [0]));
+                       Assert.IsNull (sub.BuildResult, "#1");
+               }
+               
+               // This checks if the build output for each task is written to the loggers and not directly thrown as a Project loader error.
+               [Test]
+               public void TaskOutputsToLoggers ()
+               {
+            string project_xml = @"<Project DefaultTargets='Foo' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+  <Target Name='Foo'>
+    <ItemGroup>
+      <Foo Condition='$(X)' Include='foo.txt' />
+    </ItemGroup>
+  </Target>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "BuildSubmissionTest.TaskOutputsToLoggers.proj";
+            var proj = new ProjectInstance (root);
+                       Assert.AreEqual ("$(X)", root.Targets.First ().ItemGroups.First ().Items.First ().Condition, "#0");
+                       var sw = new StringWriter ();
+                       Assert.IsFalse (proj.Build (new ILogger [] {new ConsoleLogger (LoggerVerbosity.Diagnostic, sw.WriteLine, null, null)}), "#1");
+                       Assert.IsTrue (sw.ToString ().Contains ("$(X)"), "#2");
+               }
+               
+               [Test]
+               public void EndBuildWaitsForSubmissionCompletion ()
+               {
+                       // Windows does not have useful sleep or alternative, so skip it
+                       bool is_windows = true;
+                       switch (Environment.OSVersion.Platform) {
+                       case PlatformID.Unix:
+                       case PlatformID.MacOSX:
+                               is_windows = false;
+                               break;
+                       }
+                       string project_xml = string.Format (@"<Project DefaultTargets='Wait1Sec' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Target Name='Wait1Sec'>
+    <Exec Command='{0}' />
+  </Target>
+</Project>", is_windows ? "powershell -command \"Start-Sleep -s 1\"" : "/bin/sleep 1");
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "BuildSubmissionTest.EndBuildWaitsForSubmissionCompletion.proj";
+                       var proj = new ProjectInstance (root);
+                       var bm = new BuildManager ();
+                       bm.BeginBuild (new BuildParameters ());
+                       DateTime waitDone = DateTime.MinValue;
+                       DateTime beforeExec = DateTime.Now;
+                       var sub = bm.PendBuildRequest (new BuildRequestData (proj, new string [] { "Wait1Sec" }));
+                       sub.ExecuteAsync (delegate { waitDone = DateTime.Now; }, null);
+                       bm.EndBuild ();
+                       Assert.IsTrue (sub.BuildResult.OverallResult == BuildResultCode.Success, "#1");
+                       DateTime endBuildDone = DateTime.Now;
+                       Assert.IsTrue (endBuildDone - beforeExec >= TimeSpan.FromSeconds (1), "#2");
+                       Assert.IsTrue (endBuildDone > waitDone, "#3");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectInstanceTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectInstanceTest.cs
new file mode 100644 (file)
index 0000000..327aa38
--- /dev/null
@@ -0,0 +1,103 @@
+//
+// ProjectInstanceTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using Microsoft.Build.Evaluation;
+
+namespace MonoTests.Microsoft.Build.Execution
+{
+       [TestFixture]
+       public class ProjectInstanceTest
+       {
+               [Test]
+               public void ItemsAndProperties ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <X Condition='false' Include='bar.txt' />
+    <X Include='foo.txt'>
+      <M>m</M>
+      <N>=</N>
+    </X>
+  </ItemGroup>
+  <PropertyGroup>
+    <P Condition='false'>void</P>
+    <P Condition='true'>valid</P>
+  </PropertyGroup>
+</Project>";
+            var xml = XmlReader.Create (new StringReader(project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+            var item = proj.Items.First ();
+                       Assert.AreEqual ("foo.txt", item.EvaluatedInclude, "#1");
+                       var prop = proj.Properties.First (p => p.Name=="P");
+                       Assert.AreEqual ("valid", prop.EvaluatedValue, "#2");
+                       Assert.IsNotNull (proj.GetProperty ("MSBuildProjectDirectory"), "#3");
+                       Assert.AreEqual ("2.0", proj.ToolsVersion, "#4");
+               }
+               
+               [Test]
+               public void ExplicitToolsVersion ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+            var xml = XmlReader.Create (new StringReader(project_xml));
+            var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root, null, "4.0", new ProjectCollection ());
+                       Assert.AreEqual ("4.0", proj.ToolsVersion, "#1");
+               }
+               
+               [Test]
+               public void BuildEmptyProject ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' />";
+                       var xml = XmlReader.Create (new StringReader (project_xml), null, "file://localhost/foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       // This seems to do nothing and still returns true
+                       root.FullPath = "ProjectInstanceTest.BuildEmptyProject.1.proj";
+                       Assert.IsTrue (new ProjectInstance (root).Build (), "#1");
+                       // This seems to fail to find the appropriate target
+                       root.FullPath = "ProjectInstanceTest.BuildEmptyProject.2.proj";
+                       Assert.IsFalse (new ProjectInstance (root).Build ("Build", null), "#2");
+                       // Thus, this tries to build all the targets (empty) and no one failed, so returns true(!)
+                       root.FullPath = "ProjectInstanceTest.BuildEmptyProject.3.proj";
+                       Assert.IsTrue (new ProjectInstance (root).Build (new string [0], null), "#3");
+                       // Actially null "targets" is accepted and returns true(!!)
+                       root.FullPath = "ProjectInstanceTest.BuildEmptyProject.4.proj";
+                       Assert.IsTrue (new ProjectInstance (root).Build ((string []) null, null), "#4");
+                       // matching seems to be blindly done, null string also results in true(!!)
+                       root.FullPath = "ProjectInstanceTest.BuildEmptyProject.5.proj";
+                       Assert.IsTrue (new ProjectInstance (root).Build ((string) null, null), "#5");
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectMetadataInstanceTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectMetadataInstanceTest.cs
new file mode 100644 (file)
index 0000000..5c136d6
--- /dev/null
@@ -0,0 +1,78 @@
+//
+// ProjectMetadataInstanceTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+
+namespace MonoTests.Microsoft.Build.Execution
+{
+       [TestFixture]
+       public class ProjectMetadataInstanceTest
+       {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <X Include='foo.txt'>
+      <M>m</M>
+      <N>=</N>
+    </X>
+  </ItemGroup>
+</Project>";
+
+               [Test]
+               public void PropertiesCopiesValues ()
+               {
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       string path = Path.GetFullPath ("foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root);
+                       var item = proj.Items.First ();
+                       var md = item.Metadata.First ();
+                       Assert.AreEqual ("m", item.Metadata.First ().EvaluatedValue, "#1");
+                       Assert.AreEqual ("m", root.ItemGroups.First ().Items.First ().Metadata.First ().Value, "#2");
+                       root.ItemGroups.First ().Items.First ().Metadata.First ().Value = "X";
+                       Assert.AreEqual ("m", item.Metadata.First ().EvaluatedValue, "#3");
+               }
+               
+               [Test]
+               public void ToStringOverride ()
+               {
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       string path = Path.GetFullPath ("foo.xml");
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new ProjectInstance (root);
+                       var item = proj.Items.First ();
+                       Assert.AreEqual ("M=m", item.Metadata.First ().ToString (), "#1");
+                       Assert.AreEqual ("N==", item.Metadata.Last ().ToString (), "#2"); // haha
+               }
+       }
+}
+
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectTargetInstanceTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Execution/ProjectTargetInstanceTest.cs
new file mode 100644 (file)
index 0000000..2ae7148
--- /dev/null
@@ -0,0 +1,172 @@
+//
+// ProjectTargetInstanceTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Execution;
+using NUnit.Framework;
+using Microsoft.Build.Logging;
+using Microsoft.Build.Framework;
+
+namespace MonoTests.Microsoft.Build.Execution
+{
+       [TestFixture]
+       public class ProjectTargetInstanceTest
+       {
+               [Test]
+               public void DefaultTargetsEmpty ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+                       Assert.AreEqual (new string [0], proj.DefaultTargets, "#1");
+               }
+               
+               [Test]
+               public void DefaultTargetsFromAttribute ()
+               {
+            string project_xml = @"<Project DefaultTargets='Foo Bar Baz;Foo' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+                       string [] expected = {"Foo Bar Baz", "Foo"};
+                       Assert.AreEqual (expected, proj.DefaultTargets, "#1");
+               }
+               
+               [Test]
+               public void DefaultTargetsFromElements ()
+               {
+                       string [] defaultTargetAtts = {string.Empty, "DefaultTargets=''"};
+                       
+                       for (int i = 0; i < defaultTargetAtts.Length; i++) {
+                               string project_xml = string.Format (@"<Project {0} xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Target Name='Foo' />
+       <Target Name='Bar' />
+</Project>", defaultTargetAtts [i]);
+                   var xml = XmlReader.Create (new StringReader (project_xml));
+                   var root = ProjectRootElement.Create (xml);
+                   var proj = new ProjectInstance (root);
+                               string [] expected = {"Foo"}; // Bar is not included
+                               Assert.AreEqual (expected, proj.DefaultTargets, "#1-" + i);
+                       }
+               }
+               
+               [Test]
+               public void MicrosoftCommonTargets ()
+               {
+                       string [] defaultTargetAtts = { string.Empty, "DefaultTargets=''" };
+                       
+                       for (int i = 0; i < defaultTargetAtts.Length; i++) {
+                               string project_xml = string.Format (@"<Project {0} xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+</Project>", defaultTargetAtts [i]);
+                               var xml = XmlReader.Create (new StringReader (project_xml));
+                               var root = ProjectRootElement.Create (xml);
+                               var proj = new ProjectInstance (root);
+                               Assert.AreEqual ("Build", proj.DefaultTargets.FirstOrDefault (), "#1-" + i);
+                       }
+               }
+               
+               [Test]
+               public void DefaultTargetsOverride ()
+               {
+            string project_xml = @"<Project DefaultTargets='Foo' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+            var proj = new ProjectInstance (root);
+                       Assert.AreEqual ("Foo", proj.DefaultTargets.FirstOrDefault (), "#1");
+               }
+               
+               [Test]
+               public void MultipleDefaultTargets ()
+               {
+                       bool[] expected = { true, false, true };
+                       string [] defaultTargets = {"Foo", "Foo;Bar", "Foo;Bar"};
+                               string [] targets = { string.Empty, string.Empty, "<Target Name='Bar' />" };
+                       for (int i = 0; i < expected.Length; i++) {
+                               string project_xml = string.Format (@"<Project DefaultTargets='{0}' xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Import Project='$(MSBuildToolsPath)\Microsoft.Common.targets' />
+       <Target Name='Foo' />
+       {1}
+</Project>", defaultTargets [i], targets [i]);
+                               var xml = XmlReader.Create (new StringReader (project_xml));
+                               var root = ProjectRootElement.Create (xml);
+                               root.FullPath = string.Format ("ProjectInstanceTest.MultipleDefaultTargets.{0}.proj", i);
+                               var proj = new ProjectInstance (root);
+                               Assert.AreEqual ("Foo", proj.DefaultTargets.FirstOrDefault (), "#1-" + i);
+                               Assert.AreEqual (expected [i], proj.Build (), "#2-" + i);
+                       }
+               }
+               
+               [Test]
+               public void DependsOnTargets ()
+               {
+            string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+       <Target Name='Bar' DependsOnTargets='Foo' />
+       <Target Name='Foo'>
+           <Error Text='expected error' />
+       </Target>
+</Project>";
+            var xml = XmlReader.Create (new StringReader (project_xml));
+            var root = ProjectRootElement.Create (xml);
+                       root.FullPath = "ProjectInstanceTest.DependsOnTargets.proj";
+            var proj = new ProjectInstance (root);
+                       Assert.AreEqual (2, proj.Targets.Count, "#1");
+                       Assert.IsFalse (proj.Build ("Bar", new ILogger [0]), "#2");
+               }
+               
+               [Test]
+               public void InputsAndOutputs ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <Target Name='Foo' Inputs='inputsandoutputstest.txt' Outputs='inputsandoutputstest.txt'>
+    <Error Text='error' />
+  </Target>
+</Project>";
+                       try {
+                               if (!File.Exists ("inputsandoutputstest.txt"))
+                                       File.CreateText ("inputsandoutputstest.txt").Close ();
+                               var xml = XmlReader.Create (new StringReader (project_xml));
+                               var root = ProjectRootElement.Create (xml);
+                               root.FullPath = "ProjectTargetInstanceTest.InputsAndOutputs.proj";
+                               var proj = new ProjectInstance (root);
+                               Assert.IsTrue (proj.Build (), "#1"); // if it does not skip Foo, it results in an error.
+                       } finally {
+                               if (File.Exists ("inputsandoutputstest.txt"))
+                                       File.Delete ("inputsandoutputstest.txt");
+                       }
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Internal/ExpressionParserTest.cs
new file mode 100644 (file)
index 0000000..7654538
--- /dev/null
@@ -0,0 +1,287 @@
+//
+// ExpressionParserTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
+using System.Linq;
+using System.Xml;
+using Microsoft.Build.Construction;
+using Microsoft.Build.Evaluation;
+using NUnit.Framework;
+using Microsoft.Build.Execution;
+using Microsoft.Build.Exceptions;
+using System.Collections.Generic;
+
+namespace MonoTests.Microsoft.Build.Internal
+{
+       [TestFixture]
+       public class ExpressionParserTest
+       {
+                       string [] invalid_always = {
+                               "$(Foo..Bar)",
+                               "$([DateTime.Now])", // fullname required
+                               "$([System.DateTime.Now])", // member cannot be invoked with '.'
+                       };
+                       string [] invalid_as_boolean = {
+                               "$",
+                               "@",
+                               "%",
+                               "%-1",
+                               "$(",
+                               "%(",
+                               "$)",
+                               "%)",
+                               "%24",
+                               "()",
+                               "{}",
+                               "A", // must be evaluated as a boolean
+                               "1", // ditto (no default conversion to bool)
+                               "$ (foo) == ''",
+                               "@ (foo) == ''",
+                               "$(1)",
+                               "$(Foo) == And", // reserved keyword 'and'
+                               "$(Foo) == Or", // reserved keyword 'or'
+                               "$(Foo) == $(Bar) == $(Baz)", // unexpected '=='
+                               "$([System.DateTime]::Now)", // it is DateTime
+                               "$([System.String]::Format('Tr'))$([System.String]::Format('ue'))", // only one expression is accepted
+                               "$([System.String]::Format(null))", // causing ANE, wrapped by InvalidProjectFileException
+                               "yep",
+                               "nope",
+                               "ONN",
+                               "OFFF",
+                       };
+                       string [] valid = {
+                               "'%24' == 0",
+                               "true",
+                               "fAlSe",
+                               "(false)",
+                               "A==A",
+                               "A ==A",
+                               "A== A",
+                               "A=='A'",
+                               "A==\tA",
+                               "\tA== A",
+                               "$([System.String]::Format('True'))",
+                               "$([System.String]::Format('True', null))",
+                               "False And True == True And True",
+                               "True or True or False",
+                               "(True or True or False)",
+                               "True and False",
+                               "(True) and (False)",
+                               "yes",
+                               "nO",
+                               "oN",
+                               "oFf",
+                       };
+                       string [] depends = {
+                               // valid only if evaluated to boolean
+                               "$(foo)",
+                               "@(foo)",
+                       };
+                       
+               [Test]
+               public void EvaluateAsBoolean ()
+               {
+                       foreach (var expr in invalid_always.Concat (invalid_as_boolean).Concat (valid)) {
+                               string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Condition=""{0}"" Include='x' />
+  </ItemGroup>
+</Project>";
+                               var xml = XmlReader.Create (new StringReader (string.Format (project_xml, expr)));
+                               var root = ProjectRootElement.Create (xml);
+                               try {
+                                       new Project (root);
+                                       if (invalid_as_boolean.Contains (expr) || invalid_always.Contains (expr))
+                                               Assert.Fail ("Parsing Condition '{0}' should fail", expr);
+                               } catch (Exception ex) {
+                                       if (valid.Contains (expr))
+                                               throw new Exception (string.Format ("failed to parse '{0}'", expr), ex);
+                                       else if (ex is InvalidProjectFileException)
+                                               continue;
+                                       throw new Exception (string.Format ("unexpected exception to parse '{0}'", expr), ex);
+                               }
+                       }
+               }
+               
+               [Test]
+               public void EvaluateAsString ()
+               {
+                       foreach (var expr in invalid_always.Concat (invalid_as_boolean).Concat (valid)) {
+                               try {
+                                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+         <ItemGroup>
+           <Foo Include=""{0}"" />
+         </ItemGroup>
+       </Project>";
+                                       var xml = XmlReader.Create (new StringReader (string.Format (project_xml, expr)));
+                                       var root = ProjectRootElement.Create (xml);
+                                       // everything but 'invalid_always' should pass
+                                       new Project (root);
+                               } catch (Exception ex) {
+                                       if (!invalid_always.Contains (expr))
+                                               throw new Exception (string.Format ("failed to parse '{0}'", expr), ex);
+                               }
+                       }
+               }
+               
+               [Test]
+               public void EvaluatePropertyReferencesWithProperties ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Condition=""$(foo)"" Include='x' />
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var props = new Dictionary<string,string> ();
+                       props ["foo"] = "true";
+                       new Project (root, props, null);
+               }
+               
+               [Test]
+               public void EvaluateItemReferences ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Include='false' />
+    <!-- by the time Bar is evaluated, Foo is already evaluated and taken into consideration in expansion -->
+    <Bar Condition=""@(foo)"" Include='x' />
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       new Project (root);
+               }
+               
+               [Test]
+               public void EvaluateReferencesWithoutProperties ()
+               {
+                       foreach (var expr in depends) {
+                               string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Foo Condition=""{0}"" Include='x' />
+  </ItemGroup>
+</Project>";
+                               var xml = XmlReader.Create (new StringReader (string.Format (project_xml, expr)));
+                               var root = ProjectRootElement.Create (xml);
+                               try {
+                                       new Project (root);
+                                       Assert.Fail ("Parsing Condition '{0}' should fail", expr);
+                               } catch (InvalidProjectFileException) {
+                                       continue;
+                               }
+                       }
+               }
+               
+               [Test]
+               public void SemicolonHandling ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <Foo Condition=""'A;B'=='A;B'"">'A;B'</Foo>
+  </PropertyGroup>
+  <ItemGroup>
+    <Bar Include='$(Foo)' />
+  </ItemGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root); // at this state property is parsed without error i.e. Condition evaluates fine.
+                       var prop = proj.GetProperty ("Foo");
+                       Assert.AreEqual ("'A;B'", prop.EvaluatedValue, "#1");
+                       var items = proj.GetItems ("Bar");
+                       Assert.AreEqual ("'A", items.First ().EvaluatedInclude, "#2");
+                       Assert.AreEqual ("$(Foo)", items.First ().UnevaluatedInclude, "#3");
+                       Assert.AreEqual (2, items.Count, "#4");
+                       Assert.AreEqual ("B'", items.Last ().EvaluatedInclude, "#5");
+                       Assert.AreEqual ("$(Foo)", items.Last ().UnevaluatedInclude, "#6");
+                       Assert.IsTrue (items.First ().Xml == items.Last ().Xml, "#7");
+               }
+               
+               // the same as above except that ItemGroup goes first (and yet evaluated the same).
+               [Test]
+               public void EvaluationOrderPropertiesPrecedesItems ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Bar Include='$(Foo)' />
+  </ItemGroup>
+  <PropertyGroup>
+    <Foo Condition=""'A;B'=='A;B'"">'A;B'</Foo>
+  </PropertyGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       var proj = new Project (root); // at this state property is parsed without error i.e. Condition evaluates fine.
+                       var prop = proj.GetProperty ("Foo");
+                       Assert.AreEqual ("'A;B'", prop.EvaluatedValue, "#1");
+                       var items = proj.GetItems ("Bar");
+                       Assert.AreEqual ("'A", items.First ().EvaluatedInclude, "#2");
+                       Assert.AreEqual ("$(Foo)", items.First ().UnevaluatedInclude, "#3");
+                       Assert.AreEqual (2, items.Count, "#4");
+                       Assert.AreEqual ("B'", items.Last ().EvaluatedInclude, "#5");
+                       Assert.AreEqual ("$(Foo)", items.Last ().UnevaluatedInclude, "#6");
+                       Assert.IsTrue (items.First ().Xml == items.Last ().Xml, "#7");
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void PropertyReferencesItem ()
+               {
+                       string project_xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <ItemGroup>
+    <Bar Include='True' />
+  </ItemGroup>
+  <PropertyGroup>
+    <Foo Condition='@(Bar)'>X</Foo><!-- not allowed -->
+  </PropertyGroup>
+</Project>";
+                       var xml = XmlReader.Create (new StringReader (project_xml));
+                       var root = ProjectRootElement.Create (xml);
+                       new Project (root);
+               }
+               
+               [Test]
+               [ExpectedException (typeof (InvalidProjectFileException))]
+               public void SequentialPropertyReferenceNotAllowed ()
+               {
+                       string xml = @"<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003'>
+  <PropertyGroup>
+    <A>x</A>
+    <B>y</B>
+    <C Condition=""$(A)$(B)==''"">z</C>
+  </PropertyGroup>
+</Project>";
+                       var reader = XmlReader.Create (new StringReader (xml));
+                       var root = ProjectRootElement.Create (reader);
+                       new Project (root);
+               }
+       }
+}
+
index 8dd705f6b107ee51acb6f42df5ff7c221227f455..0135393d9efe41f5178b24d13af7339e37dffaea 100644 (file)
@@ -1,3 +1,30 @@
+//
+// ConsoleLoggerTest.cs
+//
+// Author:
+//   Atsushi Enomoto (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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.IO;
@@ -10,7 +37,10 @@ namespace MonoTests.Microsoft.Build.Logging
        [TestFixture]
        public class ConsoleLoggerTest
        {
+               // Unfortunately, the existing code in MS.Build.Engine.dll has slightly different
+               // format. We'd rather use already complete implementation, just disabled this test.
                [Test]
+               [Category ("NotWorking")]
                public void BasicLoggerUsage ()
                {
                        string expected = @"file : cat error code: msg
diff --git a/mcs/class/Microsoft.Build/Test/Microsoft.Build.Logging/LoggerDescriptionTest.cs b/mcs/class/Microsoft.Build/Test/Microsoft.Build.Logging/LoggerDescriptionTest.cs
new file mode 100644 (file)
index 0000000..e062fc9
--- /dev/null
@@ -0,0 +1,49 @@
+//
+// LoggerDescriptionTest.cs
+//
+// Author:
+//     Atsushi Eno (atsushi@xamarin.com)
+//
+// Copyright (C) 2013 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 Microsoft.Build.Logging;
+using Microsoft.Build.Framework;
+using NUnit.Framework;
+
+namespace MonoTests.Microsoft.Build.Logging
+{
+       [TestFixture]
+       public class LoggerDescriptionTest
+       {
+               [Test]
+               public void CreateLogger ()
+               {
+                       new LoggerDescription ("Microsoft.Build.Logging.ConsoleLogger",
+                                       typeof (ConsoleLogger).Assembly.FullName,
+                                       null,
+                                       null,
+                                       LoggerVerbosity.Normal)
+                               .CreateLogger();
+               }
+       }
+}
diff --git a/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v2.0/RedistList/FrameworkList.xml b/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v2.0/RedistList/FrameworkList.xml
new file mode 100644 (file)
index 0000000..879fdf4
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FileList Name=".NET Framework 2.0" TargetFrameworkDirectory="..\..\..\..\..\lib\net_2_0">
+</FileList>
diff --git a/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v3.5/RedistList/FrameworkList.xml b/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v3.5/RedistList/FrameworkList.xml
new file mode 100644 (file)
index 0000000..6f4b7b9
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FileList  Name=".NET Framework 3.5" TargetFrameworkDirectory="..\..\..\..\..\lib\net_2_0" IncludeFramework="v3.0">
+</FileList>
diff --git a/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v4.0/RedistList/FrameworkList.xml b/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v4.0/RedistList/FrameworkList.xml
new file mode 100644 (file)
index 0000000..9899af1
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FileList  Name=".NET Framework 4" TargetFrameworkDirectory="..\..\..\..\..\lib\net_4_0">
+</FileList>
diff --git a/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v4.5/RedistList/FrameworkList.xml b/mcs/class/Microsoft.Build/xbuild-testing/.NETFramework/v4.5/RedistList/FrameworkList.xml
new file mode 100644 (file)
index 0000000..9223cbb
--- /dev/null
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="utf-8"?>
+<FileList  Name=".NET Framework 4.5" TargetFrameworkDirectory="..\..\..\..\..\lib\net_4_5">
+</FileList>
index 9732b655d2031f5b893cdcb96da04b6cce4b85b4..feb4294647f45a19f3ee62846f471a890bd8ed16 100644 (file)
@@ -130,6 +130,22 @@ namespace MonoTests.EvaluatorTest
                        Assert.AreEqual ("1+", sres, "The result should have been the input string, since we have a partial input");
                }
 
+               [Test]
+               public void GotoWithUnreachableStatement ()
+               {
+                       Evaluator.Run ("using System;");
+
+                       string code = "var x = new Action(() => {" +
+                       "Console.WriteLine(\"beforeGoto\");" +
+                       "goto L;" +
+               "L:" +
+                       "Console.WriteLine(\"afterGoto\");" +
+                       "});";
+
+                       Assert.IsTrue (Evaluator.Run (code), "#1");
+                       Assert.IsTrue (Evaluator.Run ("x();"), "#2");
+               }
+
 #if NET_4_0
                [Test]
                public void DynamicStatement ()
index be60f050842586b7e7fd1bda9c21985994d11389..19b444ebd39e40afb797f44f270c32cec75089b0 100644 (file)
@@ -35,6 +35,11 @@ using System.Runtime.ConstrainedExecution;
 #if !PLATFORM_COMPACTFRAMEWORK
 [assembly: AllowPartiallyTrustedCallers]
 [assembly: ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
+  #if NET_4_0
+    [assembly: SecurityRules(SecurityRuleSet.Level1)]
+  #else
+    [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
+  #endif
 #endif
 
 // Version information for an assembly consists of the following four values:
index e86df829ba5eb1e60050ea2f1fa784f53a68822a..13096f05947b418888735d9ae55edce527da6103 100644 (file)
@@ -93,6 +93,7 @@ namespace Mono.Debugger.Soft
                public long catch_type_id;
        }
 
+       [Flags]
        enum ExceptionClauseFlags {
                None = 0x0,
                Filter = 0x1,
@@ -149,6 +150,7 @@ namespace Mono.Debugger.Soft
                VALUE_TYPE_ID_TYPE = 0xf1
        }
 
+       [Flags]
        enum InvokeFlags {
                NONE = 0x0,
                DISABLE_BREAKPOINTS = 0x1,
@@ -220,6 +222,7 @@ namespace Mono.Debugger.Soft
                UNKNOWN = 4
        }
 
+       [Flags]
        enum StackFrameFlags {
                NONE = 0,
                DEBUGGER_INVOKE = 1,
@@ -345,6 +348,10 @@ namespace Mono.Debugger.Soft
                        get; set;
                }
 
+               public int ExitCode {
+                       get; set;
+               }
+
                public EventInfo (EventType type, int req_id) {
                        EventType = type;
                        ReqId = req_id;
@@ -398,7 +405,7 @@ namespace Mono.Debugger.Soft
                 * with newer runtimes, and vice versa.
                 */
                internal const int MAJOR_VERSION = 2;
-               internal const int MINOR_VERSION = 25;
+               internal const int MINOR_VERSION = 27;
 
                enum WPSuspendPolicy {
                        NONE = 0,
@@ -549,6 +556,7 @@ namespace Mono.Debugger.Soft
                        IS_INITIALIZED = 18
                }
 
+               [Flags]
                enum BindingFlagsExtensions {
                        BINDING_FLAGS_IGNORE_CASE = 0x70000000,
                }
@@ -1221,82 +1229,71 @@ namespace Mono.Debugger.Soft
 
                                                        EventType etype = (EventType)kind;
 
+                                                       long thread_id = r.ReadId ();
                                                        if (kind == EventKind.VM_START) {
-                                                               long thread_id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
                                                                //EventHandler.VMStart (req_id, thread_id, null);
                                                        } else if (kind == EventKind.VM_DEATH) {
+                                                               int exit_code = 0;
+                                                               if (Version.AtLeast (2, 27))
+                                                                       exit_code = r.ReadInt ();
                                                                //EventHandler.VMDeath (req_id, 0, null);
-                                                               events [i] = new EventInfo (etype, req_id) { };
+                                                               events [i] = new EventInfo (etype, req_id) { ExitCode = exit_code };
                                                        } else if (kind == EventKind.THREAD_START) {
-                                                               long thread_id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
                                                                //EventHandler.ThreadStart (req_id, thread_id, thread_id);
                                                        } else if (kind == EventKind.THREAD_DEATH) {
-                                                               long thread_id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
                                                                //EventHandler.ThreadDeath (req_id, thread_id, thread_id);
                                                        } else if (kind == EventKind.ASSEMBLY_LOAD) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.AssemblyLoad (req_id, thread_id, id);
                                                        } else if (kind == EventKind.ASSEMBLY_UNLOAD) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.AssemblyUnload (req_id, thread_id, id);
                                                        } else if (kind == EventKind.TYPE_LOAD) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.TypeLoad (req_id, thread_id, id);
                                                        } else if (kind == EventKind.METHOD_ENTRY) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.MethodEntry (req_id, thread_id, id);
                                                        } else if (kind == EventKind.METHOD_EXIT) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.MethodExit (req_id, thread_id, id);
                                                        } else if (kind == EventKind.BREAKPOINT) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                long loc = r.ReadLong ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
                                                                //EventHandler.Breakpoint (req_id, thread_id, id, loc);
                                                        } else if (kind == EventKind.STEP) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                long loc = r.ReadLong ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
                                                                //EventHandler.Step (req_id, thread_id, id, loc);
                                                        } else if (kind == EventKind.EXCEPTION) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                long loc = 0; // FIXME
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
                                                                //EventHandler.Exception (req_id, thread_id, id, loc);
                                                        } else if (kind == EventKind.APPDOMAIN_CREATE) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.AppDomainCreate (req_id, thread_id, id);
                                                        } else if (kind == EventKind.APPDOMAIN_UNLOAD) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = r.ReadId ();
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
                                                                //EventHandler.AppDomainUnload (req_id, thread_id, id);
                                                        } else if (kind == EventKind.USER_BREAK) {
-                                                               long thread_id = r.ReadId ();
                                                                long id = 0;
                                                                long loc = 0;
                                                                events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
                                                                //EventHandler.Exception (req_id, thread_id, id, loc);
                                                        } else if (kind == EventKind.USER_LOG) {
-                                                               long thread_id = r.ReadId ();
                                                                int level = r.ReadInt ();
                                                                string category = r.ReadString ();
                                                                string message = r.ReadString ();
index cb3c79231ba09ac0e7e587775c0238da4443e4bf..035fbcee56df096c804a3b8de2989ca9db83a9d8 100644 (file)
@@ -23,7 +23,11 @@ namespace Mono.Debugger.Soft
                StaticCtor = 1,
                /* Since protocol version 2.20 */
                /* Methods which have the [DebuggerHidden] attribute */
+               /* Before protocol version 2.26, this includes [DebuggerStepThrough] as well */
                DebuggerHidden = 2,
+               /* Since protocol version 2.26 */
+               /* Methods which have the [DebuggerStepThrough] attribute */
+               DebuggerStepThrough = 4,
        }
 
        public sealed class StepEventRequest : EventRequest {
index 3cd1edeadf4148e37ab81088f1bc360bef996fb9..125d780fd0e59a06240e7e45dc9ba7fa3bbd4bc9 100644 (file)
@@ -26,6 +26,7 @@ namespace Mono.Debugger.Soft
                TypeMirror[] ifaces;
                Dictionary<TypeMirror, InterfaceMappingMirror> iface_map;
                TypeMirror[] type_args;
+               bool cached_base_type;
                bool inited;
 
                internal const BindingFlags DefaultBindingFlags =
@@ -78,9 +79,9 @@ namespace Mono.Debugger.Soft
 
                public TypeMirror BaseType {
                        get {
-                               // FIXME: base_type could be null for object/interfaces
-                               if (base_type == null) {
+                               if (!cached_base_type) {
                                        base_type = vm.GetType (GetInfo ().base_type);
+                                       cached_base_type = true;
                                }
                                return base_type;
                        }
@@ -591,11 +592,11 @@ namespace Mono.Debugger.Soft
 
                string[] source_files;
                string[] source_files_full_path;
-               public string[] GetSourceFiles (bool return_full_paths) {
-                       string[] res = return_full_paths ? source_files_full_path : source_files;
+               public string[] GetSourceFiles (bool returnFullPaths) {
+                       string[] res = returnFullPaths ? source_files_full_path : source_files;
                        if (res == null) {
-                               res = vm.conn.Type_GetSourceFiles (id, return_full_paths);
-                               if (return_full_paths)
+                               res = vm.conn.Type_GetSourceFiles (id, returnFullPaths);
+                               if (returnFullPaths)
                                        source_files_full_path = res;
                                else
                                        source_files = res;
@@ -684,29 +685,38 @@ namespace Mono.Debugger.Soft
                 * used by the reflection-only functionality on .net.
                 */
                public CustomAttributeDataMirror[] GetCustomAttributes (bool inherit) {
-                       return GetCAttrs (null, inherit);
+                       return GetCustomAttrs (null, inherit);
                }
 
                public CustomAttributeDataMirror[] GetCustomAttributes (TypeMirror attributeType, bool inherit) {
                        if (attributeType == null)
                                throw new ArgumentNullException ("attributeType");
-                       return GetCAttrs (attributeType, inherit);
+                       return GetCustomAttrs (attributeType, inherit);
                }
 
-               CustomAttributeDataMirror[] GetCAttrs (TypeMirror type, bool inherit) {
+               void AppendCustomAttrs (IList<CustomAttributeDataMirror> attrs, TypeMirror type, bool inherit)
+               {
                        if (cattrs == null && Metadata != null && !Metadata.HasCustomAttributes)
                                cattrs = new CustomAttributeDataMirror [0];
 
-                       // FIXME: Handle inherit
                        if (cattrs == null) {
                                CattrInfo[] info = vm.conn.Type_GetCustomAttributes (id, 0, false);
                                cattrs = CustomAttributeDataMirror.Create (vm, info);
                        }
-                       var res = new List<CustomAttributeDataMirror> ();
-                       foreach (var attr in cattrs)
+
+                       foreach (var attr in cattrs) {
                                if (type == null || attr.Constructor.DeclaringType == type)
-                                       res.Add (attr);
-                       return res.ToArray ();
+                                       attrs.Add (attr);
+                       }
+
+                       if (inherit && BaseType != null)
+                               BaseType.AppendCustomAttrs (attrs, type, inherit);
+               }
+
+               CustomAttributeDataMirror[] GetCustomAttrs (TypeMirror type, bool inherit) {
+                       var attrs = new List<CustomAttributeDataMirror> ();
+                       AppendCustomAttrs (attrs, type, inherit);
+                       return attrs.ToArray ();
                }
 
                public MethodMirror[] GetMethodsByNameFlags (string name, BindingFlags flags, bool ignoreCase) {
index 18eeb92ca74f0af1f4b32907f444c7617ca9ed22..40e60ad091bd53914ff52c41e86f469a523721be 100644 (file)
@@ -4,7 +4,18 @@ namespace Mono.Debugger.Soft
 {
        public class VMDeathEvent : Event
        {
-               public VMDeathEvent (VirtualMachine vm, int req_id) : base (EventType.VMDeath, vm, req_id, -1) {
+               int exit_code;
+
+               public VMDeathEvent (VirtualMachine vm, int req_id, int exit_code) : base (EventType.VMDeath, vm, req_id, -1) {
+                       this.exit_code = exit_code;
+               }
+
+               // Since protocol version 2.27
+               public int ExitCode {
+                       get {
+                               vm.CheckProtocolVersion (2, 27);
+                               return exit_code;
+                       }
                }
     }
 }
index b77458b44110eeee8ce8ee64e36dcf4b2d5011f3..ce4c285015ab48f8d2f0c0fdde2df7fb765ea3fa 100644 (file)
@@ -137,7 +137,7 @@ namespace Mono.Debugger.Soft
                public void Detach () {
                        conn.VM_Dispose ();
                        conn.Close ();
-                       notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null);
+                       notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, 0, 0, null, 0);
                }
 
                [Obsolete ("This method was poorly named; use the Detach() method instead")]
@@ -315,7 +315,7 @@ namespace Mono.Debugger.Soft
                        root_domain = GetDomain (root_domain_id);
                }
 
-               internal void notify_vm_event (EventType evtype, SuspendPolicy spolicy, int req_id, long thread_id, string vm_uri) {
+               internal void notify_vm_event (EventType evtype, SuspendPolicy spolicy, int req_id, long thread_id, string vm_uri, int exit_code) {
                        //Console.WriteLine ("Event: " + evtype + "(" + vm_uri + ")");
 
                        switch (evtype) {
@@ -327,7 +327,7 @@ namespace Mono.Debugger.Soft
                                queue_event_set (new EventSet (this, spolicy, new Event[] { new VMStartEvent (vm, req_id, thread_id) }));
                                break;
                        case EventType.VMDeath:
-                               queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDeathEvent (vm, req_id) }));
+                               queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDeathEvent (vm, req_id, exit_code) }));
                                break;
                        case EventType.VMDisconnect:
                                queue_event_set (new EventSet (this, spolicy, new Event[] { new VMDisconnectEvent (vm, req_id) }));
@@ -620,10 +620,10 @@ namespace Mono.Debugger.Soft
 
                                switch (ei.EventType) {
                                case EventType.VMStart:
-                                       vm.notify_vm_event (EventType.VMStart, suspend_policy, req_id, thread_id, null);
+                                       vm.notify_vm_event (EventType.VMStart, suspend_policy, req_id, thread_id, null, 0);
                                        break;
                                case EventType.VMDeath:
-                                       vm.notify_vm_event (EventType.VMDeath, suspend_policy, req_id, thread_id, null);
+                                       vm.notify_vm_event (EventType.VMDeath, suspend_policy, req_id, thread_id, null, ei.ExitCode);
                                        break;
                                case EventType.ThreadStart:
                                        l.Add (new ThreadStartEvent (vm, req_id, id));
@@ -677,7 +677,7 @@ namespace Mono.Debugger.Soft
                }
 
                public void VMDisconnect (int req_id, long thread_id, string vm_uri) {
-                       vm.notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, req_id, thread_id, vm_uri);
+                       vm.notify_vm_event (EventType.VMDisconnect, SuspendPolicy.None, req_id, thread_id, vm_uri, 0);
         }
     }
 
index 09316643a8ddc0a4a8b92ea546276312b9791a19..dc4be1371e6eda1e3d9d794365fa95d1ff0671c9 100644 (file)
@@ -359,6 +359,8 @@ public class Tests : TestsBase, ITest2
                ss7 ();
                ss_nested ();
                ss_regress_654694 ();
+               ss_step_through ();
+               ss_recursive (1);
        }
 
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
@@ -452,6 +454,37 @@ public class Tests : TestsBase, ITest2
        public static void ss_nested_3 () {
        }
 
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void ss_step_through () {
+               step_through_1 ();
+               StepThroughClass.step_through_2 ();
+               step_through_3 ();
+       }
+
+       [DebuggerStepThrough]
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void step_through_1 () {
+       }
+
+       [DebuggerStepThrough]
+       class StepThroughClass {
+               [MethodImplAttribute (MethodImplOptions.NoInlining)]
+               public static void step_through_2 () {
+               }
+       }
+
+       [DebuggerStepThrough]
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void step_through_3 () {
+       }
+
+       [MethodImplAttribute (MethodImplOptions.NoInlining)]
+       public static void ss_recursive (int n) {
+               if (n == 10)
+                       return;
+               ss_recursive (n + 1);
+       }
+
        [MethodImplAttribute (MethodImplOptions.NoInlining)]
        public static bool is_even (int i) {
                return i % 2 == 0;
index f04385add38397d31187e0d89de4eb395eed31b3..2b8982b2f1668241c26e27f59bf1a750b6eb726d 100644 (file)
@@ -517,13 +517,42 @@ public class DebuggerTests
                e = step_into ();
                assert_location (e, "ss_nested_1");
                e = step_out ();
-               Console.WriteLine ("A: " + e.Thread.GetFrames ()[0].Location);
                assert_location (e, "ss_nested");
                // Check that step over steps over nested calls
                e = step_over ();
                assert_location (e, "ss_nested");
                e = step_into ();
                assert_location (e, "ss_nested_3");
+               req.Disable ();
+
+               // Check DebuggerStepThrough support
+               e = run_until ("ss_step_through");
+               req = create_step (e);
+               req.Filter = StepFilter.DebuggerStepThrough;
+               e = step_into ();
+               // Step through step_through_1 ()
+               e = step_into ();
+               assert_location (e, "ss_step_through");
+               // Step through StepThroughClass.step_through_2 ()
+               e = step_into ();
+               assert_location (e, "ss_step_through");
+               req.Disable ();
+               req.Filter = StepFilter.None;
+               e = step_into ();
+               assert_location (e, "step_through_3");
+               req.Disable ();
+
+               // Check that step-over doesn't stop at inner frames with recursive functions
+               e = run_until ("ss_recursive");
+               req = create_step (e);
+               e = step_over ();
+               e = step_over ();
+               e = step_over ();
+               var f = e.Thread.GetFrames () [0];
+               assert_location (e, "ss_recursive");
+               AssertValue (1, f.GetValue (f.Method.GetLocal ("n")));
+
+               req.Disable ();
        }
 
        [Test]
@@ -1103,7 +1132,7 @@ public class DebuggerTests
                t = frame.Method.GetParameters ()[8].ParameterType;
                Assert.AreEqual ("Tests2", t.Name);
                var attrs = t.GetCustomAttributes (true);
-               Assert.AreEqual (3, attrs.Length);
+               Assert.AreEqual (5, attrs.Length);
                foreach (var attr in attrs) {
                        if (attr.Constructor.DeclaringType.Name == "DebuggerDisplayAttribute") {
                                Assert.AreEqual (1, attr.ConstructorArguments.Count);
@@ -1122,6 +1151,12 @@ public class DebuggerTests
                                Assert.AreEqual (2, attr.NamedArguments.Count);
                                Assert.AreEqual ("afield", attr.NamedArguments [0].Field.Name);
                                Assert.AreEqual ("bfield", attr.NamedArguments [1].Field.Name);
+                       } else if (attr.Constructor.DeclaringType.Name == "ClassInterfaceAttribute") {
+                               // inherited from System.Object
+                               //} else if (attr.Constructor.DeclaringType.Name == "Serializable") {
+                               // inherited from System.Object
+                       } else if (attr.Constructor.DeclaringType.Name == "ComVisibleAttribute") {
+                               // inherited from System.Object
                        } else {
                                Assert.Fail (attr.Constructor.DeclaringType.Name);
                        }
@@ -1666,6 +1701,8 @@ public class DebuggerTests
                var e = GetNextEvent ();
                Assert.IsInstanceOfType (typeof (VMDeathEvent), e);
 
+               Assert.AreEqual (5, (e as VMDeathEvent).ExitCode);
+
                var p = vm.Process;
                /* Could be a remote vm with no process */
                if (p != null) {
index 5af7fe0f387f9b18f0e788d613eb3f29084c7a43..0fd21ab5a93e47bb56286dff21edd86d17171242 100644 (file)
@@ -1135,7 +1135,7 @@ namespace Mono.Options
                                        if (i == 0)
                                                return false;
                                        throw new OptionException (string.Format (localizer (
-                                                                       "Cannot bundle unregistered option '{0}'."), opt), opt);
+                                                                       "Cannot use unregistered option '{0}' in bundle '{1}'."), rn, f + n), null);
                                }
                                p = this [rn];
                                switch (p.OptionValueType) {
index 666bad54d5b8d90f021a32011c1b3c8f4eab3c0e..086c6d9c8c24a6f76a4463ea00e16881c9d8daf7 100644 (file)
@@ -193,7 +193,7 @@ namespace Tests.Mono.Options
                        Assert.AreEqual (libs [1], null);
 
                        Utils.AssertException (typeof(OptionException), 
-                                       "Cannot bundle unregistered option '-V'.",
+                                       "Cannot use unregistered option 'V' in bundle '-EVALUENOTSUP'.",
                                        p, v => { v.Parse (_("-EVALUENOTSUP")); });
                }
 
@@ -370,7 +370,7 @@ namespace Tests.Mono.Options
 
                        // try to bundle with an option requiring a value
                        Utils.AssertException (typeof(OptionException), 
-                                       "Cannot bundle unregistered option '-z'.", 
+                                       "Cannot use unregistered option 'z' in bundle '-cz'.",
                                        p, v => { v.Parse (_("-cz", "extra")); });
 
                        Utils.AssertException (typeof(ArgumentNullException), 
@@ -880,6 +880,22 @@ namespace Tests.Mono.Options
                        Assert.AreEqual (formats ["baz"][0], "e");
                        Assert.AreEqual (formats ["baz"][1], "f");
                }
+
+               [Test]
+               public void ReportInvalidDuplication ()
+               {
+                       int verbosity = 0;
+                       var p = new OptionSet () {
+                               { "v", v => verbosity = v != null ? verbosity + 1 : verbosity },
+                       };
+                       try {
+                               p.Parse (new []{"-v-v-v"});
+                               Assert.Fail ("Should not be reached.");
+                       } catch (OptionException e) {
+                               Assert.AreEqual (null, e.OptionName);
+                               Assert.AreEqual ("Cannot use unregistered option '-' in bundle '-v-v-v'.", e.Message);
+                       }
+               }
        }
 }
 
index ce259c0739bc97e5e8dea133a3a97be6aba199b8..46672255e04174e3e5d7a4fcaa057c17b3588dcd 100644 (file)
@@ -753,9 +753,9 @@ namespace PEAPI {
                        return modRef;
                }
 
-               public ClassRef AddExternClass(string name, TypeAttr attrs, MetaDataElement declRef) 
+               public ClassRef AddExternClass(string ns, string name, TypeAttr attrs, MetaDataElement declRef)
                {
-                       return new ExternClassRef (attrs, null, name, declRef, metaData);
+                       return new ExternClassRef (attrs, ns, name, declRef, metaData);
                }
                
                /// <summary>
index f1d24d7b957aa36de02867228e8a8a0812085673..938f4e8fbcbc7860c1b13e912d558f0cf4d06495 100644 (file)
@@ -18,7 +18,6 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
     [TestFixture]
     public class FilterUIHintAttributeTest {
         [Test]
-        [Description("Simple ctors set expected properties.")]
         public void FilterUIHintAttribute_Simple_Ctors_Set_Properties() {
             var attr = new FilterUIHintAttribute(null, null);
             Assert.IsNull(attr.FilterUIHint);
index d0329f7e2c880b8e824aea45249969d9cc3f36c1..a6c99a3ba2b78e33d7d0436392c1dd37804729e6 100644 (file)
@@ -18,7 +18,6 @@ namespace MonoTests.System.ComponentModel.DataAnnotations
     [TestFixture]
     public class UIHintAttributeTest {
         [Test]
-        [Description("Simple ctors set expected properties.")]
         public void UIHintAttribute_Simple_Ctors_Set_Properties() {
             var attr = new UIHintAttribute(null, null);
             Assert.IsNull(attr.UIHint);
index 613d0c10df54948e6d165cb5ef7ba9cd0b5f7c92..1efa2b99eb2b0e32a88ad5d498d8d3be166e15f2 100644 (file)
@@ -37,6 +37,7 @@ using System.IO;
 using NUnit.Framework;
 using SysConfig = System.Configuration.Configuration;
 using System.Runtime.InteropServices;
+using System.Reflection;
 
 namespace MonoTests.System.Configuration {
        using Util;
@@ -616,6 +617,11 @@ namespace MonoTests.System.Configuration {
                [Test]
                public void TestConnectionStringRetrieval ()
                {
+                       var currentAssembly = Assembly.GetExecutingAssembly().Location;
+                       Assert.IsTrue (File.Exists (currentAssembly + ".config"),
+                                      String.Format ("This test cannot succeed without the .config file being in the same place as the assembly ({0})",
+                                                     currentAssembly));
+
                        var connStringObj = ConfigurationManager.ConnectionStrings ["test-connstring"];
                        Assert.IsNotNull (connStringObj);
                        var connString = connStringObj.ConnectionString;
diff --git a/mcs/class/System.Core/System.Linq.Expressions/DynamicExpressionVisitor.cs b/mcs/class/System.Core/System.Linq.Expressions/DynamicExpressionVisitor.cs
new file mode 100644 (file)
index 0000000..d83e62f
--- /dev/null
@@ -0,0 +1,38 @@
+//
+// DynamicExpressionVisitor.cs
+//
+// Authors:
+//    Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright 2013 Xamarin Inc (http://www.xamarin.com).
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+//
+//
+
+#if NET_4_5
+
+namespace System.Linq.Expressions
+{
+       public abstract class DynamicExpressionVisitor : ExpressionVisitor
+       {
+       }
+}
+
+#endif
index 4c8717396860e0358477aa06a8c077bc75bdcb30..9685771de92337bbd0ac565daa48f556ef489aa2 100644 (file)
@@ -270,7 +270,7 @@ namespace System.Linq.Expressions {
                                        if (ltype == rtype && ultype.IsEnum)
                                                return null;
 
-                                       if (ltype == rtype && ultype == typeof (bool))
+                                       if (ltype == rtype && (ultype == typeof (bool) || ultype == typeof (char)))
                                                return null;
 
                                        if (ltype.IsNullable () && ConstantExpression.IsNull (right) && !ConstantExpression.IsNull (left))
index 71f392690a47666dc15496f0ffbcca58fe56dae7..23805636c6b6236d00dc7b20fce0feeb83ffd659 100644 (file)
@@ -744,6 +744,12 @@ namespace System.Linq
                        if (list != null)
                                return list [index];
 
+#if NET_4_5
+                       var readOnlyList = source as IReadOnlyList<TSource>;
+                       if (readOnlyList != null)
+                               return readOnlyList[index];
+#endif
+
                        return source.ElementAt (index, Fallback.Throw);
                }
 
@@ -762,6 +768,12 @@ namespace System.Linq
                        if (list != null)
                                return index < list.Count ? list [index] : default (TSource);
 
+#if NET_4_5
+                       var readOnlyList = source as IReadOnlyList<TSource>;
+                       if (readOnlyList != null)
+                               return index < readOnlyList.Count ? readOnlyList [index] : default (TSource);
+#endif
+
                        return source.ElementAt (index, Fallback.Default);
                }
 
@@ -1099,7 +1111,7 @@ namespace System.Linq
 
                        foreach (TOuter element in outer) {
                                TKey outerKey = outerKeySelector (element);
-                               if (innerKeys.Contains (outerKey))
+                               if (outerKey != null && innerKeys.Contains (outerKey))
                                        yield return resultSelector (element, innerKeys [outerKey]);
                                else
                                        yield return resultSelector (element, Empty<TInner> ());
@@ -1166,7 +1178,7 @@ namespace System.Linq
 
                        foreach (TOuter element in outer) {
                                TKey outerKey = outerKeySelector (element);
-                               if (innerKeys.Contains (outerKey)) {
+                               if (outerKey != null && innerKeys.Contains (outerKey)) {
                                        foreach (TInner innerElement in innerKeys [outerKey])
                                                yield return resultSelector (element, innerElement);
                                }
index a21edd6c93ee74a1f66de8d7b9fa5cf91d3fa983..aa2ae29974894366959757bf8998765aa8fc8476 100644 (file)
@@ -346,7 +346,7 @@ namespace System {
 
                        static void Fill (Stream stream, byte[] nbuf, int required)
                        {
-                               int read, offset = 0;
+                               int read = 0, offset = 0;
                                while (offset < required && (read = stream.Read (nbuf, offset, required - offset)) > 0)
                                        offset += read;
                                if (read != required)
index 749d78e40f8dcec109c137a286ebb06c09054468..be7e129d895e25738056d99896c3727327a1c985 100644 (file)
@@ -81,6 +81,18 @@ namespace MonoTests.System.Linq.Expressions
 #endif
                }
 
+               [Test]
+               public void PrimitiveNonNumeric ()
+               {
+                       BinaryExpression expr = Expression.Equal (Expression.Constant ('a'), Expression.Constant ('b'));
+                       Assert.AreEqual (ExpressionType.Equal, expr.NodeType);
+                       Assert.AreEqual (typeof (bool), expr.Type);
+                       Assert.IsNull (expr.Method);
+
+                       var eq = Expression.Lambda<Func<bool>> (expr).Compile ();
+                       Assert.IsFalse (eq ());
+               }
+
                [Test]
                public void Nullable_LiftToNull_SetToFalse ()
                {
index d98eea6446727c83b0198e0658aae0d0a2b09742..1045c8521b986d35d351ff9f383b2f5763660d7d 100644 (file)
@@ -28,6 +28,7 @@
 using System;
 using System.Collections;
 using System.Collections.Generic;
+using System.Collections.ObjectModel;
 using System.Globalization;
 using System.Text;
 using System.Threading;
@@ -539,6 +540,13 @@ namespace MonoTests.System.Linq
                        Assert.That (source.ElementAt (2), Is.EqualTo (3));
                }
 
+               [Test]
+               public void ElementAt_ReadOnlyListOptimization_ReturnsValueAtGivenIndex()
+               {
+                       var source = new NonEnumerableReadOnlyList<int> (new List<int> (new[] { 1, 2, 3, 4, 5, 6 }));
+                       Assert.That(source.ElementAt (2), Is.EqualTo (3));
+               }
+
                [Test]
                public void ElementAtOrDefault_IntegersWithOutOfRangeIndex_ReturnsDefault ()
                {
@@ -560,6 +568,13 @@ namespace MonoTests.System.Linq
                        Assert.That (source.ElementAtOrDefault (2), Is.EqualTo (3));
                }
 
+               [Test]
+               public void ElementAtOrDefault_ReadOnlyListOptimization_ReturnsValueAtGivenIndex()
+               {
+                       var source = new NonEnumerableReadOnlyList<int>(new List<int> (new[] { 1, 2, 3, 4, 5, 6 }));
+                       Assert.That(source.ElementAtOrDefault (2), Is.EqualTo (3));
+               }
+
                [Test]
                public void ElementAtOrDefault_BooleansAndNegativeIndex_ReturnsDefault ()
                {
@@ -2188,6 +2203,27 @@ namespace MonoTests.System.Linq
                }
        }
 
+       [Serializable]
+       internal sealed class NonEnumerableReadOnlyList<T> : ReadOnlyCollection<T>, IEnumerable<T> {
+               public NonEnumerableReadOnlyList () : 
+                       this (new List<T>()) { }
+
+               public NonEnumerableReadOnlyList (IList<T> collection) :
+                       base (collection) { }
+
+               // Re-implement GetEnumerator to be undefined.
+
+               IEnumerator<T> IEnumerable<T>.GetEnumerator ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               IEnumerator IEnumerable.GetEnumerator()
+               {
+                       return ((IEnumerable<T>) this).GetEnumerator();
+               }
+       }
+
     internal sealed class Reader<T> : IEnumerable<T>, IEnumerator<T>
     {
         public event EventHandler Disposed;
index f5559ae00ea98c4d6b1ced3571c68675e2efaf60..1cf514c7aab2be8561e47bf776e30175b6f5a33e 100644 (file)
@@ -1553,6 +1553,18 @@ namespace MonoTests.System.Linq {
                        AssertAreSame (expected2, dataOuter2.Join (dataInner2, x => x, x => x, (x, y) => x + y, EqualityComparer<string>.Default));
                }
 
+               [Test]
+               public void JoinTestNullKeys ()
+               {
+                       var l1 = new [] {
+                               new { Name = "name1", Nullable = (int?) null },
+                               new { Name = "name2", Nullable = (int?) null }
+                       };
+
+                       var count = l1.Join (l1, i => i.Nullable, i => i.Nullable, (x, y) => x.Name).Count ();
+                       Assert.AreEqual (0, count);
+               }
+
                [Test]
                public void GroupJoinArgumentNullTest ()
                {
@@ -1595,6 +1607,16 @@ namespace MonoTests.System.Linq {
                        AssertAreSame (expected2, dataOuter2.GroupJoin (dataInner2, x => x, x => x, (x, y) => { foreach (var s in y) x += s; return x; }, EqualityComparer<string>.Default));
                }
 
+               [Test]
+               public void GroupJoinWithNullKeys ()
+               {
+                       string[] l1 = { null };
+                       string[] l2 = { null, null };
+                       var res = l1.GroupJoin (l2, x => x, y => y, (a, b) => new { Key = a, Count = b.Count () }).ToArray ();
+                       Assert.AreEqual (1, res.Length);
+                       Assert.AreEqual (0, res [0].Count);
+               }
+
                [Test]
                public void OrderByArgumentNullTest ()
                {
index 83eaf84606829a86a0991e3d85156f91c5a6ec64..bd54b1997605d5c0008ef82808f5b21869660b9e 100644 (file)
@@ -125,3 +125,4 @@ System.Runtime.CompilerServices/ExecutionScope.cs
 System.Runtime.CompilerServices/DynamicAttribute.cs
 System.Linq.Expressions/ExpressionTransformer.cs
 System.Linq.Expressions/Extensions.cs
+System.Linq.Expressions/DynamicExpressionVisitor.cs
index 4d4f48c85380b74f19e87aa13e47029d7ad8f257..cd2aed8b93215987a6f4af1611ea6bd856974555 100644 (file)
@@ -1,3 +1,4 @@
 #include net_4_0_System.Core.dll.sources
 
 ../dlr/Runtime/Microsoft.Scripting.Core/Ast/DynamicExpression.cs
+System.Linq.Expressions/DynamicExpressionVisitor.cs
index b0962359876ee29436e75ccbf9974bb4459915db..bc10888037b7462ef2483bf8c31c884a4724b9d0 100644 (file)
@@ -846,7 +846,7 @@ namespace System.Data.SqlClient {
                                        if (keyInfo || schemaOnly)
                                                epilog = sql2.ToString ();
                                        try {
-                                               Connection.Tds.BeginExecuteProcedure (prolog,
+                                               ar = Connection.Tds.BeginExecuteProcedure (prolog,
                                                                                      epilog,
                                                                                      CommandText,
                                                                                      !wantResults,
index 6bdec491069f590577fa95a9f6277f8e1a6be42b..05038a11360b1e150422caa6247be4ce56efaed9 100644 (file)
@@ -635,8 +635,8 @@ namespace MonoTests.System.Drawing{
         [Test]
         public void GetHashCode_UnitDiffers_HashesNotEqual()
         {
-            Font f1 = new Font("DejaVu Sans", 8.25F, GraphicsUnit.Point);
-            Font f2 = new Font("DejaVu Sans", 8.25F, GraphicsUnit.Pixel);
+            Font f1 = new Font("Arial", 8.25F, GraphicsUnit.Point);
+            Font f2 = new Font("Arial", 8.25F, GraphicsUnit.Pixel);
 
             Assert.IsFalse(f1.GetHashCode() == f2.GetHashCode(),
                 "Hashcodes should differ if _unit member differs");
@@ -645,8 +645,8 @@ namespace MonoTests.System.Drawing{
         [Test]
         public void GetHashCode_NameDiffers_HashesNotEqual()
         {
-            Font f1 = new Font("DejaVu Sans", 8.25F, GraphicsUnit.Point);
-            Font f2 = new Font("Liberation Sans", 8.25F, GraphicsUnit.Point);
+            Font f1 = new Font("Arial", 8.25F, GraphicsUnit.Point);
+            Font f2 = new Font("Courier New", 8.25F, GraphicsUnit.Point);
 
             Assert.IsFalse(f1.GetHashCode() == f2.GetHashCode(),
                 "Hashcodes should differ if _name member differs");
@@ -655,8 +655,8 @@ namespace MonoTests.System.Drawing{
         [Test]
         public void GetHashCode_StyleEqualsGdiCharSet_HashesNotEqual()
         {
-            Font f1 = new Font("DejaVu Sans", 8.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
-            Font f2 = new Font("DejaVu Sans", 8.25F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(1)));
+            Font f1 = new Font("Arial", 8.25F, FontStyle.Regular, GraphicsUnit.Point, ((byte)(0)));
+            Font f2 = new Font("Arial", 8.25F, FontStyle.Bold, GraphicsUnit.Point, ((byte)(1)));
 
             Assert.IsFalse(f1.GetHashCode() == f2.GetHashCode(),
                 "Hashcodes should differ if _style member differs");
index 1dc3affa328f0afd1539881113a9d0b1e1adc6a0..a36652ce4eb4e3379bd626abd17c3473056a6b2c 100644 (file)
@@ -231,16 +231,9 @@ namespace System.Net.Http.Headers
                        if (values == null)
                                throw new ArgumentNullException ("values");
 
-                       if (string.IsNullOrEmpty (name))
-                               return false;
-
-                       Parser.Token.Check (name);
-
                        HeaderInfo headerInfo;
-                       if (known_headers.TryGetValue (name, out headerInfo) && (headerInfo.HeaderKind & HeaderKind) == 0) {
-                               if (HeaderKind != HttpHeaderKind.None && ((HeaderKind | headerInfo.HeaderKind) & HttpHeaderKind.Content) != 0)
-                                       return false;
-                       }
+                       if (!TryCheckName (name, out headerInfo))
+                               return false;
 
                        AddInternal (name, values, null, true);
                        return true;
@@ -264,6 +257,21 @@ namespace System.Net.Http.Headers
                        return headerInfo;
                }
 
+               bool TryCheckName (string name, out HeaderInfo headerInfo)
+               {
+                       if (!Parser.Token.TryCheck (name)) {
+                               headerInfo = null;
+                               return false;
+                       }
+
+                       if (known_headers.TryGetValue (name, out headerInfo) && (headerInfo.HeaderKind & HeaderKind) == 0) {
+                               if (HeaderKind != HttpHeaderKind.None && ((HeaderKind | headerInfo.HeaderKind) & HttpHeaderKind.Content) != 0)
+                                       return false;
+                       }
+
+                       return true;
+               }
+
                public void Clear ()
                {
                        connectionclose = null;
@@ -301,6 +309,8 @@ namespace System.Net.Http.Headers
 
                public IEnumerable<string> GetValues (string name)
                {
+                       CheckName (name);
+
                        IEnumerable<string> values;
                        if (!TryGetValues (name, out values))
                                throw new InvalidOperationException ();
@@ -316,7 +326,11 @@ namespace System.Net.Http.Headers
 
                public bool TryGetValues (string name, out IEnumerable<string> values)
                {
-                       var header_info = CheckName (name);
+                       HeaderInfo headerInfo;
+                       if (!TryCheckName (name, out headerInfo)) {
+                               values = null;
+                               return false;
+                       }
 
                        HeaderBucket bucket;
                        if (!headers.TryGetValue (name, out bucket)) {
@@ -324,7 +338,7 @@ namespace System.Net.Http.Headers
                                return false;
                        }
 
-                       values = GetAllHeaderValues (bucket, header_info);
+                       values = GetAllHeaderValues (bucket, headerInfo);
                        return true;
                }
 
index cdf73d3a78e6a822f8e57791d84656d96de91a19..a6d80d7375bd243df2677742d25ef36e9c5bf7fa 100644 (file)
@@ -64,14 +64,7 @@ namespace System.Net.Http.Headers
                                if (s == null)
                                        return false;
 
-                               if (!Lexer.IsValidToken (s)) {
-                                       if (s.Length == 0)
-                                               return false;
-
-                                       return false;
-                               }
-
-                               return true;
+                               return Lexer.IsValidToken (s);
                        }
 
                        public static void CheckQuotedString (string s)
index a4b255516074d7614526961adbc87a15909679d9..cae4a65c82aacac1a726114b49646776d995fbd4 100644 (file)
@@ -130,6 +130,14 @@ namespace MonoTests.System.Net.Http.Headers
                        }
                }
 
+               [Test]
+               public void TryGetValuesTest ()
+               {
+                       IEnumerable<string> headerValues;
+                       Assert.IsFalse (headers.TryGetValues (null, out headerValues), "#1");
+                       Assert.IsFalse (headers.TryGetValues ("some-name", out headerValues), "#2");
+               }
+
                [Test]
                public void ToStringTest ()
                {
index 816ca2ffceeb3a6a250e8b1f682e77919a3f658d..a05d403988bf87e95298ae18060194a7c037208b 100644 (file)
@@ -473,10 +473,20 @@ namespace System.Numerics {
                                return (((long)high) << 32) | low;
                        }
 
-                       if (high > 0x80000000u)
+                       /*
+                       We cannot represent negative numbers smaller than long.MinValue.
+                       Those values are encoded into what look negative numbers, so negating
+                       them produces a positive value, that's why it's safe to check for that
+                       condition.
+
+                       long.MinValue works fine since it's bigint encoding looks like a negative
+                       number, but since long.MinValue == -long.MinValue, we're good.
+                       */
+
+                       long result = - ((((long)high) << 32) | (long)low);
+                       if (result > 0)
                                throw new OverflowException ();
-
-                       return - ((((long)high) << 32) | (long)low);
+                       return result;
                }
 
                [CLSCompliantAttribute (false)]
index 098c50854b78f1be97ebd61df42710541e7ccbbc..a5ec016bb3ee37ce9b16e17e566b0ff36772416f 100644 (file)
@@ -1145,5 +1145,19 @@ namespace MonoTests.System.Numerics
                        a = new BigInteger ();
                        Assert.AreEqual (BigInteger.Zero.GetHashCode (), a.GetHashCode (), "#15");
                }
+
+               [Test]
+               public void Bug16526 ()
+               {
+                       var x = BigInteger.Pow(2, 63);
+                       x *= -1;
+                       x -= 1;
+                       Assert.AreEqual ("-9223372036854775809", x.ToString (), "#1");
+                       try {
+                               x = (long)x;
+                               Assert.Fail ("#2 Must OVF");
+                       } catch (OverflowException) {
+                       }
+               }
        }
 }
index e27b8db60f4d8a2871adbf6c02cc4cac8fa8be10..4be97a8140da3cf91ab6bf36f2073b88c8da9915 100644 (file)
@@ -13,7 +13,6 @@
 // 
 
 using System;
-using System.ComponentModel;
 using System.Globalization;
 using System.IO;
 using System.Xml;
@@ -1546,7 +1545,6 @@ namespace MonoTests.System.XmlSerialization
                }
 
 
-#if NET_2_0
                [Test]
                public void TestFromEnum_Null_TypeName ()
                {
@@ -1566,7 +1564,6 @@ namespace MonoTests.System.XmlSerialization
                        Assert.IsTrue (ex.Message.IndexOf ("AnInvalidValue") != -1, "#4");
                        Assert.IsTrue (ex.Message.IndexOf ("SomeType") != -1, "#5");
                }
-#endif
 
                [Test]
                public void WriteCharacter ()
@@ -1581,7 +1578,7 @@ namespace MonoTests.System.XmlSerialization
                [Serializable]
                public class ToBeSerialized
                {
-                       [DefaultValue ('a')]
+                       [global::System.ComponentModel.DefaultValue ('a')]
                        public char character = '\'';
                }
 
index 5b4cbfcf1af6aaf3d4e86dc47dc0fa24ee0a28ee..cd063347c6c3405148f7040cd17417cc85c2ac35 100644 (file)
@@ -65,6 +65,7 @@ namespace System.Collections.Concurrent
                        int index;
                        CyclicDeque<T> bag = GetBag (out index);
                        bag.PushBottom (item);
+                       staging.TryAdd (index, bag);
                        AddHint (index);
                        Interlocked.Increment (ref count);
                }
@@ -88,6 +89,7 @@ namespace System.Collections.Concurrent
                        
                        if (bag == null || bag.PopBottom (out result) != PopResult.Succeed) {
                                var self = bag;
+                               ret = false;
                                foreach (var other in staging) {
                                        // Try to retrieve something based on a hint
                                        ret = TryGetHint (out hintIndex) && (bag = container[hintIndex]).PopTop (out result) == PopResult.Succeed;
@@ -129,6 +131,7 @@ namespace System.Collections.Concurrent
 
                        if (bag == null || !bag.PeekBottom (out result)) {
                                var self = bag;
+                               ret = false;
                                foreach (var other in staging) {
                                        // Try to retrieve something based on a hint
                                        ret = TryGetHint (out hintIndex) && container[hintIndex].PeekTop (out result);
@@ -264,10 +267,7 @@ namespace System.Collections.Concurrent
                        if (container.TryGetValue (index, out value))
                                return value;
 
-                       var bag = createBag ? container.GetOrAdd (index, new CyclicDeque<T> ()) : null;
-                       if (bag != null)
-                               staging.TryAdd (index, bag);
-                       return bag;
+                       return createBag ? container.GetOrAdd (index, new CyclicDeque<T> ()) : null;
                }
 
                void TidyBag (int index, CyclicDeque<T> bag)
@@ -279,4 +279,4 @@ namespace System.Collections.Concurrent
                }
        }
 }
-#endif
\ No newline at end of file
+#endif
index 5c61d72eef89da05deee4e4ade0717818f8d4853..10951616484cde3a873715d2470166f5dbffe5a4 100644 (file)
@@ -44,7 +44,7 @@ namespace System.ComponentModel {
 
                private EventHandlerList event_handlers;
                private ISite mySite;
-               private object disposedEvent = new object ();
+               static readonly object disposedEvent = new object ();
 
                public Component ()
                {
index bf618659ce6ff8f15fa71e8a2dccff08b4c243ee..4c336dd00572f33f087e5c65a4287f57f31d74f5 100644 (file)
@@ -27,6 +27,7 @@
 //
 
 using System;
+using System.Reflection;
 #if (XML_DEP)
 using System.Xml;
 #endif
@@ -112,7 +113,79 @@ namespace System.Configuration
 #if (CONFIGURATION_DEP)
                protected override void Unmerge (ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
                {
-                       throw new NotImplementedException ();
+                       if (parentElement != null && sourceElement.GetType() != parentElement.GetType())
+                               throw new ConfigurationErrorsException ("Can't unmerge two elements of different type");
+
+                       bool isMinimalOrModified = saveMode == ConfigurationSaveMode.Minimal ||
+                               saveMode == ConfigurationSaveMode.Modified;
+
+                       foreach (PropertyInformation prop in sourceElement.ElementInformation.Properties)
+                       {
+                               if (prop.ValueOrigin == PropertyValueOrigin.Default)
+                                       continue;
+                               
+                               PropertyInformation unmergedProp = ElementInformation.Properties [prop.Name];
+                               
+                               object sourceValue = prop.Value;
+                               if (parentElement == null || !HasValue (parentElement, prop.Name)) {
+                                       unmergedProp.Value = sourceValue;
+                                       continue;
+                               }
+
+                               if (sourceValue == null)
+                                       continue;
+
+                               object parentValue = GetItem (parentElement, prop.Name);
+                               if (!PropertyIsElement (prop)) {
+                                       if (!object.Equals (sourceValue, parentValue) || 
+                                           (saveMode == ConfigurationSaveMode.Full) ||
+                                           (saveMode == ConfigurationSaveMode.Modified && prop.ValueOrigin == PropertyValueOrigin.SetHere))
+                                               unmergedProp.Value = sourceValue;
+                                       continue;
+                               }
+
+                               var sourceElem = (ConfigurationElement) sourceValue;
+                               if (isMinimalOrModified && !ElementIsModified (sourceElem))
+                                       continue;
+                               if (parentValue == null) {
+                                       unmergedProp.Value = sourceValue;
+                                       continue;
+                               }
+
+                               var parentElem = (ConfigurationElement) parentValue;
+                               ConfigurationElement copy = (ConfigurationElement) unmergedProp.Value;
+                               ElementUnmerge (copy, sourceElem, parentElem, saveMode);
+                       }
+               }
+
+               bool HasValue (ConfigurationElement element, string propName)
+               {
+                       PropertyInformation info = element.ElementInformation.Properties [propName];
+                       return info != null && info.ValueOrigin != PropertyValueOrigin.Default;
+               }
+
+               object GetItem (ConfigurationElement element, string property)
+               {
+                       PropertyInformation pi = ElementInformation.Properties [property];
+                       if (pi == null)
+                               throw new InvalidOperationException ("Property '" + property + "' not found in configuration element");
+
+                       return pi.Value;
+               }
+               
+               bool PropertyIsElement (PropertyInformation prop)
+               {
+                       return (typeof(ConfigurationElement).IsAssignableFrom (prop.Type));
+               }
+               
+               bool ElementIsModified (ConfigurationElement element)
+               {
+                       return (bool) element.GetType ().GetMethod ("IsModified", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (element, new object [0]);
+               }
+               
+               void ElementUnmerge (ConfigurationElement target, ConfigurationElement sourceElement, ConfigurationElement parentElement, ConfigurationSaveMode saveMode)
+               {
+                       target.GetType ().GetMethod ("Unmerge", BindingFlags.NonPublic | BindingFlags.Instance).Invoke (target, new object [] {sourceElement, parentElement, saveMode});
                }
 #endif
        }
index e08d79e0f10b97df5d49e13bbc1075a36df682a4..5f699855aad7fa996f4c62401e463ca2d7aa43a7 100644 (file)
@@ -1566,6 +1566,21 @@ namespace System.Diagnostics {
                                                        async_output.Close ();
                                                if (async_error != null)
                                                        async_error.Close ();
+
+                                               if (input_stream != null) {
+                                                       input_stream.Close();
+                                                       input_stream = null;
+                                               }
+
+                                               if (output_stream != null) {
+                                                       output_stream.Close();
+                                                       output_stream = null;
+                                               }
+
+                                               if (error_stream != null) {
+                                                       error_stream.Close();
+                                                       error_stream = null;
+                                               }
                                        }
                                }
                                
@@ -1576,21 +1591,6 @@ namespace System.Diagnostics {
                                                Process_free_internal(process_handle);
                                                process_handle=IntPtr.Zero;
                                        }
-
-                                       if (input_stream != null) {
-                                               input_stream.Close();
-                                               input_stream = null;
-                                       }
-
-                                       if (output_stream != null) {
-                                               output_stream.Close();
-                                               output_stream = null;
-                                       }
-
-                                       if (error_stream != null) {
-                                               error_stream.Close();
-                                               error_stream = null;
-                                       }
                                }
                        }
                        base.Dispose (disposing);
index c3c4772b5aa3fe29a75026057b81955ac4870b5c..1cdffff53304462ef786183bc0e62467ed06c10b 100644 (file)
@@ -36,6 +36,7 @@ using System.Collections;
 using System.Configuration;
 using System.Globalization;
 using System.IO;
+using System.Net;
 using System.Net.Cache;
 using System.Net.Sockets;
 using System.Runtime.Remoting.Messaging;
@@ -950,6 +951,14 @@ namespace System.Net
 
                        return result.Response;
                }
+               
+#if NET_3_5
+               public Stream EndGetRequestStream (IAsyncResult asyncResult, out TransportContext transportContext)
+               {
+                       transportContext = null;
+                       return EndGetRequestStream (asyncResult);
+               }
+#endif
 
                public override WebResponse GetResponse()
                {
@@ -1071,29 +1080,19 @@ namespace System.Net
                        redirects++;
                        Exception e = null;
                        string uriString = null;
-
                        switch (code) {
                        case HttpStatusCode.Ambiguous: // 300
                                e = new WebException ("Ambiguous redirect.");
                                break;
                        case HttpStatusCode.MovedPermanently: // 301
                        case HttpStatusCode.Redirect: // 302
-                       case HttpStatusCode.TemporaryRedirect: // 307
-                               /* MS follows the redirect for POST too
-                               if (method != "GET" && method != "HEAD") // 10.3
-                                       return false;
-                               */
-
-                               contentLength = -1;
-                               bodyBufferLength = 0;
-                               bodyBuffer = null;
-                               if (code != HttpStatusCode.TemporaryRedirect)
+                               if (method == "POST")
                                        method = "GET";
-                               uriString = webResponse.Headers ["Location"];
+                               break;
+                       case HttpStatusCode.TemporaryRedirect: // 307
                                break;
                        case HttpStatusCode.SeeOther: //303
                                method = "GET";
-                               uriString = webResponse.Headers ["Location"];
                                break;
                        case HttpStatusCode.NotModified: // 304
                                return false;
@@ -1109,6 +1108,11 @@ namespace System.Net
                        if (e != null)
                                throw e;
 
+                       //contentLength = -1;
+                       //bodyBufferLength = 0;
+                       //bodyBuffer = null;
+                       uriString = webResponse.Headers ["Location"];
+
                        if (uriString == null)
                                throw new WebException ("No Location header found for " + (int) code,
                                                        WebExceptionStatus.ProtocolError);
index a6d456293e63c54d739ab11e50275875d419bab1..27e9893a80a86df8f2db606cb13f126378cf62d2 100644 (file)
@@ -326,7 +326,8 @@ namespace System.Net
                        if (address == null)
                                throw new ArgumentNullException ("address");
 
-                       RecycleServicePoints ();
+                       if ((servicePoints.Count % 4) == 0)
+                               RecycleServicePoints ();
 
                        var origAddress = new Uri (address.Scheme + "://" + address.Authority);
                        
@@ -346,8 +347,8 @@ namespace System.Net
                        address = new Uri (address.Scheme + "://" + address.Authority);
                        
                        ServicePoint sp = null;
+                       SPKey key = new SPKey (origAddress, usesProxy ? address : null, useConnect);
                        lock (servicePoints) {
-                               SPKey key = new SPKey (origAddress, usesProxy ? address : null, useConnect);
                                sp = servicePoints [key] as ServicePoint;
                                if (sp != null)
                                        return sp;
index 04d534fa139fc7c772a142f76e028aa2914adc73..e0366bb0dbab76518d403ddf13d1530329087897 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_0
+#if NET_3_5
 
 using System.Security.Authentication.ExtendedProtection;
 
index cf07f572effc60a5d98307b4586cf7440d2c2c2c..7f65751c679f25aab1a931ebcde6ab20ca9e7b72 100644 (file)
@@ -613,16 +613,16 @@ namespace System.Net
                        return (statusCode >= 200 && statusCode != 204 && statusCode != 304);
                }
 
-               internal void GetCertificates () 
+               internal void GetCertificates (Stream stream
                {
                        // here the SSL negotiation have been done
 #if SECURITY_DEP && MONOTOUCH
-                       HttpsClientStream s = (nstream as HttpsClientStream);
+                       HttpsClientStream s = (stream as HttpsClientStream);
                        X509Certificate client = s.SelectedClientCertificate;
                        X509Certificate server = s.ServerCertificate;
 #else
-                       X509Certificate client = (X509Certificate) piClient.GetValue (nstream, null);
-                       X509Certificate server = (X509Certificate) piServer.GetValue (nstream, null);
+                       X509Certificate client = (X509Certificate) piClient.GetValue (stream, null);
+                       X509Certificate server = (X509Certificate) piServer.GetValue (stream, null);
 #endif
                        sPoint.SetCertificates (client, server);
                        certsAvailable = (server != null);
@@ -1144,16 +1144,16 @@ namespace System.Net
                        lock (this) {
                                if (Data.request != request)
                                        throw new ObjectDisposedException (typeof (NetworkStream).FullName);
-                               if (nstream == null)
-                                       return false;
                                s = nstream;
+                               if (s == null)
+                                       return false;
                        }
 
                        try {
                                s.Write (buffer, offset, size);
                                // here SSL handshake should have been done
                                if (ssl && !certsAvailable)
-                                       GetCertificates ();
+                                       GetCertificates (s);
                        } catch (Exception e) {
                                err_msg = e.Message;
                                WebExceptionStatus wes = WebExceptionStatus.SendFailure;
@@ -1166,10 +1166,10 @@ namespace System.Net
                                // if SSL is in use then check for TrustFailure
                                if (ssl) {
 #if SECURITY_DEP && MONOTOUCH
-                                       HttpsClientStream https = (nstream as HttpsClientStream);
+                                       HttpsClientStream https = (s as HttpsClientStream);
                                        if (https.TrustFailure) {
 #else
-                                       if ((bool) piTrustFailure.GetValue (nstream, null)) {
+                                       if ((bool) piTrustFailure.GetValue (, null)) {
 #endif
                                                wes = WebExceptionStatus.TrustFailure;
                                                msg = "Trust failure";
index d35ee4e0ebe66638c480e35db89de9607b34fea2..28a7011bb545c2cabf6c422bb896c3212c08c011 100644 (file)
@@ -159,7 +159,13 @@ namespace System.Timers
 
                protected override void Dispose (bool disposing)
                {
-                       Close ();
+                       // If we're disposing explicitly, clear all
+                       // fields. If not, all fields will have been
+                       // nulled by the GC during finalization, so
+                       // trying to lock on _lock will blow up.
+                       if (disposing)
+                               Close ();
+
                        base.Dispose (disposing);
                }
 
index 1262cc394724ae0e210221d1db835d67658ddb18..b7bc6b5b7ead46f36630f455443d4798e4ae097a 100644 (file)
@@ -191,6 +191,50 @@ namespace MonoTests.System.Collections.Concurrent
 
                        Assert.IsTrue (valid, "Aggregate test");
                }
+
+        [Test]
+        public void BasicRemoveEmptyTest ()
+        {
+            int result;
+            Assert.IsTrue(bag.IsEmpty);
+            Assert.IsFalse(bag.TryTake(out result));
+        }
+
+        [Test]
+        public void BasicRemoveTwiceTest()
+        {
+            bag.Add (1);
+            Assert.IsFalse (bag.IsEmpty);
+            Assert.AreEqual (1, bag.Count);
+
+            int result;
+            Assert.IsTrue (bag.TryTake (out result));
+            Assert.AreEqual (1, result);
+            Assert.IsTrue (bag.IsEmpty);
+            Assert.IsFalse (bag.TryTake (out result));
+            Assert.IsFalse (bag.TryTake (out result));
+        }
+
+        [Test]
+        public void AddRemoveAddTest()
+        {
+            bag.Add (1);
+            Assert.IsFalse (bag.IsEmpty);
+            Assert.AreEqual (1, bag.Count);
+
+            int result;
+            Assert.IsTrue (bag.TryTake (out result));
+            Assert.AreEqual (1, result);
+            Assert.IsTrue (bag.IsEmpty);
+
+            bag.Add (1);
+            Assert.IsFalse (bag.IsEmpty);
+            Assert.AreEqual (1, bag.Count);
+
+            Assert.IsTrue (bag.TryTake (out result));
+            Assert.AreEqual (1, result);
+            Assert.IsTrue (bag.IsEmpty);
+        }
                
                [Test]
                public void AddStressTest ()
old mode 100644 (file)
new mode 100755 (executable)
index 6f0e4cf..4bd26f9
@@ -4143,6 +4143,54 @@ namespace MonoTests.System.Net.Sockets
                        }
                }
 
+               [Test]
+               public void SetSocketOption_MulticastInterfaceIndex_Any ()
+               {
+                       IPAddress ip = IPAddress.Parse ("239.255.255.250");
+                       int index = 0;
+                       using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+                       {
+                               s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(index));
+                               s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, index));
+                       }
+               }
+
+               [Test]
+               public void SetSocketOption_MulticastInterfaceIndex_Loopback ()
+               {
+                       IPAddress ip = IPAddress.Parse ("239.255.255.250");
+                       int index = 1;
+                       using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+                       {
+                               s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(index));
+                               s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, index));
+                       }
+               }
+
+               [Test]
+               public void SetSocketOption_MulticastInterfaceIndex_Invalid ()
+               {
+                       IPAddress ip = IPAddress.Parse ("239.255.255.250");
+                       int index = 31415;
+                       using (Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp))
+                       {
+                               try
+                               {
+                                       s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastInterface, IPAddress.HostToNetworkOrder(index));
+                                       Assert.Fail ("#1");
+                               }
+                               catch
+                               {}
+                               try
+                               {
+                                       s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, index));
+                                       Assert.Fail ("#2");
+                               }
+                               catch
+                               {}
+                       }
+               }
+
                [Test]
                public void Shutdown_NoConnect ()
                {
index 0b17914cef9e367edec9c3325d58a07670a0dce6..f5ffb4ac713333aa3eb1654448b09b41162448f2 100644 (file)
@@ -30,7 +30,28 @@ System.Collections.Specialized/INotifyCollectionChanged.cs
 System.Collections.Specialized/NotifyCollectionChangedEventArgs.cs
 System.Collections.Specialized/NotifyCollectionChangedAction.cs
 System.Collections.Specialized/NotifyCollectionChangedEventHandler.cs
+System.ComponentModel.Design.Serialization/ComponentSerializationService.cs
+System.ComponentModel.Design.Serialization/ContextStack.cs
+System.ComponentModel.Design.Serialization/DefaultSerializationProviderAttribute.cs
+System.ComponentModel.Design.Serialization/DesignerLoader.cs
+System.ComponentModel.Design.Serialization/DesignerSerializerAttribute.cs
+System.ComponentModel.Design.Serialization/IDesignerLoaderHost.cs
+System.ComponentModel.Design.Serialization/IDesignerLoaderHost2.cs
+System.ComponentModel.Design.Serialization/IDesignerLoaderService.cs
+System.ComponentModel.Design.Serialization/IDesignerSerializationManager.cs
+System.ComponentModel.Design.Serialization/IDesignerSerializationProvider.cs
+System.ComponentModel.Design.Serialization/IDesignerSerializationService.cs
+System.ComponentModel.Design.Serialization/INameCreationService.cs
 System.ComponentModel.Design.Serialization/InstanceDescriptor.cs
+System.ComponentModel.Design.Serialization/MemberRelationship.cs
+System.ComponentModel.Design.Serialization/MemberRelationshipService.cs
+System.ComponentModel.Design.Serialization/ResolveNameEventArgs.cs
+System.ComponentModel.Design.Serialization/ResolveNameEventHandler.cs
+System.ComponentModel.Design.Serialization/RootDesignerSerializerAttribute.cs
+System.ComponentModel.Design.Serialization/SerializationStore.cs
+System.ComponentModel.Design/ActiveDesignerEventArgs.cs
+System.ComponentModel.Design/ActiveDesignerEventHandler.cs
+System.ComponentModel.Design/CheckoutException.cs
 System.ComponentModel.Design/CommandID.cs
 System.ComponentModel.Design/ComponentChangedEventArgs.cs
 System.ComponentModel.Design/ComponentChangedEventHandler.cs
@@ -40,31 +61,61 @@ System.ComponentModel.Design/ComponentEventArgs.cs
 System.ComponentModel.Design/ComponentEventHandler.cs
 System.ComponentModel.Design/ComponentRenameEventArgs.cs
 System.ComponentModel.Design/ComponentRenameEventHandler.cs
+System.ComponentModel.Design/DesignerCollection.cs
+System.ComponentModel.Design/DesignerEventArgs.cs
+System.ComponentModel.Design/DesignerEventHandler.cs
+System.ComponentModel.Design/DesignerOptionService.cs
 System.ComponentModel.Design/DesignerTransaction.cs
 System.ComponentModel.Design/DesignerTransactionCloseEventArgs.cs
 System.ComponentModel.Design/DesignerTransactionCloseEventHandler.cs
 System.ComponentModel.Design/DesignerVerb.cs
 System.ComponentModel.Design/DesignerVerbCollection.cs
+System.ComponentModel.Design/HelpContextType.cs
+System.ComponentModel.Design/HelpKeywordAttribute.cs
+System.ComponentModel.Design/HelpKeywordType.cs
 System.ComponentModel.Design/IComponentChangeService.cs
+System.ComponentModel.Design/IComponentDiscoveryService.cs
+System.ComponentModel.Design/IComponentInitializer.cs
 System.ComponentModel.Design/IDesigner.cs
+System.ComponentModel.Design/IDesignerEventService.cs
+System.ComponentModel.Design/IDesignerFilter.cs
 System.ComponentModel.Design/IDesignerHost.cs
+System.ComponentModel.Design/IDesignerHostTransactionState.cs
+System.ComponentModel.Design/IDesignerOptionService.cs
+System.ComponentModel.Design/IDictionaryService.cs
+System.ComponentModel.Design/IEventBindingService.cs
+System.ComponentModel.Design/IExtenderListService.cs
+System.ComponentModel.Design/IExtenderProviderService.cs
+System.ComponentModel.Design/IHelpService.cs
+System.ComponentModel.Design/IInheritanceService.cs
+System.ComponentModel.Design/IMenuCommandService.cs
 System.ComponentModel.Design/IReferenceService.cs
+System.ComponentModel.Design/IResourceService.cs
 System.ComponentModel.Design/IRootDesigner.cs
+System.ComponentModel.Design/ISelectionService.cs
 System.ComponentModel.Design/IServiceContainer.cs
+System.ComponentModel.Design/ITreeDesigner.cs
 System.ComponentModel.Design/ITypeDescriptorFilterService.cs
+System.ComponentModel.Design/ITypeDiscoveryService.cs
 System.ComponentModel.Design/ITypeResolutionService.cs
 System.ComponentModel.Design/MenuCommand.cs
+System.ComponentModel.Design/SelectionTypes.cs
+System.ComponentModel.Design/ServiceContainer.cs
 System.ComponentModel.Design/ServiceCreatorCallback.cs
 System.ComponentModel.Design/StandardCommands.cs
+System.ComponentModel.Design/StandardToolWindows.cs
+System.ComponentModel.Design/TypeDescriptionProviderService.cs
 System.ComponentModel.Design/ViewTechnology.cs
 System.ComponentModel/AddingNewEventArgs.cs
 System.ComponentModel/AddingNewEventHandler.cs
+System.ComponentModel/AmbientValueAttribute.cs
 System.ComponentModel/ArrayConverter.cs
 System.ComponentModel/AsyncCompletedEventArgs.cs
 System.ComponentModel/AsyncCompletedEventHandler.cs
 System.ComponentModel/AsyncOperation.cs
 System.ComponentModel/AsyncOperationManager.cs
 System.ComponentModel/AttributeCollection.cs
+System.ComponentModel/AttributeProviderAttribute.cs
 System.ComponentModel/BackgroundWorker.cs
 System.ComponentModel/BaseNumberConverter.cs
 System.ComponentModel/BindableAttribute.cs
@@ -75,20 +126,32 @@ System.ComponentModel/BooleanConverter.cs
 System.ComponentModel/BrowsableAttribute.cs
 System.ComponentModel/ByteConverter.cs
 System.ComponentModel/CancelEventArgs.cs
+System.ComponentModel/CancelEventHandler.cs
 System.ComponentModel/CategoryAttribute.cs
 System.ComponentModel/CharConverter.cs
 System.ComponentModel/CollectionChangeAction.cs
 System.ComponentModel/CollectionChangeEventArgs.cs
 System.ComponentModel/CollectionChangeEventHandler.cs
 System.ComponentModel/CollectionConverter.cs
+System.ComponentModel/ComplexBindingPropertiesAttribute.cs
 System.ComponentModel/Component.cs
 System.ComponentModel/ComponentCollection.cs
 System.ComponentModel/ComponentConverter.cs
+System.ComponentModel/ComponentEditor.cs
+System.ComponentModel/ComponentResourceManager.cs
+System.ComponentModel/Container.cs
+System.ComponentModel/ContainerFilterService.cs
 System.ComponentModel/CultureInfoConverter.cs
 System.ComponentModel/CustomTypeDescriptor.cs
 System.ComponentModel/DataErrorsChangedEventArgs.cs
+System.ComponentModel/DataObjectAttribute.cs
+System.ComponentModel/DataObjectFieldAttribute.cs
+System.ComponentModel/DataObjectMethodAttribute.cs
+System.ComponentModel/DataObjectMethodType.cs
 System.ComponentModel/DateTimeConverter.cs
+System.ComponentModel/DateTimeOffsetConverter.cs
 System.ComponentModel/DecimalConverter.cs
+System.ComponentModel/DefaultBindingPropertyAttribute.cs
 System.ComponentModel/DefaultEventAttribute.cs
 System.ComponentModel/DefaultPropertyAttribute.cs
 System.ComponentModel/DefaultValueAttribute.cs
@@ -111,24 +174,35 @@ System.ComponentModel/EventDescriptor.cs
 System.ComponentModel/EventDescriptorCollection.cs
 System.ComponentModel/EventHandlerList.cs
 System.ComponentModel/ExpandableObjectConverter.cs
+System.ComponentModel/ExtenderProvidedPropertyAttribute.cs
 System.ComponentModel/GuidConverter.cs
+System.ComponentModel/HandledEventArgs.cs
+System.ComponentModel/HandledEventHandler.cs
 System.ComponentModel/IBindingList.cs
 System.ComponentModel/IBindingListView.cs
 System.ComponentModel/ICancelAddNew.cs
 System.ComponentModel/IChangeTracking.cs
 System.ComponentModel/IComNativeDescriptorHandler.cs
 System.ComponentModel/IComponent.cs
-System.ComponentModel/IComponent.cs
 System.ComponentModel/IContainer.cs
 System.ComponentModel/ICustomTypeDescriptor.cs
 System.ComponentModel/IDataErrorInfo.cs
-System.ComponentModel/IDataErrorInfo.cs
 System.ComponentModel/IEditableObject.cs
 System.ComponentModel/IExtenderProvider.cs
+System.ComponentModel/IIntellisenseBuilder.cs
 System.ComponentModel/IListSource.cs
+System.ComponentModel/ImmutableObjectAttribute.cs
+System.ComponentModel/INestedContainer.cs
+System.ComponentModel/INestedSite.cs
+System.ComponentModel/InheritanceAttribute.cs
+System.ComponentModel/InheritanceLevel.cs
+System.ComponentModel/InitializationEventAttribute.cs
 System.ComponentModel/INotifyDataErrorInfo.cs
 System.ComponentModel/INotifyPropertyChanged.cs
 System.ComponentModel/INotifyPropertyChanging.cs
+System.ComponentModel/InstallerTypeAttribute.cs
+System.ComponentModel/InstanceCreationEditor.cs
+System.ComponentModel/InvalidAsynchronousStateException.cs
 System.ComponentModel/IRaiseItemChangedEvents.cs
 System.ComponentModel/IRevertibleChangeTracking.cs
 System.ComponentModel/ISite.cs
@@ -141,7 +215,6 @@ System.ComponentModel/Int16Converter.cs
 System.ComponentModel/Int32Converter.cs
 System.ComponentModel/Int64Converter.cs
 System.ComponentModel/InvalidEnumArgumentException.cs
-System.ComponentModel/InvalidEnumArgumentException.cs
 System.ComponentModel/ListBindableAttribute.cs
 System.ComponentModel/ListChangedEventArgs.cs
 System.ComponentModel/ListChangedEventHandler.cs
@@ -149,14 +222,18 @@ System.ComponentModel/ListChangedType.cs
 System.ComponentModel/ListSortDescription.cs
 System.ComponentModel/ListSortDescriptionCollection.cs
 System.ComponentModel/ListSortDirection.cs
-System.ComponentModel/ListSortDirection.cs
 System.ComponentModel/LocalizableAttribute.cs
+System.ComponentModel/LookupBindingPropertiesAttribute.cs
 System.ComponentModel/MarshalByValueComponent.cs
+System.ComponentModel/MaskedTextProvider.cs
+System.ComponentModel/MaskedTextResultHint.cs
 System.ComponentModel/MemberDescriptor.cs
 System.ComponentModel/MergablePropertyAttribute.cs
 System.ComponentModel/MultilineStringConverter.cs
+System.ComponentModel/NestedContainer.cs
 System.ComponentModel/NotifyParentPropertyAttribute.cs
 System.ComponentModel/NullableConverter.cs
+System.ComponentModel/ParenthesizePropertyNameAttribute.cs
 System.ComponentModel/PasswordPropertyTextAttribute.cs
 System.ComponentModel/ProgressChangedEventArgs.cs
 System.ComponentModel/ProgressChangedEventHandler.cs
@@ -165,24 +242,27 @@ System.ComponentModel/PropertyChangedEventHandler.cs
 System.ComponentModel/PropertyChangingEventArgs.cs
 System.ComponentModel/PropertyChangingEventHandler.cs
 System.ComponentModel/PropertyDescriptor.cs
-System.ComponentModel/PropertyDescriptor.cs
 System.ComponentModel/PropertyDescriptorCollection.cs
-System.ComponentModel/ReadOnlyAttribute.cs
+System.ComponentModel/PropertyTabAttribute.cs
+System.ComponentModel/PropertyTabScope.cs
+System.ComponentModel/ProvidePropertyAttribute.cs
 System.ComponentModel/ReadOnlyAttribute.cs
 System.ComponentModel/RecommendedAsConfigurableAttribute.cs
 System.ComponentModel/ReferenceConverter.cs
-System.ComponentModel/ReferenceConverter.cs
 System.ComponentModel/ReflectionEventDescriptor.cs
 System.ComponentModel/ReflectionPropertyDescriptor.cs
 System.ComponentModel/RefreshEventArgs.cs
 System.ComponentModel/RefreshEventHandler.cs
 System.ComponentModel/RefreshProperties.cs
 System.ComponentModel/RefreshPropertiesAttribute.cs
+System.ComponentModel/RunInstallerAttribute.cs
 System.ComponentModel/RunWorkerCompletedEventArgs.cs
 System.ComponentModel/RunWorkerCompletedEventHandler.cs
 System.ComponentModel/SByteConverter.cs
+System.ComponentModel/SettingsBindableAttribute.cs
 System.ComponentModel/SingleConverter.cs
 System.ComponentModel/StringConverter.cs
+System.ComponentModel/SyntaxCheck.cs
 System.ComponentModel/TimeSpanConverter.cs
 System.ComponentModel/ToolboxItemAttribute.cs
 System.ComponentModel/ToolboxItemFilterAttribute.cs
@@ -190,11 +270,13 @@ System.ComponentModel/ToolboxItemFilterType.cs
 System.ComponentModel/TypeConverter.cs
 System.ComponentModel/TypeConverterAttribute.cs
 System.ComponentModel/TypeDescriptionProvider.cs
+System.ComponentModel/TypeDescriptionProviderAttribute.cs
 System.ComponentModel/TypeDescriptor.cs
 System.ComponentModel/TypeListConverter.cs
 System.ComponentModel/UInt16Converter.cs
 System.ComponentModel/UInt32Converter.cs
 System.ComponentModel/UInt64Converter.cs
+System.ComponentModel/WarningException.cs
 System.ComponentModel/WeakObjectWrapper.cs
 System.ComponentModel/WeakObjectWrapperComparer.cs
 System.ComponentModel/Win32Exception.cs
index 7391bae68515cfdf56e75560721b8271f1678080..eef6c529dafd379f04583c3fc70b432a6b374f4a 100644 (file)
@@ -44,7 +44,7 @@ namespace System.Windows {
                public override object ConvertFrom (ITypeDescriptorContext context, CultureInfo culture, object value)
                {
                        if (!(value is string))
-                               throw new NotSupportedException ("RectConverter only supports converting from strings");
+                               throw new NotSupportedException ("PointConverter only supports converting from strings");
 
                        return Point.Parse ((string)value);
                }
index 0cf61b786f3b642c727451ce5baa00ddd8afdeee..3000f81971b1ccdc94ecbda7dee4befe574c257f 100644 (file)
@@ -106,8 +106,8 @@ $(TEST_RESX_RESOURCES) $(TEST_RESX_RESOURCES_SATELITE): %.resources: %.resx
 
 TEST_RESOURCES = $(TEST_RESX_RESOURCES) $(TEST_RESX_RESOURCES_SATELITE)
 
-satellite_assembly1 = es-ES/$(patsubst %.dll,%.Resources.dll,$(test_lib))
-satellite_assembly2 = nn-NO/$(patsubst %.dll,%.Resources.dll,$(test_lib))
+satellite_assembly1 = es-ES/$(patsubst %.dll,%.resources.dll,$(test_lib))
+satellite_assembly2 = nn-NO/$(patsubst %.dll,%.resources.dll,$(test_lib))
 
 $(test_lib): $(TEST_RESOURCES) $(satellite_assembly1) $(satellite_assembly2) 
 
@@ -140,7 +140,9 @@ $(vtsdir)/$(PROFILE)_TestLib/BinarySerializationOverVersions.exe: $(vtsdir)/Bina
                $(vtsdir)/BinarySerializationOverVersions.cs -out:$@
        @cp $(vtsdir)/$(PROFILE)_TestLib/1.0/Address.dll $(vtsdir)/$(PROFILE)_TestLib
 
-# Need to define MONO_PATH to an absolute dir since the test is ran from a subdir
+# Need to define TEST_MONO_PATH to an absolute dir since the test is ran from a subdir
+TEST_MONO_PATH=$(PWD)/../lib/$(PROFILE)
+
 run-test-vts: test-vts
        @echo Running vts tests...
        PATH="$(TEST_RUNTIME_WRAPPERS_PATH):$(PATH)" $(TEST_RUNTIME) $(RUNTIME_FLAGS) $(TEST_HARNESS) -noshadow \
index bb8e99f704eba9cef4241772f12297f1e6069c9c..a52ced14f857b6edce920d0e410169fcc22bfcf6 100644 (file)
@@ -35,6 +35,7 @@ namespace System.Collections.Concurrent
 {
        [DebuggerDisplay ("Count={Count}")]
        [DebuggerTypeProxy (typeof (CollectionDebuggerView<,>))]
+       [Serializable]
        public class ConcurrentDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
          ICollection<KeyValuePair<TKey, TValue>>, IEnumerable<KeyValuePair<TKey, TValue>>,
          IDictionary, ICollection, IEnumerable
index 9af2e9d2053b5bcd10bb683590e568ade6586f9b..840984f04f16bea9e0d544fd4b12617c04ada314 100644 (file)
@@ -69,7 +69,7 @@ namespace System.Collections.Generic {
                                AddEnumerable (collection);
                        } else {
                                _size = c.Count;
-                               _items = new T [Math.Max (_size, DefaultCapacity)];
+                               _items = new T [_size];
                                c.CopyTo (_items, 0);
                        }
                }
index 92ccb86c9031f0c9bca1ea446b9d0ab5a00dcaa7..637636e75da9bef815a2655e96ce210142bc39ce 100644 (file)
@@ -1,8 +1,9 @@
 //
 // System.Diagnostics.DebuggerTypeProxyAttribute.cs
 //
-// Author:
+// Authors:
 //   Chris Toshok (toshok@novell.com)
+//   Marek Safar (marek.safar@gmail.com)
 //
 
 //
@@ -46,8 +47,12 @@ namespace System.Diagnostics {
                        proxy_type_name = typeName;
                }
 
-               public DebuggerTypeProxyAttribute (Type type) {
-                       proxy_type_name = type.Name;
+               public DebuggerTypeProxyAttribute (Type type)
+               {
+                       if (type == null)
+                               throw new ArgumentNullException ("type");
+
+                       proxy_type_name = type.AssemblyQualifiedName;
                }
 
                public string ProxyTypeName {
index f93cac39337e31c0ebe7c72057c1e3265629d4d5..131254f4227101912be42c033e68b91af67fe34c 100644 (file)
@@ -44,7 +44,7 @@ namespace System.Globalization
        {
                static volatile CultureInfo invariant_culture_info = new CultureInfo (InvariantCultureId, false, true);
                static object shared_table_lock = new object ();
-               internal static int BootstrapCultureID;
+               static CultureInfo default_current_culture;
 
 #pragma warning disable 169, 649
                bool m_isReadOnly;
@@ -99,7 +99,7 @@ namespace System.Globalization
                // Used by Thread.set_CurrentCulture
                internal byte[] cached_serialized_form;
                
-               const int InvariantCultureId = 0x7F;
+               internal const int InvariantCultureId = 0x7F;
                const int CalendarTypeBits = 8;
 
                const string MSG_READONLY = "This instance is read only";
@@ -124,10 +124,24 @@ namespace System.Globalization
 
                internal static CultureInfo ConstructCurrentCulture ()
                {
-                       CultureInfo ci = new CultureInfo ();
-                       if (!ConstructInternalLocaleFromCurrentLocale (ci))
+                       if (default_current_culture != null)
+                               return default_current_culture;
+
+                       var locale_name = get_current_locale_name ();
+                       CultureInfo ci = null;
+                       try {
+                               ci = CreateSpecificCulture (locale_name);
+                       } catch {
+                       }
+
+                       if (ci == null) {
                                ci = InvariantCulture;
-                       BootstrapCultureID = ci.cultureID;
+                       } else {
+                               ci.m_isReadOnly = true;
+                               ci.m_useUserOverride = true;
+                       }
+
+                       default_current_culture = ci;
                        return ci;
                }
 
@@ -535,9 +549,10 @@ namespace System.Globalization
                        }
                }
 
-               public static CultureInfo InstalledUICulture
-               {
-                       get { return GetCultureInfo (BootstrapCultureID); }
+               public static CultureInfo InstalledUICulture {
+                       get {
+                               return ConstructCurrentCulture ();
+                       }
                }
 
                public bool IsReadOnly {
@@ -568,24 +583,14 @@ namespace System.Globalization
                        constructed = true;
                }
 
-               static bool ConstructInternalLocaleFromCurrentLocale (CultureInfo ci)
-               {
-                       if (!construct_internal_locale_from_current_locale (ci))
-                               return false;
-                       return true;
-               }
-
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern bool construct_internal_locale_from_lcid (int lcid);
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern bool construct_internal_locale_from_name (string name);
 
-//             [MethodImplAttribute (MethodImplOptions.InternalCall)]
-//             private extern static bool construct_internal_locale_from_specific_name (CultureInfo ci, string name);
-
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
-               private extern static bool construct_internal_locale_from_current_locale (CultureInfo ci);
+               private extern static string get_current_locale_name ();
 
                [MethodImplAttribute (MethodImplOptions.InternalCall)]
                private extern static CultureInfo [] internal_get_cultures (bool neutral, bool specific, bool installed);
@@ -678,13 +683,7 @@ namespace System.Globalization
                        }
 
                        if (!construct_internal_locale_from_name (name.ToLowerInvariant ())) {
-#if NET_4_0
-                               throw new CultureNotFoundException ("name",
-                                               "Culture name " + name + " is not supported.");
-#else
-                               throw new ArgumentException ("Culture name " + name +
-                                               " is not supported.", "name");
-#endif
+                               throw CreateNotFoundException (name);
                        }
                }
 
@@ -789,28 +788,20 @@ namespace System.Globalization
                        if (name.Length == 0)
                                return InvariantCulture;
 
-                       CultureInfo ci = null;
-                       try {
-                               ci = new CultureInfo (name);
-                       } catch (Exception) {
-                               // TODO: Use construct_internal_locale_from_name when it's not bound to constructor instead
-                               // of try-catch
+                       var src_name = name;
+                       name = name.ToLowerInvariant ();
+                       CultureInfo ci = new CultureInfo ();
+
+                       if (!ci.construct_internal_locale_from_name (name)) {
                                int idx = name.IndexOf ('-');
-                               if (idx > 0) {
-                                       try {
-                                               ci = new CultureInfo (name.Substring (0, idx));
-                                       } catch {
-                                       }
-                               }
-                               
-                               if (ci == null)
-                                       throw;
+                               if (idx < 1 || !ci.construct_internal_locale_from_name (name.Substring (0, idx)))
+                                       throw CreateNotFoundException (src_name);
                        }
 
-                       if (!ci.IsNeutralCulture)
-                               return ci;
+                       if (ci.IsNeutralCulture)
+                               ci = CreateSpecificCultureFromNeutral (ci.Name);
 
-                       return CreateSpecificCultureFromNeutral (ci.Name);
+                       return ci;
                }
 
                //
@@ -1007,25 +998,32 @@ namespace System.Globalization
                                return CreateCalendar (1 << CalendarTypeBits); // return invariant calandar if not found
                        return (Calendar) Activator.CreateInstance (type);
                }
+
+               static Exception CreateNotFoundException (string name)
+               {
+#if NET_4_0
+                       return new CultureNotFoundException ("name", "Culture name " + name + " is not supported.");
+#else
+                       return new ArgumentException ("Culture name " + name + " is not supported.", "name");
+#endif
+               }
                
 #if NET_4_5
-               [MonoTODO]
                public static CultureInfo DefaultThreadCurrentCulture {
                        get {
-                               throw new NotImplementedException ();
+                               return Thread.default_culture;
                        }
                        set {
-                               throw new NotImplementedException ();
+                               Thread.default_culture = value;
                        }
                }
                
-               [MonoTODO]
                public static CultureInfo DefaultThreadCurrentUICulture {
                        get {
-                               throw new NotImplementedException ();
+                               return Thread.default_ui_culture;
                        }
                        set {
-                               throw new NotImplementedException ();
+                               Thread.default_ui_culture = value;
                        }
                }
 #endif
index b6165a661d0ad1f4dac3498c8faa5e154b6df193..4f11e37791ebc93a794c7331175da8fab6ac4aa6 100644 (file)
@@ -39,21 +39,15 @@ namespace System.Globalization
        {
                static RegionInfo currentRegion;
 
-               // This property is not synchronized with CurrentCulture, so
-               // we need to use bootstrap CurrentCulture LCID.
                public static RegionInfo CurrentRegion {
                        get {
                                if (currentRegion == null) {
-                                       // make sure to fill BootstrapCultureID.
                                        CultureInfo ci = CultureInfo.CurrentCulture;
-                                       // If current culture is invariant then region is not available.
-                                       if (ci != null && CultureInfo.BootstrapCultureID != 0x7F)
-                                               currentRegion = new RegionInfo (CultureInfo.BootstrapCultureID);
-                                       else
+                                       if (ci != null)
+                                               return currentRegion = new RegionInfo (ci);
+
 #if MONOTOUCH
-                                               currentRegion = CreateFromNSLocale ();
-#else
-                                               currentRegion = null;
+                                       currentRegion = CreateFromNSLocale ();
 #endif
                                }
                                return currentRegion;
@@ -94,6 +88,26 @@ namespace System.Globalization
                                throw new ArgumentException (String.Format ("Region name {0} is not supported.", name), "name");
                }
 
+               RegionInfo (CultureInfo ci)
+               {
+                       if (ci.LCID == CultureInfo.InvariantCultureId) {
+                               regionId = 244;
+                               iso2Name = "IV";
+                               iso3Name = "ivc";
+                               win3Name = "IVC";
+                               nativeName = englishName = "Invariant Country";
+                               currencySymbol = "\u00A4";
+                               isoCurrencySymbol ="XDR";
+                               currencyEnglishName = currencyNativeName = "International Monetary Fund";
+                               return;
+                       }
+
+                       if (ci.Territory == null)
+                               throw new NotImplementedException ("Neutral region info");
+
+                       construct_internal_region_from_name (ci.Territory.ToUpperInvariant ());
+               }
+
                bool GetByTerritory (CultureInfo ci)
                {
                        if (ci == null)
index cd4b95be9875657bbb56e6d47caf9bf9901e97ed..56493a34362ce3da4e6c223d607b6eea34b877be 100644 (file)
@@ -225,10 +225,12 @@ namespace System.Globalization {
                                        // then don't capitalize it.
                                        int saved = i;
                                        while (++i < str.Length) {
-                                               if (Char.IsWhiteSpace (str [i]))
+                                               var ch = str [i];
+                                               var category = char.GetUnicodeCategory (ch);
+                                               if (IsSeparator (category))
                                                        break;
-                                               t = ToTitleCase (str [i]);
-                                               if (t != str [i]) {
+                                               t = ToTitleCase (ch);
+                                               if (t != ch) {
                                                        allTitle = false;
                                                        break;
                                                }
@@ -242,9 +244,11 @@ namespace System.Globalization {
                                        // where we don't have to modify
                                        // the source word.
                                        while (++i < str.Length) {
-                                               if (Char.IsWhiteSpace (str [i]))
+                                               var ch = str [i];
+                                               var category = char.GetUnicodeCategory (ch);
+                                               if (IsSeparator (category))
                                                        break;
-                                               if (ToLower (str [i]) != str [i]) {
+                                               if (ToLower (ch) != ch) {
                                                        capitalize = true;
                                                        i = saved;
                                                        break;
@@ -259,9 +263,11 @@ namespace System.Globalization {
                                        sb.Append (ToTitleCase (str [i]));
                                        start = i + 1;
                                        while (++i < str.Length) {
-                                               if (Char.IsWhiteSpace (str [i]))
+                                               var ch = str [i];
+                                               var category = char.GetUnicodeCategory (ch);
+                                               if (IsSeparator (category))
                                                        break;
-                                               sb.Append (ToLower (str [i]));
+                                               sb.Append (ToLower (ch));
                                        }
                                        start = i;
                                }
@@ -272,6 +278,27 @@ namespace System.Globalization {
                        return sb != null ? sb.ToString () : str;
                }
 
+               static bool IsSeparator (UnicodeCategory category)
+               {
+                       switch (category) {
+                       case UnicodeCategory.SpaceSeparator:
+                       case UnicodeCategory.LineSeparator:
+                       case UnicodeCategory.ParagraphSeparator:
+                       case UnicodeCategory.Control:
+                       case UnicodeCategory.Format:
+                       case UnicodeCategory.ConnectorPunctuation:
+                       case UnicodeCategory.DashPunctuation:
+                       case UnicodeCategory.OpenPunctuation:
+                       case UnicodeCategory.ClosePunctuation:
+                       case UnicodeCategory.InitialQuotePunctuation:
+                       case UnicodeCategory.FinalQuotePunctuation:
+                       case UnicodeCategory.OtherPunctuation:
+                               return true;
+                       }
+
+                       return false;
+               }
+
                // Only Azeri and Turkish have their own special cases.
                // Other than them, all languages have common special case
                // (enumerable enough).
index eb1aa06efeaf5bb1295e730d9330dc4318239f81..24dcf8b7470f9cb7542ef9873c1213658027b8f1 100644 (file)
@@ -299,7 +299,7 @@ namespace System.Reflection {
                {
                        if (index == null || index.Length == 0) {
                                /*FIXME we should check if the number of arguments matches the expected one, otherwise the error message will be pretty criptic.*/
-#if !MONOTOUCH
+#if !FULL_AOT_RUNTIME
                                if (cached_getter == null) {
                                        MethodInfo method = GetGetMethod (true);
                                        if (!DeclaringType.IsValueType && !method.ContainsGenericParameters) { //FIXME find a way to build an invoke delegate for value types.
index 197ece5adc9ab9a5c6a9b1f72df9cd16bbd04434..29578435b898fb13194a999b97c7292ed41b8453 100644 (file)
@@ -76,13 +76,8 @@ namespace System.Runtime.CompilerServices
                
                public void SetException (Exception exception)
                {
-                       if (exception is OperationCanceledException) {
-                               if (Task.TrySetCanceled ())
-                                       return;
-                       } else {
-                               if (Task.TrySetException (new AggregateException (exception)))
-                                       return;
-                       }
+                       if (Task.TrySetException (new AggregateException (exception), exception is OperationCanceledException))
+                               return;
 
                        throw new InvalidOperationException ("The task has already completed");
                }
index f955d6b9fd57a3cfbe4b94965d9635bf5c3d0b4d..96f6dc68ab0fd9ef994ce80b91fe41a1ef40602e 100644 (file)
@@ -76,13 +76,8 @@ namespace System.Runtime.CompilerServices
 
                public void SetException (Exception exception)
                {
-                       if (exception is OperationCanceledException) {
-                               if (Task.TrySetCanceled ())
-                                       return;
-                       } else {
-                               if (Task.TrySetException (new AggregateException (exception)))
-                                       return;
-                       }
+                       if (Task.TrySetException (new AggregateException (exception), exception is OperationCanceledException))
+                               return;
 
                        throw new InvalidOperationException ("The task has already completed");
                }
index 1252d062b5513c0b94eeb1e6394993b230d91494..838b31c55dcacd474f40e8f8dfde11f33911a2bf 100644 (file)
@@ -28,6 +28,7 @@
 
 #if NET_4_5
 
+using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.ExceptionServices;
 
@@ -54,6 +55,9 @@ namespace System.Runtime.CompilerServices
 
                        public void GetResult ()
                        {
+                               if (!task.IsCompleted)
+                                       task.WaitCore (Timeout.Infinite, CancellationToken.None, true);
+
                                if (task.Status != TaskStatus.RanToCompletion)
                                        ExceptionDispatchInfo.Capture (TaskAwaiter.HandleUnexpectedTaskResult (task)).Throw ();
                        }
index 380c05f3febb5602c81fe99bdef77a21c75d70e8..b96b1cc6f377fcf8804ef705575310231959facb 100644 (file)
@@ -28,6 +28,7 @@
 
 #if NET_4_5
 
+using System.Threading;
 using System.Threading.Tasks;
 using System.Runtime.ExceptionServices;
 
@@ -54,6 +55,9 @@ namespace System.Runtime.CompilerServices
 
                        public TResult GetResult ()
                        {
+                               if (!task.IsCompleted)
+                                       task.WaitCore (Timeout.Infinite, CancellationToken.None, true);
+
                                if (task.Status != TaskStatus.RanToCompletion)
                                        ExceptionDispatchInfo.Capture (TaskAwaiter.HandleUnexpectedTaskResult (task)).Throw ();
 
index ab2c8cadd674d00725363363a557cc11f5d910d2..b6998479cc3fbbb11bd2d28048edc8f5100a002c 100644 (file)
@@ -53,7 +53,7 @@ namespace System.Runtime.CompilerServices
                public void GetResult ()
                {
                        if (!task.IsCompleted)
-                               task.WaitCore (Timeout.Infinite, CancellationToken.None);
+                               task.WaitCore (Timeout.Infinite, CancellationToken.None, true);
 
                        if (task.Status != TaskStatus.RanToCompletion)
                                // Merge current and dispatched stack traces if there is any
@@ -64,20 +64,47 @@ namespace System.Runtime.CompilerServices
                {
                        switch (task.Status) {
                        case TaskStatus.Canceled:
+                               // Use original exception when we have one
+                               if (task.ExceptionSlot.Exception != null)
+                                       goto case TaskStatus.Faulted;
+
                                return new TaskCanceledException (task);
                        case TaskStatus.Faulted:
-                               return task.Exception.InnerException;
+                               return task.ExceptionSlot.Exception.InnerException;
                        default:
-                               throw new ArgumentException ("Should never be reached");
+                               throw new ArgumentException (string.Format ("Unexpected task `{0}' status `{1}'", task.Id, task.Status));
                        }
                }
 
                internal static void HandleOnCompleted (Task task, Action continuation, bool continueOnSourceContext, bool manageContext)
                {
-                       if (continueOnSourceContext && SynchronizationContext.Current != null) {
+                       if (continueOnSourceContext && SynchronizationContext.Current != null && SynchronizationContext.Current.GetType () != typeof (SynchronizationContext)) {
                                task.ContinueWith (new SynchronizationContextContinuation (continuation, SynchronizationContext.Current));
                        } else {
-                               task.ContinueWith (new ActionContinuation (continuation));
+                               IContinuation cont;
+                               Task cont_task;
+                               if (continueOnSourceContext && TaskScheduler.Current != TaskScheduler.Default) {
+                                       cont_task = new Task (TaskActionInvoker.Create (continuation), null, CancellationToken.None, TaskCreationOptions.None, null);
+                                       cont_task.SetupScheduler (TaskScheduler.Current);
+                                       cont = new SchedulerAwaitContinuation (cont_task);
+                               } else {
+                                       cont_task = null;
+                                       cont = new ActionContinuation (continuation);
+                               }
+
+                               //
+                               // This is awaiter continuation. For finished tasks we get false result and need to
+                               // queue the continuation otherwise the task would block
+                               //
+                               if (task.ContinueWith (cont, false))
+                                       return;
+
+                               if (cont_task == null) {
+                                       cont_task = new Task (TaskActionInvoker.Create (continuation), null, CancellationToken.None, TaskCreationOptions.None, null);
+                                       cont_task.SetupScheduler (TaskScheduler.Current);
+                               }
+
+                               cont_task.Schedule ();
                        }
                }
 
index f12db5fe57814cf91ada45c557aa4c5aa1b581fa..b59a0ef005e3736eed23103ee90f822c9dd2f6b7 100644 (file)
@@ -53,7 +53,7 @@ namespace System.Runtime.CompilerServices
                public TResult GetResult ()
                {
                        if (!task.IsCompleted)
-                               task.WaitCore (Timeout.Infinite, CancellationToken.None);
+                               task.WaitCore (Timeout.Infinite, CancellationToken.None, true);
 
                        if (task.Status != TaskStatus.RanToCompletion)
                                ExceptionDispatchInfo.Capture (TaskAwaiter.HandleUnexpectedTaskResult (task)).Throw ();
index 93765269524e191aabaf47bf62750d2f264a59c7..ad697dd5f7b59a5d9384d07e660c19ba1a3f0858 100644 (file)
@@ -60,7 +60,7 @@ namespace System.Runtime.CompilerServices
                                        throw new ArgumentNullException ("continuation");
 
                                var ctx = SynchronizationContext.Current;
-                               if (ctx != null) {
+                               if (ctx != null && ctx.GetType () != typeof (SynchronizationContext)) {
                                        ctx.Post (l => ((Action) l) (), continuation);
                                        return;
                                }
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/DefaultInterfaceAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/DefaultInterfaceAttribute.cs
new file mode 100644 (file)
index 0000000..284839e
--- /dev/null
@@ -0,0 +1,46 @@
+#if NET_4_5
+//
+// DefaultInterfaceAttribute.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
+       public sealed class DefaultInterfaceAttribute : Attribute
+       {
+               public Type DefaultInterface {
+                       get;
+                       private set;
+               }
+
+               public DefaultInterfaceAttribute (Type defaultInterface)
+               {
+                       DefaultInterface = defaultInterface;
+               }
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/DesignerNamespaceResolveEventArgs.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/DesignerNamespaceResolveEventArgs.cs
new file mode 100644 (file)
index 0000000..33dbc83
--- /dev/null
@@ -0,0 +1,53 @@
+#if NET_4_5
+//
+// DesignerNamespaceResolveEventArgs.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Collections.ObjectModel;
+using System.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [ComVisibleAttribute(false)]
+       public class DesignerNamespaceResolveEventArgs : EventArgs
+       {
+               public DesignerNamespaceResolveEventArgs (string namespaceName)
+               {
+                       NamespaceName = namespaceName;
+                       ResolvedAssemblyFiles = new Collection<string> ();
+               }
+
+               public string NamespaceName {
+                       get;
+                       private set;
+               }
+
+               public Collection<string> ResolvedAssemblyFiles {
+                       get;
+                       private set;
+               }
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/EventRegistrationToken.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/EventRegistrationToken.cs
new file mode 100644 (file)
index 0000000..35d4161
--- /dev/null
@@ -0,0 +1,59 @@
+#if NET_4_5
+//
+// EventRegistrationToken.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       public struct EventRegistrationToken
+       {
+#pragma warning disable 0649
+               long value;
+#pragma warning restore 0649
+
+               public static bool operator == (EventRegistrationToken left, EventRegistrationToken right)
+               {
+                       return left.value == right.value;
+               }
+
+               public static bool operator != (EventRegistrationToken left, EventRegistrationToken right)
+               {
+                       return left.value != right.value;
+               }
+
+               public override bool Equals (object obj)
+               {
+                       return ((EventRegistrationToken)obj).value == value;
+               }
+
+               public override int GetHashCode ()
+               {
+                       return unchecked ((int)value);
+               }
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/EventRegistrationTokenTable.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/EventRegistrationTokenTable.cs
new file mode 100644 (file)
index 0000000..e4d7623
--- /dev/null
@@ -0,0 +1,68 @@
+#if NET_4_5
+//
+// EventRegistrationTokenTable.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [MonoTODO]
+       public sealed class EventRegistrationTokenTable<T>
+               where T : class
+       {
+               public EventRegistrationTokenTable ()
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public T InvocationList {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+
+               public EventRegistrationToken AddEventHandler (T handler)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static EventRegistrationTokenTable<T> GetOrCreateEventRegistrationTokenTable(ref EventRegistrationTokenTable<T> refEventTable)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void RemoveEventHandler (T handler)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public void RemoveEventHandler (EventRegistrationToken token)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
+#endif
+
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/IActivationFactory.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/IActivationFactory.cs
new file mode 100644 (file)
index 0000000..e7d010d
--- /dev/null
@@ -0,0 +1,38 @@
+#if NET_4_5
+//
+// IActivationFactory.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [Guid("00000035-0000-0000-C000-000000000046")]
+       public interface IActivationFactory
+       {
+               object ActivateInstance ();
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/InterfaceImplementedInVersionAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/InterfaceImplementedInVersionAttribute.cs
new file mode 100644 (file)
index 0000000..9950193
--- /dev/null
@@ -0,0 +1,71 @@
+#if NET_4_5
+//
+// InterfaceImplementedInVersionAttribute.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [AttributeUsageAttribute(AttributeTargets.Class|AttributeTargets.Interface, AllowMultiple = false, Inherited = false)]
+       public sealed class InterfaceImplementedInVersionAttribute : Attribute
+       {
+               public InterfaceImplementedInVersionAttribute (Type interfaceType, byte majorVersion, byte minorVersion,
+                       byte buildVersion, byte revisionVersion)
+               {
+                       InterfaceType = interfaceType;
+                       MajorVersion = majorVersion;
+                       MinorVersion = minorVersion;
+                       BuildVersion = buildVersion;
+                       RevisionVersion = revisionVersion;
+               }
+
+               public byte BuildVersion {
+                       get;
+                       private set;
+               }
+
+               public Type InterfaceType {
+                       get;
+                       private set;
+               }
+
+               public byte MajorVersion {
+                       get;
+                       private set;
+               }
+
+               public byte MinorVersion {
+                       get;
+                       private set;
+               }
+       
+               public byte RevisionVersion {
+                       get;
+                       private set;
+               }
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/NamespaceResolveEventArgs.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/NamespaceResolveEventArgs.cs
new file mode 100644 (file)
index 0000000..f57569b
--- /dev/null
@@ -0,0 +1,60 @@
+#if NET_4_5
+//
+// NamespaceResolveEventArgs.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Collections.ObjectModel;
+using System.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [ComVisibleAttribute(false)]
+       public class NamespaceResolveEventArgs : EventArgs
+       {
+               public NamespaceResolveEventArgs (string namespaceName, Assembly requestingAssembly)
+               {
+                       NamespaceName = namespaceName;
+                       RequestingAssembly = requestingAssembly;
+                       ResolvedAssemblies = new Collection<Assembly> ();
+               }
+
+               public string NamespaceName {
+                       get;
+                       private set;
+               }
+
+               public Assembly RequestingAssembly {
+                       get;
+                       private set;
+               }
+
+               public Collection<Assembly> ResolvedAssemblies {
+                       get;
+                       private set;
+               }
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/ReadOnlyArrayAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/ReadOnlyArrayAttribute.cs
new file mode 100644 (file)
index 0000000..0c5ecc3
--- /dev/null
@@ -0,0 +1,37 @@
+#if NET_4_5
+//
+// ReadOnlyArrayAttribute.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [AttributeUsageAttribute(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
+       public sealed class ReadOnlyArrayAttribute : Attribute
+       {
+       }
+}
+#endif
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/ReturnValueNameAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/ReturnValueNameAttribute.cs
new file mode 100644 (file)
index 0000000..8fd0173
--- /dev/null
@@ -0,0 +1,44 @@
+//
+// ReturnValueNameAttribute.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [AttributeUsageAttribute(AttributeTargets.Delegate|AttributeTargets.ReturnValue, AllowMultiple = false, Inherited = false)]
+       public sealed class ReturnValueNameAttribute : Attribute
+       {
+               public ReturnValueNameAttribute (string name)
+               {
+                       Name = name;
+               }
+
+               public string Name {
+                       get;
+                       private set;
+               }
+       }
+}
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMarshal.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMarshal.cs
new file mode 100644 (file)
index 0000000..fc24594
--- /dev/null
@@ -0,0 +1,72 @@
+#if NET_4_5
+//
+// WindowsRuntimeMarshal.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [MonoTODO]
+       public static class WindowsRuntimeMarshal
+       {
+               public static void AddEventHandler<T> ( Func<T, EventRegistrationToken> addMethod, Action<EventRegistrationToken> removeMethod, T handler)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static void FreeHString (IntPtr ptr)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static IActivationFactory GetActivationFactory (Type type)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static string PtrToStringHString (IntPtr ptr)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static void RemoveAllEventHandlers(Action<EventRegistrationToken> removeMethod)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static void RemoveEventHandler<T> (Action<EventRegistrationToken> removeMethod, T handler)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static IntPtr StringToHString (string s)
+               {
+                       throw new NotImplementedException ();
+               }
+       }
+}
+#endif
+
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMetadata.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMetadata.cs
new file mode 100644 (file)
index 0000000..4457336
--- /dev/null
@@ -0,0 +1,53 @@
+#if NET_4_5
+//
+// WindowsRuntimeMetadata.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Collections.Generic;
+using System.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [MonoTODO]
+       public static class WindowsRuntimeMetadata
+       {
+               public static IEnumerable<string> ResolveNamespace (string namespaceName, IEnumerable<string> packageGraphFilePaths)
+               {
+                       throw new NotImplementedException ();
+               }
+
+               public static IEnumerable<string> ResolveNamespace (string namespaceName, string windowsSdkFilePath, IEnumerable<string> packageGraphFilePaths)
+               {
+                       throw new NotImplementedException ();
+               }
+               
+#pragma warning disable 0067
+               public static event EventHandler<DesignerNamespaceResolveEventArgs> DesignerNamespaceResolve;
+               public static event EventHandler<NamespaceResolveEventArgs> ReflectionOnlyNamespaceResolve;
+#pragma warning restore 0067
+       }
+}
+#endif
+
diff --git a/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WriteOnlyArrayAttribute.cs b/mcs/class/corlib/System.Runtime.InteropServices.WindowsRuntime/WriteOnlyArrayAttribute.cs
new file mode 100644 (file)
index 0000000..7d5e461
--- /dev/null
@@ -0,0 +1,37 @@
+#if NET_4_5
+//
+// WriteOnlyArrayAttribute.cs
+//
+// Author:
+//       Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 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.Runtime.CompilerServices;
+
+namespace System.Runtime.InteropServices.WindowsRuntime
+{
+       [AttributeUsageAttribute(AttributeTargets.Parameter, Inherited = false, AllowMultiple = false)]
+       public sealed class WriteOnlyArrayAttribute : Attribute
+       {
+       }
+}
+#endif
index 4b5352a4aead209e4acf58aa54c1629724d1adba..fad4eaf4e4ebffb2cc5f9da6c7d3a4e7e48acd9c 100644 (file)
@@ -46,6 +46,7 @@ namespace System.Runtime.Remoting.Messaging
        public sealed class CallContext 
        {
                [ThreadStatic] static Header [] Headers;
+               [ThreadStatic] static Hashtable logicalDatastore;
                [ThreadStatic] static Hashtable datastore;
                [ThreadStatic] static object hostContext;
                
@@ -62,28 +63,37 @@ namespace System.Runtime.Remoting.Messaging
                public static void FreeNamedDataSlot (string name) 
                {
                        Datastore.Remove (name);
+                       LogicalDatastore.Remove (name);
                }
 
                public static object GetData (string name) 
                {
-                       return Datastore [name];
+                       if (LogicalDatastore.ContainsKey (name)) {
+                               return LogicalDatastore [name];
+                       } else {
+                               return Datastore [name];
+                       }
                }
                
                public static void SetData (string name, object data) 
                {
-                       Datastore [name] = data;
+                       if (data is ILogicalThreadAffinative) {
+                               LogicalSetData (name, data);
+                       } else {
+                               LogicalDatastore.Remove (name);
+                               Datastore [name] = data;
+                       }
                }
-
-               [MonoTODO]
+               
                public static object LogicalGetData (string name) 
                {
-                       throw new NotImplementedException ();
+                       return LogicalDatastore [name];
                }
-               
-               [MonoTODO]
+
                public static void LogicalSetData (string name, object data) 
                {
-                       throw new NotImplementedException ();
+                       Datastore.Remove (name);
+                       LogicalDatastore [name] = data;
                }
 
                public static Header[] GetHeaders () 
@@ -99,12 +109,11 @@ namespace System.Runtime.Remoting.Messaging
                internal static LogicalCallContext CreateLogicalCallContext (bool createEmpty)
                {
                        LogicalCallContext ctx = null;
-                       if (datastore != null) {
-                               foreach (DictionaryEntry entry in datastore)
-                                       if (entry.Value is ILogicalThreadAffinative) {
-                                               if (ctx == null) ctx = new LogicalCallContext ();
-                                               ctx.SetData ((string)entry.Key, entry.Value);
-                                       }
+                       if (logicalDatastore != null) {
+                               ctx = new LogicalCallContext ();
+                               foreach (DictionaryEntry entry in logicalDatastore) {
+                                       ctx.SetData ((string)entry.Key, entry.Value);
+                               }
                        }
 
                        if (ctx == null && createEmpty)
@@ -115,26 +124,31 @@ namespace System.Runtime.Remoting.Messaging
 
                internal static object SetCurrentCallContext (LogicalCallContext ctx)
                {
-                       object oldData = datastore;
+                       object oldData = new object[] { datastore, logicalDatastore };
 
                        if (ctx != null && ctx.HasInfo)
-                               datastore = (Hashtable) ctx.Datastore.Clone ();
+                               logicalDatastore = (Hashtable) ctx.Datastore.Clone ();
                        else
-                               datastore = null;
+                               logicalDatastore = null;
                                
                        return oldData;
                }
                
-               internal static void UpdateCurrentCallContext (LogicalCallContext ctx)
+               internal static void UpdateCurrentLogicalCallContext (LogicalCallContext ctx)
                {
                        Hashtable data = ctx.Datastore;
+                       if (data == null)
+                               return;
+
                        foreach (DictionaryEntry entry in data)
-                               SetData ((string)entry.Key, entry.Value);
+                               LogicalSetData ((string)entry.Key, entry.Value);
                }
                
                internal static void RestoreCallContext (object oldContext)
                {
-                       datastore = (Hashtable) oldContext;
+                       object[] contextArray = (object[])oldContext;
+                       datastore = (Hashtable)contextArray [0];
+                       logicalDatastore = (Hashtable)contextArray [1];
                }
 
                private static Hashtable Datastore
@@ -146,6 +160,16 @@ namespace System.Runtime.Remoting.Messaging
                                return r;
                        }
                }
+
+               private static Hashtable LogicalDatastore
+               {
+                       get {
+                               Hashtable r = logicalDatastore;
+                               if (r == null)
+                                       return logicalDatastore = new Hashtable ();
+                               return r;
+                       }
+               }
        }
 
        [System.Runtime.InteropServices.ComVisible (true)]
index 745c16134451013c22fa87c1e42c13a3a43e0f53..d430e9ccc1d505f0815f4d5c0100f7bf8d9d60d8 100644 (file)
@@ -218,7 +218,7 @@ namespace System.Runtime.Remoting.Proxies
                        }
                        
                        if (res_msg.LogicalCallContext != null && res_msg.LogicalCallContext.HasInfo)
-                               CallContext.UpdateCurrentCallContext (res_msg.LogicalCallContext);
+                               CallContext.UpdateCurrentLogicalCallContext (res_msg.LogicalCallContext);
 
                        exc = res_msg.Exception;
 
index f4bab8d4ad1c5c19dea2259422a92a9129a87b08..66ef9ce0e64df1e9a4d15b7b0dc431eb4f4f19c2 100644 (file)
@@ -796,7 +796,7 @@ namespace System.Runtime.Remoting
                        if (obj is CACD) {
                                CACD cad = (CACD) obj;
                                obj = cad.d;
-                               CallContext.UpdateCurrentCallContext ((LogicalCallContext) cad.c);
+                               CallContext.UpdateCurrentLogicalCallContext ((LogicalCallContext) cad.c);
                        }
                        return obj;
                }
index 1ae5559957ee710ce4206daf00fb0532f1df6987..cf34f769c950e68be8eb749eeacf0ce90ef8c0ea 100644 (file)
@@ -224,7 +224,7 @@ namespace System.Threading.Tasks
                        }
 
                        Schedule ();
-                       Wait ();
+                       WaitCore (Timeout.Infinite, CancellationToken.None, false);
                }
                #endregion
                
@@ -330,18 +330,28 @@ namespace System.Threading.Tasks
                        ContinueWith (new TaskContinuation (continuation, options));
                }
                
-               internal void ContinueWith (IContinuation continuation)
+               internal bool ContinueWith (IContinuation continuation, bool canExecuteInline = true)
                {
                        if (IsCompleted) {
+                               if (!canExecuteInline)
+                                       return false;
+
                                continuation.Execute ();
-                               return;
+                               return true;
                        }
                        
                        continuations.Add (continuation);
                        
                        // Retry in case completion was achieved but event adding was too late
-                       if (IsCompleted && continuations.Remove (continuation))
+                       if (IsCompleted) {
+                               continuations.Remove (continuation);
+                               if (!canExecuteInline)
+                                       return false;
+
                                continuation.Execute ();
+                       }
+
+                       return true;
                }
 
                internal void RemoveContinuation (IContinuation continuation)
@@ -438,7 +448,7 @@ namespace System.Threading.Tasks
                        return true;
                }
 
-               internal bool TrySetException (AggregateException aggregate)
+               internal bool TrySetException (AggregateException aggregate, bool cancellation)
                {
                        if (IsCompleted)
                                return false;
@@ -450,8 +460,16 @@ namespace System.Threading.Tasks
 
                                return false;
                        }
-                       
-                       HandleGenericException (aggregate);
+
+                       if (cancellation) {
+                               ExceptionSlot.Exception = aggregate;
+                               Thread.MemoryBarrier ();
+
+                               CancelReal ();
+                       } else {
+                               HandleGenericException (aggregate);
+                       }
+
                        return true;
                }
 
@@ -641,7 +659,7 @@ namespace System.Threading.Tasks
                        if (millisecondsTimeout < -1)
                                throw new ArgumentOutOfRangeException ("millisecondsTimeout");
 
-                       bool result = WaitCore (millisecondsTimeout, cancellationToken);
+                       bool result = WaitCore (millisecondsTimeout, cancellationToken, true);
 
                        if (IsCanceled)
                                throw new AggregateException (new TaskCanceledException (this));
@@ -653,13 +671,13 @@ namespace System.Threading.Tasks
                        return result;
                }
 
-               internal bool WaitCore (int millisecondsTimeout, CancellationToken cancellationToken)
+               internal bool WaitCore (int millisecondsTimeout, CancellationToken cancellationToken, bool runInline)
                {
                        if (IsCompleted)
                                return true;
 
                        // If the task is ready to be run and we were supposed to wait on it indefinitely without cancellation, just run it
-                       if (Status == TaskStatus.WaitingToRun && millisecondsTimeout == Timeout.Infinite && scheduler != null && !cancellationToken.CanBeCanceled)
+                       if (runInline && Status == TaskStatus.WaitingToRun && millisecondsTimeout == Timeout.Infinite && scheduler != null && !cancellationToken.CanBeCanceled)
                                scheduler.RunInline (this, true);
 
                        bool result = true;
@@ -1082,6 +1100,9 @@ namespace System.Threading.Tasks
 
                internal static Task<TResult[]> WhenAllCore<TResult> (IList<Task<TResult>> tasks)
                {
+                       if (tasks.Count == 0)
+                               return FromResult(new TResult[0]);
+
                        foreach (var t in tasks) {
                                if (t == null)
                                        throw new ArgumentException ("tasks", "the tasks argument contains a null element");
@@ -1242,7 +1263,7 @@ namespace System.Threading.Tasks
                
                public AggregateException Exception {
                        get {
-                               if (exSlot == null)
+                               if (exSlot == null || !IsFaulted)
                                        return null;
                                exSlot.Observed = true;
                                return exSlot.Exception;
@@ -1283,7 +1304,7 @@ namespace System.Threading.Tasks
                        }
                }
 
-               TaskExceptionSlot ExceptionSlot {
+               internal TaskExceptionSlot ExceptionSlot {
                        get {
                                if (exSlot != null)
                                        return exSlot;
index f4b3a3b81d7504fedf96f09524a54e2da0026bad..5c175aa1e74755b72ba56205a5ee3de9c953236a 100644 (file)
@@ -113,7 +113,7 @@ namespace System.Threading.Tasks
                        if (aggregate.InnerExceptions.Count == 0)
                                throw new ArgumentNullException ("exceptions");
 
-                       return source.TrySetException (aggregate);
+                       return source.TrySetException (aggregate, false);
                }
                
                public bool TrySetResult (TResult result)
index 9825be780009dbd896e61e072e17d8118bdedfef..e613712a448cf5b38279647d6fe6fddeae5a0e83 100644 (file)
@@ -125,6 +125,21 @@ namespace System.Threading.Tasks
                }
        }
 
+       class SchedulerAwaitContinuation : IContinuation
+       {
+               readonly Task task;
+
+               public SchedulerAwaitContinuation (Task task)
+               {
+                       this.task = task;
+               }
+
+               public void Execute ()
+               {
+                       task.RunSynchronouslyCore (task.scheduler);
+               }
+       }
+
        class SynchronizationContextContinuation : IContinuation
        {
                readonly Action action;
@@ -179,7 +194,7 @@ namespace System.Threading.Tasks
                        }
 
                        if (exceptions != null) {
-                               owner.TrySetException (new AggregateException (exceptions));
+                               owner.TrySetException (new AggregateException (exceptions), false);
                                return;
                        }
 
@@ -239,7 +254,7 @@ namespace System.Threading.Tasks
                        }
 
                        if (exceptions != null) {
-                               owner.TrySetException (new AggregateException (exceptions));
+                               owner.TrySetException (new AggregateException (exceptions), false);
                                return;
                        }
 
index 607f08da4ec4652c97ea9c82dbb4ae905e53813d..a558c622c5ebf2cf5a3158394a86ecd9da609966 100644 (file)
@@ -214,9 +214,14 @@ namespace System.Threading.Tasks
                                                        TaskCreationOptions creationOptions,
                                                        TaskScheduler scheduler)
                {
-                       Task<TResult> t = new Task<TResult> (function, state, cancellationToken, creationOptions);
-                       t.Start (scheduler);
+                       var t = new Task<TResult> (function, state, cancellationToken, creationOptions);
                        
+                       //
+                       // Don't start cancelled task it would throw an exception
+                       //
+                       if (!t.IsCompleted)
+                               t.Start (scheduler);
+
                        return t;
                }
                #endregion
index 3a75238f4dfe390f68e1987546f77a826f7db304..bf5f3da002f72a155437840b40fcb786ba46e59a 100644 (file)
@@ -171,9 +171,11 @@ namespace System.Threading
                                        if (stopCondition ())
                                                return false;
 
-                                       if (wait.Count > spinCount)
-                                               handle.WaitOne (Math.Min (Math.Max (millisecondsTimeout - (int)sw.ElapsedMilliseconds, 1), deepSleepTime));
-                                       else
+                                       if (wait.Count > spinCount) {
+                                               int timeout = millisecondsTimeout < 0 ? deepSleepTime :
+                                                       Math.Min (Math.Max (millisecondsTimeout - (int)sw.ElapsedMilliseconds, 1), deepSleepTime);
+                                               handle.WaitOne (timeout);
+                                       } else
                                                wait.SpinOnce ();
                                }
                        } while (true);
index 813c458f94934936e1ef7054b9de7f1200db2028..5af6800382751c3e602bf242e888eaa96c27131f 100644 (file)
@@ -137,6 +137,8 @@ namespace System.Threading {
 
                IPrincipal principal;
                int principal_version;
+               bool current_culture_set;
+               bool current_ui_culture_set;
                CultureInfo current_culture;
                CultureInfo current_ui_culture;
 
@@ -156,6 +158,9 @@ namespace System.Threading {
 
                static NamedDataSlot namedDataSlot;             
 
+               static internal CultureInfo default_culture;
+               static internal CultureInfo default_ui_culture;
+
                // can be both a ThreadStart and a ParameterizedThreadStart
                private MulticastDelegate threadstart;
                //private string thread_name=null;
@@ -470,11 +475,13 @@ namespace System.Threading {
                public CultureInfo CurrentCulture {
                        get {
                                CultureInfo culture = current_culture;
-                               if (culture != null)
+                               if (current_culture_set && culture != null)
                                        return culture;
 
+                               if (default_culture != null)
+                                       return default_culture;
+
                                current_culture = culture = CultureInfo.ConstructCurrentCulture ();
-                               NumberFormatter.SetThreadCurrentCulture (culture);
                                return culture;
                        }
                        
@@ -485,16 +492,19 @@ namespace System.Threading {
 
                                value.CheckNeutral ();
                                current_culture = value;
-                               NumberFormatter.SetThreadCurrentCulture (value);
+                               current_culture_set = true;
                        }
                }
 
                public CultureInfo CurrentUICulture {
                        get {
                                CultureInfo culture = current_ui_culture;
-                               if (culture != null)
+                               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;
                        }
@@ -503,6 +513,7 @@ namespace System.Threading {
                                if (value == null)
                                        throw new ArgumentNullException ("value");
                                current_ui_culture = value;
+                               current_ui_culture_set = true;
                        }
                }
 
index 77d76ad069dcb4cf22438a132c64adbf32a8b91a..612e603f6000cc076e041903ed11df55accec5a6 100644 (file)
@@ -134,13 +134,13 @@ namespace System
 
                T IList<T>.this[int index] {
                        get {
-                               if (index < 0 || count < index)
+                               if (index < 0 || index >= count)
                                        throw new ArgumentOutOfRangeException ("index");
 
                                return array[offset + index];
                        }
                        set {
-                               if (index < 0 || count < index)
+                               if (index < 0 || index >= count)
                                        throw new ArgumentOutOfRangeException ("index");
 
                                array[offset + index] = value;
index 46d0b775dbfb0c85f659f27446003e3a74dd569c..be91a7a182a9a723bf4ebc9347c9570f4061fc69 100644 (file)
@@ -258,7 +258,7 @@ namespace System
 
                public override int GetHashCode ()
                {
-                       int result = TypeId.GetHashCode ();
+                       int result = GetType ().GetHashCode ();
 
                        FieldInfo[] fields = GetType ().GetFields (BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
                        foreach (FieldInfo field in fields) {
index c62c8d0d039ef4e9b679ed87094d12fb475b1767..961cb949d628389dc977fbb12b11b12e9031d27c 100644 (file)
@@ -31,80 +31,83 @@ namespace System {
        [Serializable]
        public struct ConsoleKeyInfo {
                internal static ConsoleKeyInfo Empty = new ConsoleKeyInfo ('\0', 0, false, false, false);
-               ConsoleKey key;
-               char keychar;
-               ConsoleModifiers modifiers;
+               ConsoleKey _key;
+               char _keyChar;
+               ConsoleModifiers _mods;
 
                public ConsoleKeyInfo (char keyChar, ConsoleKey key, bool shift, bool alt, bool control)
                {
-                       this.key = key;
-                       this.keychar = keyChar;
-                       modifiers = 0;
+                       _key = key;
+                       _keyChar = keyChar;
+                       _mods = 0;
                        SetModifiers (shift, alt, control);
                }
 
                internal ConsoleKeyInfo (ConsoleKeyInfo other)
                {
-                       this.key = other.key;
-                       this.keychar = other.keychar;
-                       this.modifiers = other.modifiers;
+                       _key = other._key;
+                       _keyChar = other._keyChar;
+                       _mods = other._mods;
                }
 
                internal void SetKey (ConsoleKey key)
                {
-                       this.key = key;
+                       _key = key;
                }
 
                internal void SetKeyChar (char keyChar)
                {
-                       this.keychar = keyChar;
+                       _keyChar = keyChar;
                }
 
                internal void SetModifiers (bool shift, bool alt, bool control)
                {
-                       this.modifiers = (shift) ? ConsoleModifiers.Shift : 0;
-                       this.modifiers |= (alt) ? ConsoleModifiers.Alt : 0;
-                       this.modifiers |= (control) ? ConsoleModifiers.Control : 0;
+                       _mods = (shift) ? ConsoleModifiers.Shift : 0;
+                       _mods |= (alt) ? ConsoleModifiers.Alt : 0;
+                       _mods |= (control) ? ConsoleModifiers.Control : 0;
                }
 
-               public ConsoleKey Key {
-                       get { return key; }
+               public ConsoleKey Key 
+               {
+                       get { return _key; }
                }
 
-               public char KeyChar {
-                       get { return keychar; }
+               public char KeyChar 
+               {
+                       get { return _keyChar; }
                }
 
-               public ConsoleModifiers Modifiers {
-                       get { return modifiers; }
+               public ConsoleModifiers Modifiers 
+               {
+                       get { return _mods; }
                }
-               
+
                public override bool Equals (object value)
                {
                        if (!(value is ConsoleKeyInfo))
                                return false;
+
                        return Equals ((ConsoleKeyInfo) value);
                }
-               
+
                public static bool operator == (ConsoleKeyInfo a, ConsoleKeyInfo b)
                {
                        return a.Equals (b);
                }
-               
+
                public static bool operator != (ConsoleKeyInfo a, ConsoleKeyInfo b)
                {
                        return !a.Equals (b);
                }
-               
+
                public bool Equals (ConsoleKeyInfo obj)
                {
-                       return key == obj.key && obj.keychar == keychar && obj.modifiers == modifiers;
+                       return _key == obj._key && _keyChar == obj._keyChar && _mods == obj._mods;
                }
-               
+
                public override int GetHashCode ()
                {
-                       return key.GetHashCode () ^ keychar.GetHashCode () ^ modifiers.GetHashCode ();
+                       return _key.GetHashCode () ^ _keyChar.GetHashCode () ^ _mods.GetHashCode ();
                }
        }
 }
-
index aa4301d01619b26f80c2b177722f16f625e3eee1..507153c421aa2432b48f47c7eddacc499c4639ba 100644 (file)
@@ -527,7 +527,7 @@ namespace System
                                return source;
 
                        if (source.GetType () != value.GetType ())
-                               throw new ArgumentException ("Delegate type mismatch");
+                               throw new ArgumentException (Locale.GetText ("Incompatible Delegate Types. First is {0} second is {1}.", source.GetType ().FullName, value.GetType ().FullName));
 
                        return source.RemoveImpl (value);
                }
index d1b4015c0327b1644d611647b529a180ed0c94b6..13d63ccc129d66740dc1148e997d36aa5b2b7d46 100644 (file)
@@ -56,7 +56,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 110;
+               private const int mono_corlib_version = 111;
 #pragma warning restore 169
 
                [ComVisible (true)]
index 4f948aaf38bdb485bf3d395827b4862a255256a5..dc0fb5a1e11800578f51294235ee4d2d5884cb05 100644 (file)
@@ -557,9 +557,7 @@ namespace System
 
                private void Resize (int len)
                {
-                       char[] newBuf = new char [len];
-                       Array.Copy (_cbuf, newBuf, _ind);
-                       _cbuf = newBuf;
+                       Array.Resize (ref _cbuf, len);
                }
 
                private void Append (char c)
@@ -783,6 +781,7 @@ namespace System
                        threadNumberFormatter = null;
                        if (res == null)
                                return new NumberFormatter (Thread.CurrentThread);
+                       res.CurrentCulture = Thread.CurrentThread.CurrentCulture;
                        return res;
                }
 
@@ -791,12 +790,6 @@ namespace System
                        threadNumberFormatter = this;
                }
 
-               internal static void SetThreadCurrentCulture (CultureInfo culture)
-               {
-                       if (threadNumberFormatter != null)
-                               threadNumberFormatter.CurrentCulture = culture;
-               }
-
                public static string NumberToString (string format, sbyte value, IFormatProvider fp)
                {
                        NumberFormatter inst = GetInstance();
index d30735f9bdbad34a0239933209a4997f4609a14d..00055dc07e2602a8f0de725d2f0109e39e61081b 100644 (file)
@@ -2743,11 +2743,13 @@ namespace System
                        if (values == null)
                                throw new ArgumentNullException ("values");
                        
-                       var stringList = new List<string> ();
-                       foreach (var v in values)
-                               stringList.Add (v.ToString ());
+                       var stringList = values as IList<T> ?? new List<T> (values);
+                       var strCopy = new string [stringList.Count];
+                       int i = 0;
+                       foreach (var v in stringList)
+                               strCopy [i++] = v.ToString ();
 
-                       return JoinUnchecked (separator, stringList.ToArray (), 0, stringList.Count);
+                       return JoinUnchecked (separator, strCopy, 0, strCopy.Length);
                }
 
                public static bool IsNullOrWhiteSpace (string value)
index 316e99ce44b45950e71ca0162b679ae5ad439fef..5e11d8d53dd6ad74baf301dd1cbd8ddbc7b3412c 100644 (file)
@@ -357,12 +357,22 @@ namespace System
                        if (time.Kind == DateTimeKind.Utc)
                                return TimeSpan.Zero;
 
-                       if (IsDaylightSavingTime (time))
+                       if (IsDaylightSavingTime (time) && !IsAmbiguousTime (time))
                                return utcOffsetWithDLS;
 
                        return utcOffsetWithOutDLS;
                }
 
+               private bool IsAmbiguousTime (DateTime time)
+               {
+                       if (time.Kind == DateTimeKind.Utc)
+                               return false;
+
+                       DaylightTime changes = GetDaylightChanges (time.Year);
+
+                       return time < changes.End && time >= changes.End - changes.Delta;
+               }
+
                void IDeserializationCallback.OnDeserialization (object sender)
                {
                        OnDeserialization (null);
old mode 100644 (file)
new mode 100755 (executable)
index a2c030c..3bffaf3
@@ -2201,6 +2201,8 @@ namespace MonoTests.Microsoft.Win32
                }
 
                [Test]
+               // This hangs on windows
+               [Category ("NotWorking")]
                public void OpenRemoteBaseKey_MachineName_DoesNotExist ()
                {
                        // access to registry of remote machines is not implemented on unix
index 6542238daedae949f3c822ac4f846c3b6a851f42..9ac58e0fdd9016a8c517b327da8dbe546d485d27 100644 (file)
@@ -30,8 +30,6 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_2_0
-
 using System;
 using System.Collections;
 using System.Collections.Generic;
@@ -286,6 +284,10 @@ namespace MonoTests.System.Collections.Generic {
                        Assert.AreEqual (l1.Count, l1.Capacity);
                        for (int i = 0; i < l1.Count; i++)
                                Assert.AreEqual (_list1 [i], l1 [i]);
+
+                       var input = new [] { "a", "b", "c" };
+                       var l2 = new List<string>(input);
+                       Assert.AreEqual (3, l2.Capacity);
                }
 
                [Test, ExpectedException (typeof (ArgumentNullException))]
@@ -1549,5 +1551,4 @@ namespace MonoTests.System.Collections.Generic {
 
        }
 }
-#endif
 
index 3dbcccdf29b97fc213d877e05f57c9cc921f7692..5564e47a36bafcdbea18559cbd03788a9c883586 100644 (file)
@@ -1,5 +1,5 @@
 //
-// MonoTests.System.Diagnostics.DebuggerDisplayAttributeTest.cs
+// DebuggerDisplayAttributeTest.cs
 //
 // Author:
 //      Rolf Bjarne Kvinge  (RKvinge@novell.com)
@@ -7,8 +7,6 @@
 // (C) 2007
 //
 
-#if NET_2_0
-
 using System;
 using System.Diagnostics;
 using NUnit.Framework;
@@ -172,5 +170,3 @@ namespace MonoTests.System.Diagnostics
                }
        }
 }
-
-#endif
\ No newline at end of file
diff --git a/mcs/class/corlib/Test/System.Diagnostics/DebuggerTypeProxyAttribute.cs b/mcs/class/corlib/Test/System.Diagnostics/DebuggerTypeProxyAttribute.cs
new file mode 100644 (file)
index 0000000..bd3297d
--- /dev/null
@@ -0,0 +1,56 @@
+//
+// DecoupledTask.cs
+//
+// Authors:
+//    Marek Safar  <marek.safar@gmail.com>
+//
+// Copyright 2013 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.Diagnostics;
+using NUnit.Framework;
+
+namespace MonoTests.System.Diagnostics
+{
+       [TestFixture]
+       public class DebuggerTypeProxyAttributeTest
+       {
+               [Test]
+               public void Constructor_Type ()
+               {
+                       var dtp = new DebuggerTypeProxyAttribute (typeof (string));
+                       Assert.IsNull (dtp.Target, "#1");
+                       Assert.AreEqual (typeof (string).AssemblyQualifiedName, dtp.ProxyTypeName, "#2");
+               }
+
+               [Test]
+               public void Constructor_Type_Invalid ()
+               {
+                       try {
+                               new DebuggerTypeProxyAttribute (null as Type);
+                               Assert.Fail ();
+                       } catch (ArgumentNullException) {                       
+                       }
+               }
+       }
+}
index 033cc08539db4fea459009761435d537c08022e7..0f7646b03673719877215d846cd8a3bbc86b9d1a 100644 (file)
@@ -42,6 +42,7 @@ namespace MonoTests.System.Diagnostics
                ///   Tests whether getting file name works.
                /// </summary>
                [Test]
+               [Category("LLVMNotWorking")]
                public void TestGetFileName ()
                {
                        Assert.AreEqual ("dir/someFile",
@@ -57,6 +58,7 @@ namespace MonoTests.System.Diagnostics
                /// Tests whether getting file line number works.
                /// </summary>
                [Test]
+               [Category("LLVMNotWorking")]
                public void TestGetFileLineNumber ()
                {
                        Assert.AreEqual (13,
@@ -152,6 +154,7 @@ namespace MonoTests.System.Diagnostics
                }
 
                [Test]
+               [Category ("LLVMNotWorking")]
                public void TestGetFileName2 ()
                {
                        Assert.IsNotNull (frame2.GetFileName (), "File name not null");
@@ -164,13 +167,14 @@ namespace MonoTests.System.Diagnostics
                /// Tests whether getting file line number works.
                /// </summary>
                [Test]
+               [Category ("LLVMNotWorking")]
                public void TestGetFileLineNumber ()
                {
                        Assert.AreEqual (0,
                                                         frame1.GetFileLineNumber (),
                                                         "Line number (1)");
 
-                       Assert.AreEqual (132,
+                       Assert.AreEqual (134,
                                                         frame2.GetFileLineNumber (),
                                                         "Line number (2)");
 
@@ -280,6 +284,7 @@ namespace MonoTests.System.Diagnostics
                /// Tests whether getting file name works.
                /// </summary>
                [Test]
+               [Category ("LLVMNotWorking")]
                public void TestGetFileName ()
                {
                        Assert.IsNull (frame1.GetFileName (),
@@ -299,13 +304,14 @@ namespace MonoTests.System.Diagnostics
 #if ONLY_1_1
                [Category ("NotDotNet")] // .NET 1.1 is off by one
 #endif
+               [Category ("LLVMNotWorking")]
                public void TestGetFileLineNumber ()
                {
                        Assert.AreEqual (0,
                                                         frame1.GetFileLineNumber (),
                                                         "Line number (1)");
 
-                       Assert.AreEqual (260,
+                       Assert.AreEqual (264,
                                                         frame2.GetFileLineNumber (),
                                                         "Line number (2)");
                }
index 7714f53ab3251892b0f2e34cb38ca2f20cbcacb3..45fd5d0e99ce526876998635219099707db107f0 100644 (file)
@@ -599,5 +599,122 @@ namespace MonoTests.System.Globalization
                        // https://bugzilla.xamarin.com/show_bug.cgi?id=3471
                        new CultureInfo ("en-HK");
                }
+
+#if NET_4_5
+               CountdownEvent barrier = new CountdownEvent (3);
+               AutoResetEvent[] evt = new AutoResetEvent [] { new AutoResetEvent (false), new AutoResetEvent (false), new AutoResetEvent (false)};
+
+               CultureInfo[] initial_culture = new CultureInfo[3];
+               CultureInfo[] changed_culture = new CultureInfo[3];
+               CultureInfo[] changed_culture2 = new CultureInfo[3];
+               CultureInfo alternative_culture = new CultureInfo("pt-BR");
+
+               void StepAllPhases (int index)
+               {
+                       initial_culture [index] = CultureInfo.CurrentCulture;
+                       /*Phase 1 - we witness the original value */
+                       barrier.Signal ();
+
+                       /*Phase 2 - main thread changes culture */
+                       evt [index].WaitOne ();
+
+                       /*Phase 3 - we witness the new value */
+                       changed_culture [index] = CultureInfo.CurrentCulture;
+                       barrier.Signal ();
+
+                       /* Phase 4 - main thread changes culture back */
+                       evt [index].WaitOne ();
+
+                       /*Phase 5 - we witness the new value */
+                       changed_culture2 [index] = CultureInfo.CurrentCulture;
+                       barrier.Signal ();
+               }
+
+               void ThreadWithoutChange () {
+                       StepAllPhases (0);
+               }
+
+               void ThreadWithChange () {
+                       Thread.CurrentThread.CurrentCulture = alternative_culture;
+                       StepAllPhases (1);
+               }
+
+               void ThreadPoolWithoutChange () {
+                       StepAllPhases (2);
+               }
+
+               [Test]
+               public void DefaultThreadCurrentCulture () {
+                       var orig_culture = CultureInfo.CurrentCulture;
+                       var new_culture = new CultureInfo("fr-FR");
+
+                       // The test doesn't work if the current culture is already set
+                       if (orig_culture != CultureInfo.InvariantCulture)
+                               return;
+
+                       /* Phase 0 - warm up */
+                       new Thread (ThreadWithoutChange).Start ();
+                       new Thread (ThreadWithChange).Start ();
+                       Action x = ThreadPoolWithoutChange;
+                       x.BeginInvoke (null, null);
+
+                       /* Phase 1 - let everyone witness initial values */
+                       initial_culture [0] = CultureInfo.CurrentCulture;
+                       barrier.Wait ();
+                       barrier.Reset ();
+
+                       /* Phase 2 - change the default culture*/
+                       CultureInfo.DefaultThreadCurrentCulture = new_culture;
+                       evt [0].Set ();
+                       evt [1].Set ();
+                       evt [2].Set ();
+                       /* Phase 3 - let everyone witness the new value */
+                       changed_culture [0] = CultureInfo.CurrentCulture;
+                       barrier.Wait ();
+                       barrier.Reset ();
+
+                       /* Phase 4 - revert the default culture back to null */
+                       CultureInfo.DefaultThreadCurrentCulture = null;
+                       evt [0].Set ();
+                       evt [1].Set ();
+                       evt [2].Set ();
+
+                       /* Phase 5 - let everyone witness the new value */
+                       changed_culture2 [0] = CultureInfo.CurrentCulture;
+                       barrier.Wait ();
+                       barrier.Reset ();
+
+                       CultureInfo.DefaultThreadCurrentCulture = null;
+
+                       Assert.AreEqual (orig_culture, initial_culture [0], "#2");
+                       Assert.AreEqual (alternative_culture, initial_culture [1], "#3");
+                       Assert.AreEqual (orig_culture, initial_culture [2], "#4");
+
+                       Assert.AreEqual (new_culture, changed_culture [0], "#6");
+                       Assert.AreEqual (alternative_culture, changed_culture [1], "#7");
+                       Assert.AreEqual (new_culture, changed_culture [2], "#8");
+
+                       Assert.AreEqual (orig_culture, changed_culture2 [0], "#10");
+                       Assert.AreEqual (alternative_culture, changed_culture2 [1], "#11");
+                       Assert.AreEqual (orig_culture, changed_culture2 [2], "#12");
+               }
+
+               [Test]
+               public void DefaultThreadCurrentCultureAndNumberFormaters () {
+                       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");
+                       });
+                       thread.Start ();
+                       thread.Join ();
+                       CultureInfo.DefaultThreadCurrentCulture = null;
+                       Assert.AreEqual ("$100,000.00", us_str, "#1");
+                       Assert.AreEqual ("R$ 100.000,00", br_str, "#2");
+               }
+#endif
        }
 }
diff --git a/mcs/class/corlib/Test/System.Globalization/NumberFormatInfoTest.cs b/mcs/class/corlib/Test/System.Globalization/NumberFormatInfoTest.cs
new file mode 100644 (file)
index 0000000..a195c28
--- /dev/null
@@ -0,0 +1,57 @@
+//
+// NumberFormatInfoTest.cs
+//
+// Authors:
+//     Marek Safar (marek.safar@gmail.com)
+//
+// Copyright (C) 2013 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 NUnit.Framework;
+using System;
+using System.Globalization;
+
+namespace MonoTests.System.Globalization
+{
+       [TestFixture]
+       public class NumberFormatInfoTest
+       {
+               [Test]
+               public void CurrencyDecimalDigits ()
+               {
+                       CultureInfo c;
+                       
+                       c = CultureInfo.GetCultureInfo ("id-ID");
+                       Assert.AreEqual (0, c.NumberFormat.CurrencyDecimalDigits, "#1");
+
+                       c = CultureInfo.GetCultureInfo ("is-IS");
+                       Assert.AreEqual (0, c.NumberFormat.CurrencyDecimalDigits, "#2");
+
+                       c = CultureInfo.InvariantCulture;
+                       Assert.AreEqual (2, c.NumberFormat.CurrencyDecimalDigits, "#3");
+
+               }
+       }
+}
+
+
index 5113cc5e981c7d4b88c367641a700f993237639d..9629dacf4b9ed9dfc4c02243941c19a7a9a8ef84 100644 (file)
@@ -24,10 +24,11 @@ public class TextInfoTest {
        {
                TextInfo ti = new CultureInfo ("en-US", false).TextInfo;
 
-               Assert.AreEqual (" The Dog", ti.ToTitleCase (" the dog"));
-               Assert.AreEqual (" The Dude", ti.ToTitleCase (" The Dude"));
-               Assert.AreEqual ("La Guerra Yla Paz", ti.ToTitleCase ("la Guerra yLa pAz"));
-               Assert.AreEqual ("\tTab\tAnd\tPeace", ti.ToTitleCase ("\ttab\taNd\tpeaCE"));
+               Assert.AreEqual (" The Dog", ti.ToTitleCase (" the dog"), "#1");
+               Assert.AreEqual (" The Dude", ti.ToTitleCase (" The Dude"), "#2");
+               Assert.AreEqual ("La Guerra Yla Paz", ti.ToTitleCase ("la Guerra yLa pAz"), "#3");
+               Assert.AreEqual ("\tTab\tAnd\tPeace", ti.ToTitleCase ("\ttab\taNd\tpeaCE"), "#4");
+               Assert.AreEqual ("This_Is\uFE58A\u0095String\u06D4With\uFE33Separators", ti.ToTitleCase ("this_is\uFE58a\u0095string\u06D4with\uFE33separators"), "#5");
        }
 
        [Test]
index 692a7359500622c068f317586d46d5af8814beae..7953d46250754b08061cced9561e6feba632e974 100644 (file)
@@ -11074,5 +11074,53 @@ namespace MonoTests.System.Reflection.Emit
                        Activator.CreateInstance (t, new object[] { "string"});
                }
 
+               public interface IFace16096 {
+                       object Bar ();
+               }
+
+               [Test]
+               public void MemberRef_Caching_16096 () {
+                       var outer_class = module.DefineType(
+                               "container",
+                               TypeAttributes.Class | TypeAttributes.Public,
+                               typeof(object));
+
+                       var builder = outer_class.DefineNestedType(
+                               "bind@32-1",
+                               TypeAttributes.Class | TypeAttributes.Public,
+                               typeof(object));
+
+                       builder.AddInterfaceImplementation (typeof (IFace16096));
+
+                       var ctor = builder.DefineDefaultConstructor (MethodAttributes.Public);
+                       var field = builder.DefineField ("Field", typeof (object), FieldAttributes.Public);
+                       var g_args = builder.DefineGenericParameters("b","a");
+                       var method = builder.DefineMethod ("Bar", MethodAttributes.Public | MethodAttributes.Virtual, typeof (object), new Type [0]);
+
+                       var il = method.GetILGenerator();
+                       il.Emit (OpCodes.Ldarg_0);
+                       il.Emit (OpCodes.Ldfld, TypeBuilder.GetField (builder.MakeGenericType (g_args), field));
+                       il.Emit (OpCodes.Pop);
+                       il.Emit (OpCodes.Newobj, TypeBuilder.GetConstructor (builder.MakeGenericType (g_args), ctor));
+                       il.Emit (OpCodes.Ret);
+
+                       var type = builder.CreateType ();
+
+                       /*Build a gshared instance. */
+                       var ginst = type.MakeGenericType (typeof (List<char>), typeof (object));
+                       var ins = (IFace16096)Activator.CreateInstance (ginst);
+
+                       /* This will trigger the runtime to cache the MEMBER_REF to the .ctor as it won't have a context. */
+                       var ins2 = ins.Bar ();
+                       Assert.IsNotNull (ins2);
+
+                       /* Build an unsharable version. */
+                       var ginst2 = type.MakeGenericType (typeof (List<char>), typeof (char));
+                       var ins3 = (IFace16096)Activator.CreateInstance (ginst2);
+
+                       /* This will trigger the runtime to use the cached version, which is wrong as it's an open type. */
+                       var ins4 = ins3.Bar ();
+                       Assert.IsNotNull (ins4);
+               }
        }
 }
index 48f629adface65b5d690e707af73fd8c1bb957c9..18b2099b8dd5fa9e00ff893ee5c6688648192ae8 100644 (file)
@@ -33,12 +33,45 @@ using System.Threading;
 using System.Threading.Tasks;
 using NUnit.Framework;
 using System.Runtime.CompilerServices;
+using System.Collections.Generic;
 
 namespace MonoTests.System.Runtime.CompilerServices
 {
        [TestFixture]
        public class TaskAwaiterTest
        {
+               class Scheduler : TaskScheduler
+               {
+                       string name;
+
+                       public Scheduler (string name)
+                       {
+                               this.name = name;
+                       }
+
+                       public int InlineCalls { get; set; }
+                       public int QueueCalls { get; set; }
+
+                       protected override IEnumerable<Task> GetScheduledTasks ()
+                       {
+                               throw new NotImplementedException ();
+                       }
+
+                       protected override void QueueTask (Task task)
+                       {
+                               ++QueueCalls;
+                               ThreadPool.QueueUserWorkItem (o => {
+                                       TryExecuteTask (task);
+                               });
+                       }
+
+                       protected override bool TryExecuteTaskInline (Task task, bool taskWasPreviouslyQueued)
+                       {
+                               ++InlineCalls;
+                               return false;
+                       }
+               }
+
                [Test]
                public void GetResultFaulted ()
                {
@@ -85,6 +118,72 @@ namespace MonoTests.System.Runtime.CompilerServices
                        awaiter.GetResult ();
                        Assert.AreEqual (TaskStatus.RanToCompletion, task.Status);
                }
+
+               [Test]
+               public void CustomScheduler ()
+               {
+                       // some test runners (e.g. Touch.Unit) will execute this on the main thread and that would lock them
+                       if (!Thread.CurrentThread.IsBackground)
+                               return;
+
+                       var a = new Scheduler ("a");
+                       var b = new Scheduler ("b");
+
+                       var t = TestCS (a, b);
+                       Assert.IsTrue (t.Wait (3000), "#0");
+                       Assert.AreEqual (0, t.Result, "#1");
+                       Assert.AreEqual (1, a.InlineCalls, "#2a");
+                       Assert.AreEqual (0, b.InlineCalls, "#2b");
+                       Assert.AreEqual (2, a.QueueCalls, "#3a");
+                       Assert.AreEqual (1, b.QueueCalls, "#3b");
+               }
+
+               static async Task<int> TestCS (TaskScheduler schedulerA, TaskScheduler schedulerB)
+               {
+                       var res = await Task.Factory.StartNew (async () => {
+                               if (TaskScheduler.Current != schedulerA)
+                                       return 1;
+
+                               await Task.Factory.StartNew (
+                                       () => {
+                                               if (TaskScheduler.Current != schedulerB)
+                                                       return 2;
+
+                                               return 0;
+                                       }, CancellationToken.None, TaskCreationOptions.None, schedulerB);
+
+                               if (TaskScheduler.Current != schedulerA)
+                                       return 3;
+
+                               return 0;
+                       }, CancellationToken.None, TaskCreationOptions.None, schedulerA);
+
+                       return res.Result;
+               }
+
+               [Test]
+               public void FinishedTaskOnCompleted ()
+               {
+                       var mres = new ManualResetEvent (false);
+                       var mres2 = new ManualResetEvent (false);
+
+                       var tcs = new TaskCompletionSource<object> ();
+                       tcs.SetResult (null);
+                       var task = tcs.Task;
+
+                       var awaiter = task.GetAwaiter ();
+                       Assert.IsTrue (awaiter.IsCompleted, "#1");
+
+                       awaiter.OnCompleted(() => { 
+                               if (mres.WaitOne (1000))
+                                       mres2.Set ();
+                       });
+
+                       mres.Set ();
+                       // this will only terminate correctly if the test was not executed from the main thread
+                       // e.g. Touch.Unit defaults to run tests on the main thread and this will return false
+                       Assert.AreEqual (Thread.CurrentThread.IsBackground, mres2.WaitOne (2000), "#2");;
+               }
        }
 }
 
index f0f87a898f2868de95cf2e7d324f6e7cdaf08c4e..857841e326ff72a4535ffcd095975c31b2c6857f 100644 (file)
@@ -604,16 +604,24 @@ namespace MonoTests.System.Threading.Tasks
                [Test]
                public void StartNewCancelled ()
                {
-                       var cts = new CancellationTokenSource ();
-                       cts.Cancel ();
+                       var ct = new CancellationToken (true);
 
-                       var task = factory.StartNew (() => Assert.Fail ("Should never be called"), cts.Token);
+                       var task = factory.StartNew (() => Assert.Fail ("Should never be called"), ct);
                        try {
                                task.Start ();
+                               Assert.Fail ("#1");
                        } catch (InvalidOperationException) {
                        }
 
                        Assert.IsTrue (task.IsCanceled, "#2");
+
+                       task = factory.StartNew (() => { }, ct);
+                       try {
+                               task.Wait ();
+                       } catch (AggregateException e) {
+                               Assert.IsTrue (task.IsCanceled, "#3");
+                               Assert.That (e.InnerException, Is.TypeOf (typeof (TaskCanceledException)), "#4");
+                       }
                }
        }
 }
index 0c30a093b03e1f30e010b5b4141f1794cffb6118..ff964bb9cfcc65e348b234958455b37394d8e901 100644 (file)
@@ -33,6 +33,9 @@ using System.Threading;
 using System.Threading.Tasks;
 
 using NUnit.Framework;
+#if !MOBILE
+using NUnit.Framework.SyntaxHelpers;
+#endif
 
 namespace MonoTests.System.Threading.Tasks
 {
@@ -249,6 +252,29 @@ namespace MonoTests.System.Threading.Tasks
                        Assert.AreEqual ("1", task.Result, "#2");
                }
 
+               [Test]
+               public void StartNewCancelled ()
+               {
+                       var ct = new CancellationToken (true);
+                       var factory = new TaskFactory<int> ();
+
+                       var task = factory.StartNew (() => { Assert.Fail ("Should never be called"); return 1; }, ct);
+                       try {
+                               task.Start ();
+                               Assert.Fail ("#1");
+                       } catch (InvalidOperationException) {
+                       }
+
+                       Assert.IsTrue (task.IsCanceled, "#2");
+
+                       task = factory.StartNew (() => 1, ct);
+                       try {
+                               task.Wait ();
+                       } catch (AggregateException e) {
+                               Assert.IsTrue (task.IsCanceled, "#3");
+                               Assert.That (e.InnerException, Is.TypeOf (typeof (TaskCanceledException)), "#4");
+                       }
+               }
        }
 }
 
index feff0e8b06f234afa871dfb8c18570b201ba566a..f61a64d4aa0f89fceb29833e418b9910cafabce2 100644 (file)
@@ -1149,6 +1149,16 @@ namespace MonoTests.System.Threading.Tasks
                        }
                }
 
+               [Test]
+               public void WhenAll_Empty ()
+               {
+                       var tasks = new Task[0];
+
+                       Task t = Task.WhenAll(tasks);
+
+                       Assert.IsTrue(t.Wait(1000), "#1");
+               }
+
                [Test]
                public void WhenAll_WithNull ()
                {
@@ -1274,6 +1284,18 @@ namespace MonoTests.System.Threading.Tasks
                        Assert.IsTrue (t.Wait (1000), "#2");
                }
 
+               [Test]
+               public void WhenAllResult_Empty ()
+               {
+                       var tasks = new Task<int>[0];
+
+                       Task<int[]> t = Task.WhenAll(tasks);
+
+                       Assert.IsTrue(t.Wait(1000), "#1");
+                       Assert.IsNotNull(t.Result, "#2");
+                       Assert.AreEqual(t.Result.Length, 0, "#3");
+               }
+
                [Test]
                public void WhenAllResult_WithNull ()
                {
index 6f9c23fc5fb660504723d290123b0bbf9d42bee6..df0a77631c48df292285e3825469656dbaae39a0 100644 (file)
@@ -66,6 +66,8 @@ namespace MonoTests.System.Threading
                }
 
                [Test] // bug #81529
+               // Causes a Attempting to unref unused handle 0x2 warning
+               [Category ("NotWorking")]
                public void Handle_Valid ()
                {
                        AutoResetEvent are1 = new AutoResetEvent (false);
index 9e795120020b85881cd822ca74b8a4ad86069104..2fa3d91a04fcd6512470d47c00c270ea9d5d0a33 100644 (file)
@@ -67,6 +67,66 @@ namespace MonoTests.System.Threading {
                {
                        if (ExecutionContext.IsFlowSuppressed ())
                                ExecutionContext.RestoreFlow ();
+
+                       CallContext.FreeNamedDataSlot ("testlc");
+               }
+
+               [Test]
+               [Category("MobileNotWorking")]
+               public void LogicalGetData_SetData()
+               {
+                       var value = "a";
+
+                       CallContext.SetData ("testlc", value);
+                       var capturedValue = CallContext.LogicalGetData ("testlc");
+
+                       Assert.IsNull (capturedValue);
+               }
+               
+               [Test]
+               [Category("MobileNotWorking")]
+               public void LogicalGetData_SetDataLogicalThreadAffinative()
+               {
+                       var value = new CallContextValue ("a");
+
+                       CallContext.SetData ("testlc", value);
+                       var capturedValue = CallContext.LogicalGetData ("testlc");
+
+                       Assert.AreEqual (value, capturedValue);
+               }
+
+               [Test]
+               [Category("MobileNotWorking")]
+               public void GetData_SetLogicalData()
+               {
+                       var value = "a";
+
+                       CallContext.LogicalSetData ("testlc", value);
+                       var capturedValue = CallContext.GetData ("testlc");
+
+                       Assert.AreEqual (value, capturedValue);
+               }
+
+               [Test]
+               [Category("MobileNotWorking")]
+               public void CaptureLogicalCallContext()
+               {
+                       var value = "Tester";
+                       object capturedValue = null;
+
+                       CallContext.LogicalSetData ("testlc", value);
+
+                       ExecutionContext ec = ExecutionContext.Capture ();
+                       Assert.IsNotNull (ec, "Capture");
+                       Assert.AreEqual (value, CallContext.LogicalGetData ("testlc"));
+                       CallContext.LogicalSetData ("testlc", null);
+
+                       ExecutionContext.Run (ec, new ContextCallback (new Action<object> ((data) => {
+                               capturedValue = CallContext.LogicalGetData ("testlc");
+                       })), null);
+
+                       Assert.AreEqual (value, capturedValue);
+                       Assert.AreNotEqual (value, CallContext.LogicalGetData ("testlc"));
                }
 
                [Test]
@@ -92,6 +152,7 @@ namespace MonoTests.System.Threading {
                }
 
                [Test]
+               [Category("MobileNotWorking")]
                public void Capture ()
                {
                        ExecutionContext ec = ExecutionContext.Capture ();
@@ -109,6 +170,7 @@ namespace MonoTests.System.Threading {
                }
 
                [Test]
+               [Category("MobileNotWorking")]
                public void Copy ()
                {
                        ExecutionContext ec = ExecutionContext.Capture ();
@@ -138,6 +200,7 @@ namespace MonoTests.System.Threading {
                }
 
                [Test]
+               [Category("MobileNotWorking")]
                public void IsFlowSuppressed ()
                {
                        Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
@@ -151,12 +214,14 @@ namespace MonoTests.System.Threading {
 
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
+               [Category("MobileNotWorking")]
                public void RestoreFlow_None ()
                {
                        ExecutionContext.RestoreFlow ();
                }
 
                [Test]
+               [Category("MobileNotWorking")]
                public void RestoreFlow_SuppressFlow ()
                {
                        Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
@@ -177,6 +242,7 @@ namespace MonoTests.System.Threading {
 
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
+               [Category("MobileNotWorking")]
                public void Run_SuppressFlow ()
                {
                        Assert.IsFalse (ExecutionContext.IsFlowSuppressed ());
@@ -191,6 +257,7 @@ namespace MonoTests.System.Threading {
                }
 
                [Test]
+               [Category("MobileNotWorking")]
                public void SuppressFlow ()
                {
                        Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
@@ -204,6 +271,7 @@ namespace MonoTests.System.Threading {
 
                [Test]
                [ExpectedException (typeof (InvalidOperationException))]
+               [Category("MobileNotWorking")]
                public void SuppressFlow_Two_Undo ()
                {
                        Assert.IsFalse (ExecutionContext.IsFlowSuppressed (), "IsFlowSuppressed-1");
index 1d88666538f50e9ec25e0f6acd9a61fd6a1d4ac3..9c950226391ce42bf60a5e48f7c724be13bab6ba 100644 (file)
@@ -2073,7 +2073,6 @@ namespace MonoTests.System
                                AppDomain.CurrentDomain.ExecuteAssembly (
                                        assembly.Location);
                                Assert.Fail ("#1");
-#if NET_2_0
                        } catch (MissingMethodException ex) {
                                // Entry point not found in assembly '...'
                                Assert.AreEqual (typeof (MissingMethodException), ex.GetType (), "#2");
@@ -2081,15 +2080,6 @@ namespace MonoTests.System
                                Assert.IsNotNull (ex.Message, "#4");
                                Assert.IsTrue (ex.Message.IndexOf (assembly.FullName) != -1, "#5");
                        }
-#else
-                       } catch (COMException ex) {
-                               // Unspecified error
-                               Assert.AreEqual (typeof (COMException), ex.GetType (), "#2");
-                               Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
-                               Assert.IsNull (ex.InnerException, "#4");
-                               Assert.IsNotNull (ex.Message, "#5");
-                       }
-#endif
                }
 
                [Test] // ExecuteAssembly (String, Evidence)
@@ -2102,7 +2092,6 @@ namespace MonoTests.System
                                        assembly.Location,
                                        (Evidence) null);
                                Assert.Fail ("#1");
-#if NET_2_0
                        } catch (MissingMethodException ex) {
                                // Entry point not found in assembly '...'
                                Assert.AreEqual (typeof (MissingMethodException), ex.GetType (), "#2");
@@ -2110,15 +2099,6 @@ namespace MonoTests.System
                                Assert.IsNotNull (ex.Message, "#4");
                                Assert.IsTrue (ex.Message.IndexOf (assembly.FullName) != -1, "#5");
                        }
-#else
-                       } catch (COMException ex) {
-                               // Unspecified error
-                               Assert.AreEqual (typeof (COMException), ex.GetType (), "#2");
-                               Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
-                               Assert.IsNull (ex.InnerException, "#4");
-                               Assert.IsNotNull (ex.Message, "#5");
-                       }
-#endif
                }
 
                [Test] // ExecuteAssembly (String, Evidence, String [])
@@ -2132,7 +2112,6 @@ namespace MonoTests.System
                                        (Evidence) null,
                                        new string [0]);
                                Assert.Fail ("#1");
-#if NET_2_0
                        } catch (MissingMethodException ex) {
                                // Entry point not found in assembly '...'
                                Assert.AreEqual (typeof (MissingMethodException), ex.GetType (), "#2");
@@ -2140,15 +2119,6 @@ namespace MonoTests.System
                                Assert.IsNotNull (ex.Message, "#4");
                                Assert.IsTrue (ex.Message.IndexOf (assembly.FullName) != -1, "#5");
                        }
-#else
-                       } catch (COMException ex) {
-                               // Unspecified error
-                               Assert.AreEqual (typeof (COMException), ex.GetType (), "#2");
-                               Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
-                               Assert.IsNull (ex.InnerException, "#4");
-                               Assert.IsNotNull (ex.Message, "#5");
-                       }
-#endif
                }
 
                [Test] // ExecuteAssembly (String, Evidence, String [], Byte [], AssemblyHashAlgorithm)
@@ -2165,7 +2135,6 @@ namespace MonoTests.System
                                        (byte []) null,
                                        AssemblyHashAlgorithm.SHA1);
                                Assert.Fail ("#1");
-#if NET_2_0
                        } catch (MissingMethodException ex) {
                                // Entry point not found in assembly '...'
                                Assert.AreEqual (typeof (MissingMethodException), ex.GetType (), "#2");
@@ -2173,15 +2142,6 @@ namespace MonoTests.System
                                Assert.IsNotNull (ex.Message, "#4");
                                Assert.IsTrue (ex.Message.IndexOf (assembly.FullName) != -1, "#5");
                        }
-#else
-                       } catch (COMException ex) {
-                               // Unspecified error
-                               Assert.AreEqual (typeof (COMException), ex.GetType (), "#2");
-                               Assert.AreEqual (-2147467259, ex.ErrorCode, "#3");
-                               Assert.IsNull (ex.InnerException, "#4");
-                               Assert.IsNotNull (ex.Message, "#5");
-                       }
-#endif
                }
 
                [Test] // bug #79720
@@ -3044,14 +3004,9 @@ namespace MonoTests.System
                        try {
                                AppDomain.CurrentDomain.Load (aname);
                                Assert.Fail ("#C9");
-#if NET_2_0
                        } catch (SecurityException) {
                                // Invalid assembly public key
                        }
-#else
-                       } catch (FileLoadException) {
-                       }
-#endif
 
                        aname = new AssemblyName ();
                        aname.Name = "bug79522C";
@@ -3212,6 +3167,30 @@ namespace MonoTests.System
                        // we have no public way to get the default appdomain
                }
 
+               static bool resolve_called;
+
+               [Test]
+               public void AssemblyResolveParseError ()
+               {
+                       AppDomain currentDomain = AppDomain.CurrentDomain;
+                       ResolveEventHandler d = ParseErrorResolve;
+                       currentDomain.AssemblyResolve += d;
+                       try {
+                               resolve_called = false;
+                               var a = Assembly.Load ("MyDynamicType, 1.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756");
+                               Assert.Fail ();
+                       } catch (FileNotFoundException) {
+                               Assert.IsTrue (resolve_called);
+                       }
+                       currentDomain.AssemblyResolve -= d;
+               }
+
+               static Assembly ParseErrorResolve (object sender, ResolveEventArgs args)
+               {
+                       resolve_called = true;
+                       return null;
+               }
+
                [Test]
                public void ReflectionOnlyGetAssemblies ()
                {
index 6a4d8ae78f9bdd650a017acc5726317bca222ff8..28588f8e008664c9ee0dc501fa0ae6e27db06dec 100644 (file)
@@ -260,6 +260,24 @@ namespace MonoTests.System
                        s[1] = -3;
                        Assert.AreEqual (-3, s[1], "#2a");
                }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void IList_IndexerErrorTest1 ()
+               {
+                       byte[] arr = new byte[4];
+                       IList<byte> seg = new ArraySegment<byte> (arr, 1, 2);
+                       seg[-1] = 3;
+               }
+
+               [Test]
+               [ExpectedException (typeof (ArgumentOutOfRangeException))]
+               public void IList_IndexerErrorTest2 ()
+               {
+                       byte[] arr = new byte[4];
+                       IList<byte> seg = new ArraySegment<byte> (arr);
+                       seg[4] = 3;
+               }
 #endif
        }
 }
index f8fe8cd7a001f294a54e2f7bdd0b0aec37e917d0..10fb4fcbce6264d613150950882ec40c562e7b4d 100644 (file)
@@ -88,6 +88,13 @@ namespace MonoTests.System
                class MyDerivedClassNoAttribute : MyClass
                {
                }
+
+               internal class AttributeWithTypeId : Attribute
+               {
+                       public override object TypeId {
+                               get { return this; }
+                       }
+               }
        }
 
        [TestFixture]
@@ -998,6 +1005,14 @@ namespace MonoTests.System
                        MyOwnCustomAttribute b1 = new MyOwnCustomAttribute (null);
                        Assert.AreNotEqual (a1.GetHashCode (), b1.GetHashCode (), "non-identical-types");
                }
+
+               [Test]
+               public void GetHashCodeWithOverriddenTypeId ()
+               {
+                       //check for not throwing stack overflow exception
+                       AttributeWithTypeId a = new AttributeWithTypeId ();
+                       a.GetHashCode ();
+               }
        }
 
        namespace ParamNamespace {
index 4d675d51e61222f380b9dda52886dffb3536607c..4403fd6346bf0c9433bc4f3c2a9a6877ddb708c2 100644 (file)
@@ -122,6 +122,32 @@ public class TimeZoneTest {
                Assert.AreEqual(0L, t1.GetUtcOffset (d5).Ticks, "D14");
        }
 
+       private void NZST(TimeZone t1) {
+               Assert.AreEqual("NZST", t1.StandardName, "E01");
+               Assert.AreEqual("NZDT", t1.DaylightName, "E02");
+
+               DaylightTime d1 = t1.GetDaylightChanges (2013);
+               Assert.AreEqual("09/29/2013 02:00:00", d1.Start.ToString ("G"), "E03");
+               Assert.AreEqual("04/07/2013 03:00:00", d1.End.ToString ("G"), "E04");
+               Assert.AreEqual(36000000000L, d1.Delta.Ticks, "E05");
+
+               DaylightTime d2 = t1.GetDaylightChanges (2001);
+               Assert.AreEqual("10/07/2001 02:00:00", d2.Start.ToString ("G"), "E06");
+               Assert.AreEqual("03/18/2001 03:00:00", d2.End.ToString ("G"), "E07");
+               Assert.AreEqual(36000000000L, d2.Delta.Ticks, "E08");
+
+               DateTime d3 = new DateTime(2013,02,15);
+               Assert.AreEqual(true, t1.IsDaylightSavingTime (d3), "E09");
+               DateTime d4 = new DateTime(2013,04,30);
+               Assert.AreEqual(false, t1.IsDaylightSavingTime (d4), "E10");
+               DateTime d5 = new DateTime(2013,11,03);
+               Assert.AreEqual(true, t1.IsDaylightSavingTime (d5), "E11");
+
+               Assert.AreEqual(36000000000L /*hour*/ * 13L, t1.GetUtcOffset (d3).Ticks, "E12");
+               Assert.AreEqual(36000000000L /*hour*/ * 12L, t1.GetUtcOffset (d4).Ticks, "E13");
+               Assert.AreEqual(36000000000L /*hour*/ * 13L, t1.GetUtcOffset (d5).Ticks, "E14");
+       }
+
        [Test]
        [Culture ("")]
        public void TestCtors ()
@@ -141,6 +167,9 @@ public class TimeZoneTest {
                        case "GMT":
                                GMT (t1);
                                break;
+                       case "NZST":
+                               NZST (t1);
+                               break;
                        default:
                                NUnit.Framework.Assert.Ignore ("Your time zone (" + t1.StandardName + ") isn't defined in the test case");
                                break;
@@ -251,6 +280,45 @@ public class TimeZoneTest {
                Assert.IsTrue (tz.ToLocalTime (dst_start_utc.Add (new TimeSpan (1, 0, 0))) < tz.ToLocalTime (dst_start_utc.Add (new TimeSpan (1, 1, 0))), "0:4:00 < 0:4:01");
        }
 
+               [Test]
+               public void GetUtcOffsetAtDSTBoundary ()
+               {
+                       /*
+                        * Getting a definitive list of timezones which do or don't observe Daylight
+                        * Savings is difficult (can't say America's or USA definitively) and lengthy see 
+                        *
+                        * http://en.wikipedia.org/wiki/Daylight_saving_time_by_country
+                        *
+                        * as a good starting point for a list.
+                        *
+                        * The following are SOME of the timezones/regions which do support daylight savings.
+                        *
+                        * Pacific/Auckland
+                        * Pacific/Sydney
+                        * USA (EST, CST, MST, PST, AKST) note this does not cover all states or regions
+                        * Europe/London (GMT)
+                        * CET (member states of the European Union)
+                        *
+                        * This test should work in all the above timezones
+                        */
+
+
+                       TimeZone tz = TimeZone.CurrentTimeZone;
+                       DaylightTime daylightChanges = tz.GetDaylightChanges(2007);
+                       DateTime dst_end = daylightChanges.End;
+
+                       if (dst_end == DateTime.MinValue)
+                               Assert.Ignore (tz.StandardName + " did not observe daylight saving time during 2007.");
+
+                       var standardOffset = tz.GetUtcOffset(daylightChanges.Start.AddMinutes(-1));
+
+                       Assert.AreEqual(standardOffset, tz.GetUtcOffset (dst_end));
+                       Assert.AreEqual(standardOffset, tz.GetUtcOffset (dst_end.Add (daylightChanges.Delta.Negate ().Add (TimeSpan.FromSeconds(1)))));
+                       Assert.AreEqual(standardOffset, tz.GetUtcOffset (dst_end.Add(daylightChanges.Delta.Negate ())));
+                       Assert.AreNotEqual(standardOffset, tz.GetUtcOffset (dst_end.Add(daylightChanges.Delta.Negate ().Add (TimeSpan.FromSeconds(-1)))));
+               }
+
+
                [Test]
                public void StaticProperties ()
                {
index bc726ce38fd7a611a00c39f5b2dd8702bcf80067..8972880062692c9fb0a14cc09e6dce1de7d5505b 100644 (file)
@@ -4024,6 +4024,25 @@ PublicKeyToken=b77a5c561934e089"));
                }
 #endif
 
+               [Test]
+               public void GetTypeParseGenericCorrectly () { //Bug #15124
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1"), typeof (Foo<>), "#1");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32]"), typeof (Foo<int>), "#2");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[[System.Int32]]"), typeof (Foo<int>), "#3");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32][]"), typeof (Foo<int>[]), "#4");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[][System.Int32]"), null, "#5");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32][,]"), typeof (Foo<int>[,]), "#6");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[]"), typeof (Foo<>).MakeArrayType(), "#7");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[,]"), typeof (Foo<>).MakeArrayType (2), "#8");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[][]"), typeof (Foo<>).MakeArrayType ().MakeArrayType (), "#9");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1["), null, "#10");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[["), null, "#11");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[[]"), null, "#12");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[,"), null, "#13");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[*"), null, "#14");
+                       Assert.AreEqual (Type.GetType ("MonoTests.System.Foo`1[System.Int32"), null, "#15");
+               }
+
                public abstract class Stream : IDisposable
                {
                        public void Dispose ()
index f581c0d5e599fc34ad44eb38c948ae69647d2664..3bab3edb7f8d9495a371fcf13a5b0ae8bb1ef975 100644 (file)
@@ -925,6 +925,18 @@ System.Runtime.InteropServices.ComTypes/VARDESC.cs
 System.Runtime.InteropServices.ComTypes/VARFLAGS.cs
 System.Runtime.InteropServices.ComTypes/VARKIND.cs
 System.Runtime.InteropServices.Expando/IExpando.cs
+System.Runtime.InteropServices.WindowsRuntime/DefaultInterfaceAttribute.cs
+System.Runtime.InteropServices.WindowsRuntime/DesignerNamespaceResolveEventArgs.cs
+System.Runtime.InteropServices.WindowsRuntime/EventRegistrationToken.cs
+System.Runtime.InteropServices.WindowsRuntime/EventRegistrationTokenTable.cs
+System.Runtime.InteropServices.WindowsRuntime/IActivationFactory.cs
+System.Runtime.InteropServices.WindowsRuntime/InterfaceImplementedInVersionAttribute.cs
+System.Runtime.InteropServices.WindowsRuntime/NamespaceResolveEventArgs.cs
+System.Runtime.InteropServices.WindowsRuntime/ReadOnlyArrayAttribute.cs
+System.Runtime.InteropServices.WindowsRuntime/ReturnValueNameAttribute.cs
+System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMarshal.cs
+System.Runtime.InteropServices.WindowsRuntime/WindowsRuntimeMetadata.cs
+System.Runtime.InteropServices.WindowsRuntime/WriteOnlyArrayAttribute.cs
 System.Runtime.Remoting/ActivatedClientTypeEntry.cs
 System.Runtime.Remoting/ActivatedServiceTypeEntry.cs
 System.Runtime.Remoting/CustomErrorsModes.cs
index 51c354cc224645f7dbcba742086312519e6d66df..5cd15e5de427f45a22fed0a7a84428ca5d1e455e 100644 (file)
@@ -56,6 +56,7 @@ System/DecimalFormatterTest.cs
 System/DecimalTest2.cs
 System/DecimalTest.cs
 System.Diagnostics/DebuggerDisplayAttributeTest.cs
+System.Diagnostics/DebuggerTypeProxyAttribute.cs
 System.Diagnostics/StackFrameTest.cs
 System.Diagnostics/StackTraceTest.cs
 System.Diagnostics.Contracts/ContractAssertTest.cs
@@ -79,6 +80,7 @@ System.Globalization/DateTimeFormatInfoTest.cs
 System.Globalization/DaylightTimeTest.cs
 System.Globalization/EastAsianLunisolarCalendarTest.cs
 System.Globalization/IdnMappingTest.cs
+System.Globalization/NumberFormatInfoTest.cs
 System.Globalization/RegionInfoTest.cs
 System.Globalization/SortKeyTest.cs
 System.Globalization/StringInfoTest.cs
index d4f9cc2665bdf9c046ad971e524ac0b529712b4d..a065daf212cb7236746681b46d36d89d663761d3 100644 (file)
@@ -240,7 +240,7 @@ namespace Monodoc.Generators.Html
 
                static void ClearUntil (StateInfo s, string required)
                {
-                       string e;
+                       string e = null;
                        while (s.tags.Count > 0 && 
                               (e = s.tags.Peek ().ToString ()) != required) {
                                s.output.Append (s.tags.Pop ().ToString ());
index 341f439b9688f2c15bce15f1aceee8d58cc12f9a..97937fc442a54a5ef4c3961541b42f1d2a99a010 100644 (file)
@@ -10,7 +10,6 @@
 }
 
 p {
-       text-align: justify;
        margin-top: .5em;
        margin-bottom: .5em;
 }
diff --git a/mcs/errors/CS0246-29-lib.il b/mcs/errors/CS0246-29-lib.il
new file mode 100644 (file)
index 0000000..27709d4
--- /dev/null
@@ -0,0 +1,25 @@
+.assembly extern mscorlib
+{
+}
+
+.assembly extern 'missing'
+{
+  .ver 0:0:0:0
+}
+
+.assembly 'CS0246-29-lib'
+{
+  .hash algorithm 0x00008004
+  .ver 0:0:0:0
+}
+
+.module 'CS0246-29-lib.dll'
+
+.class extern forwarder A
+{
+  .assembly extern 'missing'
+}
+.class extern B
+{
+  .class extern A
+}
\ No newline at end of file
diff --git a/mcs/errors/CS0731-1-lib.il b/mcs/errors/CS0731-1-lib.il
new file mode 100644 (file)
index 0000000..d130a15
--- /dev/null
@@ -0,0 +1,21 @@
+.assembly extern mscorlib
+{
+}
+
+.assembly extern 'CS0731-2-lib'
+{
+  .ver 0:0:0:0
+}
+
+.assembly 'CS0731-1-lib'
+{
+  .hash algorithm 0x00008004
+  .ver 0:0:0:0
+}
+
+.module 'CS0731-1-lib.dll'
+
+.class extern forwarder A
+{
+  .assembly extern 'CS0731-2-lib'
+}
diff --git a/mcs/errors/CS0731-2-lib.il b/mcs/errors/CS0731-2-lib.il
new file mode 100644 (file)
index 0000000..ded95c7
--- /dev/null
@@ -0,0 +1,21 @@
+.assembly extern mscorlib
+{
+}
+
+.assembly extern 'CS0731-1-lib'
+{
+  .ver 0:0:0:0
+}
+
+.assembly 'CS0731-2-lib'
+{
+  .hash algorithm 0x00008004
+  .ver 0:0:0:0
+}
+
+.module 'CS0731-2-lib.dll'
+
+.class extern forwarder A
+{
+  .assembly extern 'CS0731-1-lib'
+}
\ No newline at end of file
index d4487ff8443af9646584e689d8ae7154d6aa8aa1..620077130783fb54d0bf3e7f6a7cb9af2c835d29 100644 (file)
@@ -14,7 +14,7 @@
 
 .module 'CS1070-lib.dll'
 
-.class extern forwarder E
+.class extern forwarder N.E
 {
   .assembly extern 'CS1070-lib-missing'
 }
index 756d130359a64a00c933e61a0301bee7edac65d2..036f7aee5191e79ae42a6e9579d1cb126d24db7a 100644 (file)
@@ -23,13 +23,13 @@ DISTFILES = \
 TEST_SUPPORT_FILES = \
        CS0012-lib.dll CS0012-2-lib.dll CS0012-3-lib.dll CS0012-4-lib.dll CS0012-5-lib.dll CS0012-6-lib.dll CS0012-9-lib.dll CS0012-10-lib.dll CS0012-11-lib.dll CS0012-12-lib.dll CS0012-13-lib.dll CS0012-14-lib.dll CS0012-15-lib.dll CS0012-16-lib.dll CS0012-17-lib.dll CS0012-18-lib.dll CS0012-21-lib.dll CS0029-26-lib.dll \
        CS0103-2-lib.dll CS0118-2-lib.dll CS0122-8-lib.dll CS0122-10-lib.dll CS0122-14-lib.dll CS0122-15-lib.dll CS0122-19-lib.dll CS0122-35-lib.dll CS0122-36-lib.dll CS0143-lib.dll CS0144-3-lib.dll CS0165-19-lib.dll \
-       CS0205-3-lib.dll CS0229-3-lib.dll CS0229-4-lib.dll CS0266-25-lib.dll \
+       CS0205-3-lib.dll CS0246-29-lib.dll CS0229-3-lib.dll CS0229-4-lib.dll CS0266-25-lib.dll \
        CS0315-2-lib.dll \
        CS0425-7-lib.dll CS0433-lib.dll CS0433-2-lib.dll \
        CS0506-3-lib.dll CS0507-7-lib.dll CS0507-8-lib.dll CS0534-3-lib.dll CS0534-4-lib.dll CS0534-6-lib.dll CS0571-3-lib.dll CS0571-5-lib.dll CS0571-6-lib.dll \
        CS0612-2-lib.dll CS0618-2-lib.dll CS0619-8-lib.dll CS0619-17-lib.dll CS0619-32-lib.dll CS0619-33-lib.dll CS0619-36-lib.dll CS0619-42-lib.dll \
        CS0619-43-lib.dll CS1546-lib.dll CS0619-51-lib.dll CS1509-module.dll CS1681-2-lib.dll \
-       CS0730-lib.dll \
+       CS0730-lib.dll CS0731-1-lib.dll CS0731-2-lib.dll \
        CS1070-lib.dll \
        CS1540-15-lib.dll CS1540-17-lib.dll CS1542-lib.dll CS1577-lib.dll \
        CS1607-3-lib.dll CS1683-lib.dll CS1684-lib.dll CS1685-2-lib.dll \
diff --git a/mcs/errors/cs0035-2.cs b/mcs/errors/cs0035-2.cs
new file mode 100644 (file)
index 0000000..12d91ef
--- /dev/null
@@ -0,0 +1,33 @@
+// CS0035: Operator `++' is ambiguous on an operand of type `MyType'
+// Line: 31
+
+public class MyType
+{
+       public static implicit operator float (MyType v)
+       {
+               return 0;
+       }
+
+       public static implicit operator decimal (MyType v)
+       {
+               return 0;
+       }
+
+       public static implicit operator MyType (float v)
+       {
+               return null;
+       }
+
+       public static implicit operator MyType (decimal v)
+       {
+               return null;
+       }
+}
+
+class Test
+{
+       static void test (MyType x)
+       {
+               x++;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0103-12.cs b/mcs/errors/cs0103-12.cs
new file mode 100644 (file)
index 0000000..9e2274c
--- /dev/null
@@ -0,0 +1,11 @@
+// CS0103: The name `bar' does not exist in the current context
+// Line: 8
+
+public class Test
+{
+       static void Main ()
+       {
+               if (false && bar ()) {
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0104-3.cs b/mcs/errors/cs0104-3.cs
new file mode 100644 (file)
index 0000000..95e116e
--- /dev/null
@@ -0,0 +1,33 @@
+// CS0104: `X' is an ambiguous reference between `A.X' and `B.X'
+// Line: 25
+
+namespace A
+{
+       class X { }
+}
+
+namespace B
+{
+       class X { }
+}
+
+namespace C
+{
+       using System;
+       using A;
+       using B;
+
+       class Test 
+       {
+               static void Main ()
+               {
+                       Foo (delegate {
+                               X x;
+                       });
+               }
+               
+               static void Foo (Action a)
+               {
+               }
+       }
+}
diff --git a/mcs/errors/cs0104-4.cs b/mcs/errors/cs0104-4.cs
new file mode 100644 (file)
index 0000000..9072d99
--- /dev/null
@@ -0,0 +1,25 @@
+// CS0104: `XAttribute' is an ambiguous reference between `A.XAttribute' and `B.XAttribute'
+// Line: 21
+
+using System;
+
+namespace A
+{
+       class XAttribute : Attribute { }
+}
+
+namespace B
+{
+       class XAttribute : Attribute { }
+}
+
+namespace C
+{
+       using A;
+       using B;
+
+       [X]
+       class Test 
+       {
+       }
+}
diff --git a/mcs/errors/cs0126-2.cs b/mcs/errors/cs0126-2.cs
new file mode 100644 (file)
index 0000000..c472df7
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0126: An object of a type convertible to `string' is required for the return statement
+// Line: 7
+
+using System.Threading.Tasks;
+
+class A
+{
+       static async Task<string> Test ()
+       {
+               await CallAsync ();
+               return;
+       }
+       
+       static Task<string> CallAsync ()
+       {
+               return null;
+       }
+}
diff --git a/mcs/errors/cs0161-4.cs b/mcs/errors/cs0161-4.cs
deleted file mode 100644 (file)
index faeaf57..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-// CS0161: `T.Main()': not all code paths return a value
-// Line: 6
-// CSC bug: The error is not reported even if it should as in other unreachable cases
-
-class T {
-       public static int Main ()
-       {
-               switch (1) {
-               case 1:
-                       return 0;
-               default:
-                       break;
-               }
-       }
-}
diff --git a/mcs/errors/cs0162-17.cs b/mcs/errors/cs0162-17.cs
deleted file mode 100644 (file)
index 821c741..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-// CS0162: Unreachable code detected
-// Line: 10
-// Compiler options: -warnaserror
-
-public class X
-{
-       public static void Main ()
-       {
-               return;
-               1+1;
-       }
-}
\ No newline at end of file
diff --git a/mcs/errors/cs0162-20.cs b/mcs/errors/cs0162-20.cs
new file mode 100644 (file)
index 0000000..e2bb4dc
--- /dev/null
@@ -0,0 +1,21 @@
+// CS0162: Unreachable code detected
+// Line: 14
+// Compiler options: -warnaserror
+
+using System;
+
+class X
+{
+
+       public static void Main ()
+       {
+               goto X;
+       A:
+               bool b = false;
+               if (b) {
+                       goto A;
+               }
+       X:
+               return;
+       }
+}
\ No newline at end of file
index d8ae75fb0c50b0a238eff8e0999cd4c1a8dd97ac..3eb8bcfdb3f5adc8a90bff945f19218a319522bc 100644 (file)
@@ -2,9 +2,6 @@
 // Line: 9
 // Compiler options: -warnaserror -warn:2
 
-// this requires a multi-pass algorithm for unreachable code detection
-// punting for now
-
 class Foo {
        static void Main ()
        {
diff --git a/mcs/errors/cs0163-2.cs b/mcs/errors/cs0163-2.cs
new file mode 100644 (file)
index 0000000..dfdd9c1
--- /dev/null
@@ -0,0 +1,20 @@
+// CS0163: Control cannot fall through from one case label `case 1:' to another
+// Line: 14
+
+using System;
+using System.Collections.Generic;
+
+static class C
+{
+       public static IEnumerable<int> Test (int key)
+       {
+               switch (key) {
+               case 1:
+                       yield return 0;
+               case 2:
+                       yield return 2;
+               default:
+                       throw new ArgumentOutOfRangeException ("symbol:" + key);
+               }
+       }
+}
\ No newline at end of file
index 7596a4fceae1d81e68bf8eb4759dfdc805682510..1f65f60490e53176c04c189e6e0466e1ae0ab355 100644 (file)
@@ -1,6 +1,5 @@
-// CS0163: Control cannot fall through from one case label to another
-// Line: 17
-
+// CS0163: Control cannot fall through from one case label `case 3:' to another
+// Line: 21
 
 public class Foo
 {
diff --git a/mcs/errors/cs0165-22.cs b/mcs/errors/cs0165-22.cs
new file mode 100644 (file)
index 0000000..6b76beb
--- /dev/null
@@ -0,0 +1,34 @@
+// CS0165: Use of unassigned local variable `x'
+// Line: 17
+
+using System;
+
+class Program
+{
+       static int Main ()
+       {
+               int foo = 9;
+               int x;
+
+               switch (foo) {
+               case 1:
+                       x = 1;
+                       gotoTarget: 
+                       {
+                               Console.WriteLine (x);
+                       }
+                       break;
+               default:
+                       {
+                               if (foo != 0) {
+                                       goto gotoTarget;
+                               }
+
+                               break;
+                       }
+               }
+
+               return 1;
+       }
+}
+
diff --git a/mcs/errors/cs0165-23.cs b/mcs/errors/cs0165-23.cs
new file mode 100644 (file)
index 0000000..8c947a2
--- /dev/null
@@ -0,0 +1,23 @@
+// CS0165: Use of unassigned local variable `retval'
+// Line: 9
+
+class Test
+{
+       static string DoStuff (string msg)
+       {
+               string retval;
+
+               switch (msg) {
+               case "hello":
+                       retval = "goodbye";
+                       return retval;
+               case "goodbye":
+                       return retval;
+               case "other":
+                       retval = "other";
+               case "":
+                       return msg;
+               }
+               return "";
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-24.cs b/mcs/errors/cs0165-24.cs
new file mode 100644 (file)
index 0000000..cbc9c97
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 14
+
+class X
+{
+       public static void Main ()
+       {
+               int i = 3;
+               switch (i) {
+               case 1:
+                       float a = 7.0f;
+                       break;
+               default:
+                       float b = a + 99.0f;
+                       break;
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-25.cs b/mcs/errors/cs0165-25.cs
new file mode 100644 (file)
index 0000000..8ffe586
--- /dev/null
@@ -0,0 +1,24 @@
+// CS0165: Use of unassigned local variable `trial'
+// Line: 18
+
+using System;
+
+class Test
+{
+       public static void Main (string[] args)
+       {
+               bool trial;
+               string action = "add_trial";
+
+               switch (action) {
+               case "add_trial":
+                       trial = true;
+                       goto case "add_to_project";
+               case "add_to_project":
+                       Console.WriteLine (trial);
+                       break;
+               case "test":
+                       break;
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-26.cs b/mcs/errors/cs0165-26.cs
new file mode 100644 (file)
index 0000000..b144218
--- /dev/null
@@ -0,0 +1,15 @@
+// CS0165: Use of unassigned local variable `eh'
+// Line: 12
+
+using System;
+
+public class E
+{
+       public static void Main ()
+       {
+               EventHandler eh;
+               eh = delegate {
+                       Console.WriteLine (eh);
+               };
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-27.cs b/mcs/errors/cs0165-27.cs
new file mode 100644 (file)
index 0000000..db34dd8
--- /dev/null
@@ -0,0 +1,15 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 13
+
+using System;
+
+class Program
+{
+       public static void Main (string[] args)
+       {
+               int a, b;
+               string s = "";
+               var res = s != null ? a = 1 : b = 2;
+               Console.WriteLine (a);
+       }
+}
diff --git a/mcs/errors/cs0165-28.cs b/mcs/errors/cs0165-28.cs
new file mode 100644 (file)
index 0000000..4b22f7d
--- /dev/null
@@ -0,0 +1,15 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 13
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+               var res = s == null || ((a = 1) > 0);
+               Console.WriteLine (a);
+       }
+}
diff --git a/mcs/errors/cs0165-29.cs b/mcs/errors/cs0165-29.cs
new file mode 100644 (file)
index 0000000..238093d
--- /dev/null
@@ -0,0 +1,12 @@
+// CS0165: Use of unassigned local variable `j'
+// Line: 10
+
+class Test
+{
+       static void Main ()
+       {
+               int? i;
+               int? j;
+               int? x = (i = 7) ?? j;
+    }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-30.cs b/mcs/errors/cs0165-30.cs
new file mode 100644 (file)
index 0000000..c800aff
--- /dev/null
@@ -0,0 +1,11 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 9
+
+using System;
+
+class Test {
+       
+       static void Main () {
+               Action a = () => a();
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-31.cs b/mcs/errors/cs0165-31.cs
new file mode 100644 (file)
index 0000000..07759cb
--- /dev/null
@@ -0,0 +1,11 @@
+// CS0165: Use of unassigned local variable `i'
+// Line: 9
+
+public class MainClass
+{
+       public void Foo ()
+       {
+               int i;
+               i++;
+       }
+}
diff --git a/mcs/errors/cs0165-32.cs b/mcs/errors/cs0165-32.cs
new file mode 100644 (file)
index 0000000..fb96522
--- /dev/null
@@ -0,0 +1,16 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 9
+
+class C
+{
+       static void Main ()
+       {
+               int a;
+               Foo (out a, a);
+       }
+
+       static void Foo (out int a, int b)
+       {
+               a = b;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-33.cs b/mcs/errors/cs0165-33.cs
new file mode 100644 (file)
index 0000000..16afc7d
--- /dev/null
@@ -0,0 +1,20 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 13
+
+using System;
+using System.Diagnostics;
+
+class C
+{
+       static int Main ()
+       {
+               int a;
+               Foo (a = 9);
+               return a;
+       }
+
+       [Conditional ("MISSING")]
+       static void Foo (int value)
+       {
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0165-34.cs b/mcs/errors/cs0165-34.cs
new file mode 100644 (file)
index 0000000..229f472
--- /dev/null
@@ -0,0 +1,17 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+
+               if (s != "s" || (a = 4) > 3) {
+                       Console.WriteLine (a);
+               }
+       }
+}
diff --git a/mcs/errors/cs0165-35.cs b/mcs/errors/cs0165-35.cs
new file mode 100644 (file)
index 0000000..ad3604f
--- /dev/null
@@ -0,0 +1,19 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+
+               if (s != "s" && (a = 4) > 3) {
+                       return;
+               }
+               
+               Console.WriteLine (a);
+       }
+}
diff --git a/mcs/errors/cs0165-36.cs b/mcs/errors/cs0165-36.cs
new file mode 100644 (file)
index 0000000..594eafc
--- /dev/null
@@ -0,0 +1,17 @@
+// CS0165: Use of unassigned local variable `s'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               string s;
+               object o = null;
+               while (o != null && string.IsNullOrEmpty (s = (string) o.ToString ())) {
+               }
+               
+               Console.WriteLine (s);
+       }
+}
diff --git a/mcs/errors/cs0165-37.cs b/mcs/errors/cs0165-37.cs
new file mode 100644 (file)
index 0000000..cb56118
--- /dev/null
@@ -0,0 +1,16 @@
+// CS0165: Use of unassigned local variable `s'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               string s;
+               object o = null;
+               while (o != null || string.IsNullOrEmpty (s = (string) o.ToString ())) {
+                       Console.WriteLine (s);
+               }
+       }
+}
diff --git a/mcs/errors/cs0165-38.cs b/mcs/errors/cs0165-38.cs
new file mode 100644 (file)
index 0000000..20fc409
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 16
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+
+               do {
+               } while (s != "s" && (a = 4) > 3);
+
+               Console.WriteLine (a);
+       }
+}
diff --git a/mcs/errors/cs0165-39.cs b/mcs/errors/cs0165-39.cs
new file mode 100644 (file)
index 0000000..c5da9d6
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 16
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+
+               for (int i = 0; s != "s" && (a = 4) > 3; ++i) {
+               }
+
+               Console.WriteLine (a);
+       }
+}
diff --git a/mcs/errors/cs0165-40.cs b/mcs/errors/cs0165-40.cs
new file mode 100644 (file)
index 0000000..690cdae
--- /dev/null
@@ -0,0 +1,17 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+
+               if (!(s != "s" && (a = 4) > 3)) {
+                       Console.WriteLine (a);
+               }
+       }
+}
diff --git a/mcs/errors/cs0165-41.cs b/mcs/errors/cs0165-41.cs
new file mode 100644 (file)
index 0000000..b1242a0
--- /dev/null
@@ -0,0 +1,15 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               int a;
+               string s = "";
+
+               var res = (s == "" && (a = 4) > 3) ? 1 : a;
+       }
+}
diff --git a/mcs/errors/cs0165-42.cs b/mcs/errors/cs0165-42.cs
new file mode 100644 (file)
index 0000000..81de0cf
--- /dev/null
@@ -0,0 +1,16 @@
+// CS0165: Use of unassigned local variable `a'
+// Line: 14
+
+using System;
+
+class Program
+{
+       public static void Main ()
+       {
+               object a;
+               string s = null;
+
+               var res = s ?? (a = null);
+               Console.WriteLine (a);
+       }
+}
diff --git a/mcs/errors/cs0165-43.cs b/mcs/errors/cs0165-43.cs
new file mode 100644 (file)
index 0000000..b4762ab
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0165: Use of unassigned local variable `g'
+// Line: 10
+
+public class A
+{
+       static bool Test7 ()
+       {
+               int f = 1;
+               int g;
+               return f > 1 && OutCall (out g) || g > 1;
+       }
+
+       static bool OutCall (out int arg)
+       {
+               arg = 1;
+               return false;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0171-6.cs b/mcs/errors/cs0171-6.cs
new file mode 100644 (file)
index 0000000..e968f1a
--- /dev/null
@@ -0,0 +1,18 @@
+// CS0171: Field `S.value' must be fully assigned before control leaves the constructor
+// Line: 10
+
+using System;
+
+struct S
+{
+       string value;
+
+       public S (int arg)
+       {
+               if (arg > 0) {
+                       return;
+               }
+
+               throw new ApplicationException ();
+       }
+}
diff --git a/mcs/errors/cs0177-14.cs b/mcs/errors/cs0177-14.cs
new file mode 100644 (file)
index 0000000..103bf7a
--- /dev/null
@@ -0,0 +1,22 @@
+// CS0177: The out parameter `val' must be assigned to before control leaves the current method
+// Line: 12
+
+public class A
+{
+       public bool GetValue (out int val)
+       {
+               val = 0;
+               return true;
+       }
+
+       public void ReallyGetValue (out int val)
+       {
+               if (AlwaysReturnTrue () || GetValue (out val)) {
+               }
+       }
+
+       public bool AlwaysReturnTrue ()
+       {
+               return true;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0201-10.cs b/mcs/errors/cs0201-10.cs
new file mode 100644 (file)
index 0000000..a76e80a
--- /dev/null
@@ -0,0 +1,11 @@
+// CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
+// Line: 9
+
+public class X
+{
+       public static void Main ()
+       {
+               return;
+               1+1;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0201-11.cs b/mcs/errors/cs0201-11.cs
new file mode 100644 (file)
index 0000000..536ee24
--- /dev/null
@@ -0,0 +1,12 @@
+// CS0201: Only assignment, call, increment, decrement, await, and new object expressions can be used as a statement
+// Line: 10
+
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               new Func<int> (() => 0);
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0246-29.cs b/mcs/errors/cs0246-29.cs
new file mode 100644 (file)
index 0000000..051b956
--- /dev/null
@@ -0,0 +1,10 @@
+// CS0246: The type or namespace name `B' could not be found. Are you missing an assembly reference?
+// Line: 8
+
+class X
+{
+       public static void Main ()
+       {
+               B b;
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs0411-15.cs b/mcs/errors/cs0411-15.cs
deleted file mode 100644 (file)
index ed39e45..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// CS0411: The type arguments for method `C.Foo<T>(IFoo<T>, IFoo<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly
-// Line: 17
-
-interface IFoo<in T>
-{
-}
-
-class C
-{
-       public static void Foo<T> (IFoo<T> e1, IFoo<T> e2)
-       {
-       }
-       
-       public static void Main ()
-       {
-               IFoo<int> a = null;
-               IFoo<object> b = null;
-               Foo (a, b);
-       }
-}
diff --git a/mcs/errors/cs0411-6.cs b/mcs/errors/cs0411-6.cs
deleted file mode 100644 (file)
index c6e7ffd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-// CS0411: The type arguments for method `Hello.World<U>(U, IFoo<U>)' cannot be inferred from the usage. Try specifying the type arguments explicitly
-// Line: 16
-public interface IFoo<T>
-{ }
-
-public class Foo : IFoo<int>, IFoo<string>
-{ }
-
-public class Hello
-{
-       public void World<U> (U u, IFoo<U> foo)
-       { }
-
-       public void Test (Foo foo)
-       {
-               World ("Canada", foo);
-       }
-}
-
-class X
-{
-       static void Main ()
-       {
-       }
-}
diff --git a/mcs/errors/cs0411-7.cs b/mcs/errors/cs0411-7.cs
deleted file mode 100644 (file)
index c22648e..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-// CS0411: The type arguments for method `C.Foo<T>(T, System.Collections.Generic.Comparer<T>)' cannot be inferred from the usage. Try specifying the type arguments explicitly
-// Line: 20
-
-using System;
-using System.Collections.Generic;
-
-public class C
-{
-       static void Foo<T>(T t, Comparer<T> tc)
-       {
-       }
-       
-       static int Compare (int a, int b)
-       {
-               return -1;
-       }
-       
-       public static void Main ()
-       {
-               Foo (1, Compare);
-       }
-}
diff --git a/mcs/errors/cs0429-4.cs b/mcs/errors/cs0429-4.cs
new file mode 100644 (file)
index 0000000..d808039
--- /dev/null
@@ -0,0 +1,14 @@
+// CS0429: Unreachable expression code detected
+// Line: 12
+// Compiler options: -warnaserror
+
+public class X
+{
+       static void test (int stop)
+       {
+               int pos = 0;
+               do {
+                       break;
+               } while (pos < stop);
+       }
+}
diff --git a/mcs/errors/cs0534-11.cs b/mcs/errors/cs0534-11.cs
new file mode 100644 (file)
index 0000000..7d67ac6
--- /dev/null
@@ -0,0 +1,17 @@
+// CS0534: `Foo' does not implement inherited abstract member `SomeAbstract.SomeProperty.get'
+// Line: 13
+
+public class SomeProperty
+{
+}
+
+public abstract class SomeAbstract
+{
+       public abstract SomeProperty SomeProperty { get; }
+}
+
+public class Foo : SomeAbstract
+{
+       public static SomeProperty SomeProperty { get { return null; } }
+}
+
diff --git a/mcs/errors/cs0540-3.cs b/mcs/errors/cs0540-3.cs
new file mode 100644 (file)
index 0000000..99f5f5e
--- /dev/null
@@ -0,0 +1,27 @@
+// CS0540: `Foo.ISomeProp.SomeProperty': containing type does not implement interface `ISomeProp'
+// Line: 18
+
+public class SomeProperty
+{
+}
+
+public abstract class SomeAbstract : ISomeProp
+{
+       public abstract SomeProperty SomeProperty { get; }
+}
+
+interface ISomeProp
+{
+       SomeProperty SomeProperty { get; }
+}
+
+public class Foo : SomeAbstract
+{
+       SomeProperty ISomeProp.SomeProperty { get { return null; } }
+
+       public override SomeProperty SomeProperty { get { return null; } }
+
+       public static void Main ()
+       {
+       }
+}
diff --git a/mcs/errors/cs0731.cs b/mcs/errors/cs0731.cs
new file mode 100644 (file)
index 0000000..4eb3553
--- /dev/null
@@ -0,0 +1,11 @@
+// CS0731: The type forwarder for type `A' in assembly `CS0731-2-lib, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' has circular dependency
+// Line: 9
+// Compiler options: -r:CS0731-1-lib.dll -r:CS0731-2-lib.dll
+
+class Test
+{
+       static void Main ()
+       {
+               new A ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1061-14.cs b/mcs/errors/cs1061-14.cs
new file mode 100644 (file)
index 0000000..e5c3db5
--- /dev/null
@@ -0,0 +1,25 @@
+// CS1061: Type `string' does not contain a definition for `Name' and no extension method `Name' of type `string' could be found. Are you missing an assembly reference?
+// Line: 18
+
+using System;
+
+static class X
+{
+       public static void Main ()
+       {
+       }
+
+       static void Foo ()
+       {
+               var fileName = "";
+               string[] all = null;
+
+               all.Each (x => {
+                       var name = fileName.Name;
+               });
+       }
+
+       static void Each<T> (this T[] s, Action<T> a)
+       {
+       }
+}
diff --git a/mcs/errors/cs1070-2.cs b/mcs/errors/cs1070-2.cs
new file mode 100644 (file)
index 0000000..7fe8760
--- /dev/null
@@ -0,0 +1,12 @@
+// CS1070: The type `N.E' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `CS1070-lib-missing, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
+// Line: 9
+// Compiler options: -r:CS1070-lib.dll
+
+using N;
+
+public class D
+{
+       public void Foo (E e)
+       {
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1503-14.cs b/mcs/errors/cs1503-14.cs
new file mode 100644 (file)
index 0000000..26422fa
--- /dev/null
@@ -0,0 +1,25 @@
+// CS1503: Argument `#2' cannot convert `IContravariant<object>' expression to type `ICovariant<string>'
+// Line: 23
+
+interface IContravariant<in T>
+{
+}
+
+interface ICovariant<out T>
+{
+}
+
+class C
+{
+       public static void Test<T> (ICovariant<T> e1, ICovariant<T> e2)
+       {
+       }
+
+       public static void Main ()
+       {
+               ICovariant<string> a_2 = null;
+               IContravariant<object> b_2 = null;
+
+               Test (a_2, b_2);
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1503-15.cs b/mcs/errors/cs1503-15.cs
new file mode 100644 (file)
index 0000000..4313fcf
--- /dev/null
@@ -0,0 +1,20 @@
+// CS1503: Argument `#2' cannot convert `IFoo<object>' expression to type `IFoo<int>'
+// Line: 18
+
+interface IFoo<in T>
+{
+}
+
+class C
+{
+       public static void Foo<T> (IFoo<T> e1, IFoo<T> e2)
+       {
+       }
+       
+       public static void Main ()
+       {
+               IFoo<int> a = null;
+               IFoo<object> b = null;
+               Foo (a, b);
+       }
+}
diff --git a/mcs/errors/cs1503-16.cs b/mcs/errors/cs1503-16.cs
new file mode 100644 (file)
index 0000000..24fa1e6
--- /dev/null
@@ -0,0 +1,22 @@
+// CS1503: Argument `#2' cannot convert `method group' expression to type `System.Collections.Generic.Comparer<int>'
+// Line: 20
+
+using System;
+using System.Collections.Generic;
+
+public class C
+{
+       static void Foo<T>(T t, Comparer<T> tc)
+       {
+       }
+       
+       static int Compare (int a, int b)
+       {
+               return -1;
+       }
+       
+       public static void Main ()
+       {
+               Foo (1, Compare);
+       }
+}
diff --git a/mcs/errors/cs1632-2.cs b/mcs/errors/cs1632-2.cs
new file mode 100644 (file)
index 0000000..fe6c1c2
--- /dev/null
@@ -0,0 +1,16 @@
+// CS1632: Control cannot leave the body of an anonymous method
+// Line: 12
+
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               while (true) {
+                       Action a = () => {
+                               break;
+                       };
+               }
+       }
+}
diff --git a/mcs/errors/cs1632-3.cs b/mcs/errors/cs1632-3.cs
new file mode 100644 (file)
index 0000000..b7e457b
--- /dev/null
@@ -0,0 +1,20 @@
+// CS1632: Control cannot leave the body of an anonymous method
+// Line: 14
+
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               int b = 0;
+               switch (b) {
+                       case 1:
+                       Action a = () => {
+                               break;
+                       };
+                       
+                       break;
+               }
+       }
+}
diff --git a/mcs/errors/cs1632-4.cs b/mcs/errors/cs1632-4.cs
new file mode 100644 (file)
index 0000000..a9127d5
--- /dev/null
@@ -0,0 +1,22 @@
+// CS1632: Control cannot leave the body of an anonymous method
+// Line: 14
+
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               int b = 0;
+               switch (b) {
+               case 1:
+                       Action a = () => {
+                               goto case 2;
+                       };
+                       
+                       break;
+               case 2:
+                       break;
+               }
+       }
+}
diff --git a/mcs/errors/cs1654-3.cs b/mcs/errors/cs1654-3.cs
new file mode 100644 (file)
index 0000000..c49e687
--- /dev/null
@@ -0,0 +1,25 @@
+// CS1654: Cannot assign to members of `f' because it is a `using variable'
+// Line: 22
+
+using System;
+
+struct Foo : IDisposable
+{
+       public int Property {
+               set { }
+       }
+
+       public void Dispose ()
+       {
+       }
+}
+
+class Bar
+{
+       static void Main ()
+       {
+               using (var f = new Foo ()) {
+                       f.Property = 0;
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/errors/cs1654-4.cs b/mcs/errors/cs1654-4.cs
new file mode 100644 (file)
index 0000000..c568dde
--- /dev/null
@@ -0,0 +1,25 @@
+// CS1654: Cannot assign to members of `f' because it is a `using variable'
+// Line: 22
+
+using System;
+
+struct Foo : IDisposable
+{
+       public int this[int arg] {
+               set { }
+       }
+
+       public void Dispose ()
+       {
+       }
+}
+
+class Bar
+{
+       static void Main ()
+       {
+               using (var f = new Foo ()) {
+                       f[0] = 1;
+               }
+       }
+}
\ No newline at end of file
index cbad5a36cf827d4e439d0aa053eac24762d86eea..a2f951235f75fc19955fb37374a3c73c59602f78 100644 (file)
 # Parser problems
 cs0080.cs 
 
-cs0162-7.cs NO ERROR
-cs0165-3.cs
-
 # Operators
 cs0457-2.cs
 cs0457.cs
+
+cs1060.cs NO ERROR
+cs1060-2.cs NO ERROR
+cs1060-3.cs NO ERROR
index 25a46efbf3180a5898d536eb0b2224a4bc0132f8..1e41fe720c93b8070f68ab8f983112df05f48dd3 100644 (file)
@@ -251,13 +251,13 @@ namespace Mono.ILASM {
 
         public class ExternClass
         {
-            string name;
+            string fullName;
             TypeAttr ta;
             string assemblyReference;
 
-            public ExternClass (string name, TypeAttr ta, string assemblyReference)
+            public ExternClass (string fullName, TypeAttr ta, string assemblyReference)
             {
-                this.name = name;
+                this.fullName = fullName;
                 this.ta = ta;
                 this.assemblyReference = assemblyReference;
             }
@@ -265,8 +265,18 @@ namespace Mono.ILASM {
             public void Resolve (CodeGen code_gen, ExternTable table)
             {
                 var ar = table.GetAssemblyRef (assemblyReference);
-                if (ar != null)
-                    code_gen.PEFile.AddExternClass (name, ta, ar.AssemblyRef);
+                if (ar != null) {
+                    string ns = null;
+                    string name = fullName;
+
+                    int pos = name.LastIndexOf ('.');
+                    if (pos > 0) {
+                        ns = name.Substring (0, pos);
+                        name = name.Substring (pos + 1);
+                    }
+                    code_gen.PEFile.AddExternClass (ns, name, ta, ar.AssemblyRef);
+                }
             }
         }
 
index 72a8a25b0f8ba8bf55e78ecbd91a2f5dc09ea7a5..c6cdbfea21cecf187d0435cbc29c636337f5d661 100644 (file)
@@ -3208,7 +3208,7 @@ exptype_head              : D_CLASS K_EXTERN expt_attr comp_name
                                        }\r
                        ;\r
 \r
-expt_attr              : /* EMPTY */\r
+expt_attr              : { $$ = 0; } /* EMPTY */\r
                        | expt_attr K_PRIVATE                   { $$ = (TypeAttr)$1 | TypeAttr.Private; }\r
                        | expt_attr K_PUBLIC                    { $$ = (TypeAttr)$1 | TypeAttr.Public; }\r
                        | expt_attr K_NESTED K_PUBLIC           { $$ = (TypeAttr)$1 | TypeAttr.NestedPublic; }\r
index 27b1485f56a92473f0ca42559ea8b3edb8b4620d..e5cb73dd94bebae71565fe5be8125122faa228ea 100644 (file)
@@ -214,6 +214,11 @@ namespace Mono.CSharp {
                                hoisted_this.EmitAssign (ec, source, false, false);
                        }
 
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               return false;
+                       }
+
                        protected override void CloneTo (CloneContext clonectx, Statement target)
                        {
                                // Nothing to clone
@@ -1339,13 +1344,6 @@ namespace Mono.CSharp {
                        if (!DoResolveParameters (ec))
                                return null;
 
-#if !STATIC
-                       // FIXME: The emitted code isn't very careful about reachability
-                       // so, ensure we have a 'ret' at the end
-                       BlockContext bc = ec as BlockContext;
-                       if (bc != null && bc.CurrentBranching != null && bc.CurrentBranching.CurrentUsageVector.IsUnreachable)
-                               bc.NeedReturnLabel ();
-#endif
                        return this;
                }
 
@@ -1521,12 +1519,28 @@ namespace Mono.CSharp {
                        }
 
                        var bc = ec as BlockContext;
-                       if (bc != null)
+
+                       if (bc != null) {
                                aec.AssignmentInfoOffset = bc.AssignmentInfoOffset;
+                               aec.EnclosingLoop = bc.EnclosingLoop;
+                               aec.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch;
+                               aec.Switch = bc.Switch;
+                       }
 
                        var errors = ec.Report.Errors;
 
-                       bool res = Block.Resolve (ec.CurrentBranching, aec, null);
+                       bool res = Block.Resolve (aec);
+
+                       if (res && errors == ec.Report.Errors) {
+                               MarkReachable (new Reachability ());
+
+                               if (!CheckReachableExit (ec.Report)) {
+                                       return null;
+                               }
+
+                               if (bc != null)
+                                       bc.AssignmentInfoOffset = aec.AssignmentInfoOffset;
+                       }
 
                        if (am != null && am.ReturnTypeInference != null) {
                                am.ReturnTypeInference.FixAllTypes (ec);
@@ -1557,6 +1571,47 @@ namespace Mono.CSharp {
                        return false;
                }
 
+               bool CheckReachableExit (Report report)
+               {
+                       if (block.HasReachableClosingBrace && ReturnType.Kind != MemberKind.Void) {
+                               // FIXME: Flow-analysis on MoveNext generated code
+                               if (!IsIterator) {
+                                       report.Error (1643, StartLocation,
+                                                       "Not all code paths return a value in anonymous method of type `{0}'", GetSignatureForError ());
+
+                                       return false;
+                               }
+                       }
+
+                       return true;
+               }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       // We are reachable, mark block body reachable too
+                       MarkReachable (new Reachability ());
+
+                       CheckReachableExit (fc.Report);
+
+                       var das = fc.BranchDefiniteAssignment ();
+                       var prev_pb = fc.ParametersBlock;
+                       fc.ParametersBlock = Block;
+                       var da_ontrue = fc.DefiniteAssignmentOnTrue;
+                       var da_onfalse = fc.DefiniteAssignmentOnFalse;
+
+                       block.FlowAnalysis (fc);
+
+                       fc.ParametersBlock = prev_pb;
+                       fc.DefiniteAssignment = das;
+                       fc.DefiniteAssignmentOnTrue = da_ontrue;
+                       fc.DefiniteAssignmentOnFalse = da_onfalse;
+               }
+
+               public override void MarkReachable (Reachability rc)
+               {
+                       block.MarkReachable (rc);
+               }
+
                public void SetHasThisAccess ()
                {
                        ExplicitBlock b = block;
index facb0eb28c092e4d3f0ecdab9071bd8524306aeb..13d0526cc2cd9c5a47e422bbdc2b9c763c2de9b4 100644 (file)
@@ -127,6 +127,29 @@ namespace Mono.CSharp
                        return this;
                }
 
+               public void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (ArgType == AType.Out) {
+                               var vr = Expr as VariableReference;
+                               if (vr != null) {
+                                       if (vr.VariableInfo != null)
+                                               fc.SetVariableAssigned (vr.VariableInfo);
+
+                                       return;
+                               }
+
+                               var fe = Expr as FieldExpr;
+                               if (fe != null) {
+                                       fe.SetFieldAssigned (fc);
+                                       return;
+                               }
+
+                               return;
+                       }
+
+                       Expr.FlowAnalysis (fc);
+               }
+
                public string GetSignatureForError ()
                {
                        if (Expr.eclass == ExprClass.MethodGroup)
@@ -152,18 +175,16 @@ namespace Mono.CSharp
 
                public void Resolve (ResolveContext ec)
                {
-//                     using (ec.With (ResolveContext.Options.DoFlowAnalysis, true)) {
-                               // Verify that the argument is readable
-                               if (ArgType != AType.Out)
-                                       Expr = Expr.Resolve (ec);
+                       // Verify that the argument is readable
+                       if (ArgType != AType.Out)
+                               Expr = Expr.Resolve (ec);
 
-                               // Verify that the argument is writeable
-                               if (Expr != null && IsByRef)
-                                       Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess);
+                       // Verify that the argument is writeable
+                       if (Expr != null && IsByRef)
+                               Expr = Expr.ResolveLValue (ec, EmptyExpression.OutAccess);
 
-                               if (Expr == null)
-                                       Expr = ErrorExpression.Instance;
-//                     }
+                       if (Expr == null)
+                               Expr = ErrorExpression.Instance;
                }
        }
 
@@ -476,6 +497,29 @@ namespace Mono.CSharp
                        return null;
                }
 
+               public void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       bool has_out = false;
+                       foreach (var arg in args) {
+                               if (arg.ArgType == Argument.AType.Out) {
+                                       has_out = true;
+                                       continue;
+                               }
+
+                               arg.FlowAnalysis (fc);
+                       }
+
+                       if (!has_out)
+                               return;
+
+                       foreach (var arg in args) {
+                               if (arg.ArgType != Argument.AType.Out)
+                                       continue;
+
+                               arg.FlowAnalysis (fc);
+                       }
+               }
+
                public List<Argument>.Enumerator GetEnumerator ()
                {
                        return args.GetEnumerator ();
index 49595edd0f473212d53faef69c0af454ae60bfbf..714e953be0052518939d5d21d537479379568620 100644 (file)
@@ -417,6 +417,14 @@ namespace Mono.CSharp {
                        Emit (ec, true);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       source.FlowAnalysis (fc);
+
+                       if (target is ArrayAccess || target is IndexerExpr || target is PropertyExpr)
+                               target.FlowAnalysis (fc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        Assign _target = (Assign) t;
@@ -465,6 +473,32 @@ namespace Mono.CSharp {
 
                        return this;
                }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       base.FlowAnalysis (fc);
+
+                       var vr = target as VariableReference;
+                       if (vr != null) {
+                               if (vr.VariableInfo != null)
+                                       fc.SetVariableAssigned (vr.VariableInfo);
+
+                               return;
+                       }
+
+                       var fe = target as FieldExpr;
+                       if (fe != null) {
+                               fe.SetFieldAssigned (fc);
+                               return;
+                       }
+               }
+
+               public override void MarkReachable (Reachability rc)
+               {
+                       var es = source as ExpressionStatement;
+                       if (es != null)
+                               es.MarkReachable (rc);
+               }
        }
 
        public class RuntimeExplicitAssign : Assign
@@ -521,20 +555,21 @@ namespace Mono.CSharp {
                // share same constructor (block) for expression trees resolve but
                // they have they own resolve scope
                //
-               sealed class FieldInitializerContext : ResolveContext
+               sealed class FieldInitializerContext : BlockContext
                {
-                       ExplicitBlock ctor_block;
+                       readonly ExplicitBlock ctor_block;
 
-                       public FieldInitializerContext (IMemberContext mc, ResolveContext constructorContext)
-                               : base (mc, Options.FieldInitializerScope | Options.ConstructorScope)
+                       public FieldInitializerContext (IMemberContext mc, BlockContext constructorContext)
+                               : base (mc, null, constructorContext.ReturnType)
                        {
+                               flags |= Options.FieldInitializerScope | Options.ConstructorScope;
                                this.ctor_block = constructorContext.CurrentBlock.Explicit;
                        }
 
                        public override ExplicitBlock ConstructorBlock {
-                               get {
-                                       return ctor_block;
-                               }
+                           get {
+                               return ctor_block;
+                           }
                        }
                }
 
@@ -552,21 +587,25 @@ namespace Mono.CSharp {
                                ((FieldExpr)target).InstanceExpression = new CompilerGeneratedThis (mc.CurrentType, expression.Location);
                }
 
+               public int AssignmentOffset { get; private set; }
+
                public override Location StartLocation {
                        get {
                                return loc;
                        }
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext rc)
                {
                        // Field initializer can be resolved (fail) many times
                        if (source == null)
                                return null;
 
+                       var bc = (BlockContext) rc;
                        if (resolved == null) {
-                               var ctx = new FieldInitializerContext (mc, ec);
+                               var ctx = new FieldInitializerContext (mc, bc);
                                resolved = base.DoResolve (ctx) as ExpressionStatement;
+                               AssignmentOffset = ctx.AssignmentInfoOffset - bc.AssignmentInfoOffset;
                        }
 
                        return resolved;
@@ -593,6 +632,11 @@ namespace Mono.CSharp {
                        else
                                base.EmitStatement (ec);
                }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       source.FlowAnalysis (fc);
+               }
                
                public bool IsDefaultInitializer {
                        get {
@@ -780,6 +824,12 @@ namespace Mono.CSharp {
                        return base.DoResolve (ec);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       target.FlowAnalysis (fc);
+                       source.FlowAnalysis (fc);
+               }
+
                protected override Expression ResolveConversions (ResolveContext ec)
                {
                        //
index daa0073136204c4679d02a28290e89e11654c31b..ca39017696d7a61b6d2b9dc650e7ffb903ff78c6 100644 (file)
@@ -65,8 +65,19 @@ namespace Mono.CSharp
                        return true;
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+
+                       stmt.RegisterResumePoint ();
+               }
+
                protected override Expression DoResolve (ResolveContext rc)
                {
+                       if (rc.HasSet (ResolveContext.Options.FinallyScope)) {
+                               rc.Report.Error (1984, loc,  "The `await' operator cannot be used in the body of a finally clause");
+                       }
+
                        if (rc.HasSet (ResolveContext.Options.LockScope)) {
                                rc.Report.Error (1996, loc,
                                        "The `await' operator cannot be used in the body of a lock statement");
@@ -115,6 +126,12 @@ namespace Mono.CSharp
                        stmt.EmitStatement (ec);
                }
 
+               public override void MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       stmt.MarkReachable (rc);
+               }
+
                public override object Accept (StructuralVisitor visitor)
                {
                        return visitor.Visit (this);
@@ -175,6 +192,7 @@ namespace Mono.CSharp
                public AwaitStatement (Expression expr, Location loc)
                        : base (expr, loc)
                {
+                       unwind_protect = true;
                }
 
                #region Properties
@@ -306,6 +324,10 @@ namespace Mono.CSharp
                                return false;
                        }
 
+                       if (bc.HasSet (ResolveContext.Options.CatchScope)) {
+                               bc.Report.Error (1985, loc, "The `await' operator cannot be used in the body of a catch clause");
+                       }
+
                        if (!base.Resolve (bc))
                                return false;
 
@@ -363,6 +385,47 @@ namespace Mono.CSharp
                }
        }
 
+       class AsyncInitializerStatement : StatementExpression
+       {
+               public AsyncInitializerStatement (AsyncInitializer expr)
+                       : base (expr)
+               {
+               }
+
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       base.DoFlowAnalysis (fc);
+
+                       var init = (AsyncInitializer) Expr;
+                       var res = !init.Block.HasReachableClosingBrace;
+                       var storey = (AsyncTaskStorey) init.Storey;
+
+                       if (storey.ReturnType.IsGenericTask)
+                               return res;
+
+                       return true;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (!rc.IsUnreachable)
+                               reachable = true;
+
+                       var init = (AsyncInitializer) Expr;
+                       rc = init.Block.MarkReachable (rc);
+
+                       var storey = (AsyncTaskStorey) init.Storey;
+
+                       //
+                       // Explicit return is required for Task<T> state machine
+                       //
+                       if (storey.ReturnType != null && storey.ReturnType.IsGenericTask)
+                               return rc;
+
+                   return Reachability.CreateUnreachable ();
+               }
+       }
+
        public class AsyncInitializer : StateMachineInitializer
        {
                TypeInferenceContext return_inference;
@@ -398,14 +461,15 @@ namespace Mono.CSharp
 
                #endregion
 
-               protected override BlockContext CreateBlockContext (ResolveContext rc)
+               protected override BlockContext CreateBlockContext (BlockContext bc)
                {
-                       var ctx = base.CreateBlockContext (rc);
-                       var lambda = rc.CurrentAnonymousMethod as LambdaMethod;
+                       var ctx = base.CreateBlockContext (bc);
+                       var lambda = bc.CurrentAnonymousMethod as LambdaMethod;
                        if (lambda != null)
                                return_inference = lambda.ReturnTypeInference;
 
-                       ctx.StartFlowBranching (this, rc.CurrentBranching);
+                       ctx.Set (ResolveContext.Options.TryScope);
+
                        return ctx;
                }
 
@@ -426,6 +490,13 @@ namespace Mono.CSharp
                        storey.EmitInitializer (ec);
                        ec.Emit (OpCodes.Ret);
                }
+
+               public override void MarkReachable (Reachability rc)
+               {
+                       //
+                       // Reachability has been done in AsyncInitializerStatement
+                       //
+               }
        }
 
        class AsyncTaskStorey : StateMachine
index 87174664d48c31202fac13d59a1e44b2e973b4d8..2a02757200f7a2479702eb542938a5627a7d88b1 100644 (file)
@@ -284,7 +284,8 @@ namespace Mono.CSharp {
                /// </summary>
                void ResolveAttributeType (bool comparisonOnly)
                {
-                       SessionReportPrinter resolve_printer = new SessionReportPrinter ();
+                       var resolve_printer = new SessionReportPrinter ();
+                       SessionReportPrinter secondary_printer = null;
                        ReportPrinter prev_recorder = Report.SetPrinter (resolve_printer);
 
                        bool t1_is_attr = false;
@@ -297,20 +298,25 @@ namespace Mono.CSharp {
 
                        try {
                                t1 = expression.ResolveAsType (context);
-                               if (t1 != null)
-                                       t1_is_attr = t1.IsAttribute;
-
                                resolve_printer.EndSession ();
 
+                               if (t1 != null && resolve_printer.ErrorsCount == 0)
+                                       t1_is_attr = t1.IsAttribute;
+
                                if (nameEscaped) {
                                        t2 = null;
                                } else {
                                        expanded = (ATypeNameExpression) expression.Clone (null);
                                        expanded.Name += "Attribute";
 
+                                       secondary_printer = new SessionReportPrinter ();
+                                       Report.SetPrinter (secondary_printer);
                                        t2 = expanded.ResolveAsType (context);
-                                       if (t2 != null)
+                                       secondary_printer.EndSession ();
+                                       if (t2 != null && secondary_printer.ErrorsCount == 0)
                                                t2_is_attr = t2.IsAttribute;
+
+                                       secondary_printer.EndSession ();
                                }
                        } finally {
                                context.Module.Compiler.Report.SetPrinter (prev_recorder);
@@ -341,17 +347,25 @@ namespace Mono.CSharp {
 
                        resolve_error = true;
 
-                       if (t1 != null) {
-                               resolve_printer.Merge (prev_recorder);
+                       if (t1 != null) {       
+                               if (resolve_printer.IsEmpty) {
+                                       Report.SymbolRelatedToPreviousError (t1);
+                                       Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
+                               } else {
+                                       resolve_printer.Merge (prev_recorder);
+                               }
 
-                               Report.SymbolRelatedToPreviousError (t1);
-                               Report.Error (616, Location, "`{0}': is not an attribute class", t1.GetSignatureForError ());
                                return;
                        }
 
                        if (t2 != null) {
-                               Report.SymbolRelatedToPreviousError (t2);
-                               Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
+                               if (secondary_printer.IsEmpty) {
+                                       Report.SymbolRelatedToPreviousError (t2);
+                                       Report.Error (616, Location, "`{0}': is not an attribute class", t2.GetSignatureForError ());
+                               } else {
+                                       secondary_printer.Merge (prev_recorder);
+                               }
+
                                return;
                        }
 
index 69c39d5be7a721f0950c56cfced70fd0a3734a52..0a46fd5b7ce8ae2ac0130b2a76e99c1ec00a5ccf 100644 (file)
@@ -692,6 +692,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                //
                // Returns true for secondary partial containers
                //
@@ -991,6 +997,7 @@ namespace Mono.CSharp
                                        if (!has_complex_initializer && fi.IsDefaultInitializer)
                                                continue;
 
+                                       ec.AssignmentInfoOffset += fi.AssignmentOffset;
                                        ec.CurrentBlock.AddScopeStatement (new StatementExpression (init [i]));
                                }
 
@@ -1012,6 +1019,7 @@ namespace Mono.CSharp
                                if (fi.IsDefaultInitializer && ec.Module.Compiler.Settings.Optimize)
                                        continue;
 
+                               ec.AssignmentInfoOffset += fi.AssignmentOffset;
                                ec.CurrentBlock.AddScopeStatement (new StatementExpression (s));
                        }
                }
@@ -2307,11 +2315,20 @@ namespace Mono.CSharp
                /// </summary>
                public bool VerifyImplements (InterfaceMemberBase mb)
                {
-                       var ifaces = spec.Interfaces;
+                       var ifaces = PartialContainer.Interfaces;
                        if (ifaces != null) {
                                foreach (TypeSpec t in ifaces){
                                        if (t == mb.InterfaceType)
                                                return true;
+
+                                       var expanded_base = t.Interfaces;
+                                       if (expanded_base == null)
+                                               continue;
+
+                                       foreach (var bt in expanded_base) {
+                                               if (bt == mb.InterfaceType)
+                                                       return true;
+                                       }
                                }
                        }
                        
@@ -2368,8 +2385,6 @@ namespace Mono.CSharp
                //
                // Public function used to locate types.
                //
-               // Set 'ignore_cs0104' to true if you want to ignore cs0104 errors.
-               //
                // Returns: Type or null if they type can not be found.
                //
                public override FullNamedExpression LookupNamespaceOrType (string name, int arity, LookupMode mode, Location loc)
@@ -2395,7 +2410,13 @@ namespace Mono.CSharp
                                if (t != null && (t.IsAccessible (this) || mode == LookupMode.IgnoreAccessibility))
                                        e = new TypeExpression (t, Location.Null);
                                else {
+                                       var errors = Compiler.Report.Errors;
                                        e = Parent.LookupNamespaceOrType (name, arity, mode, loc);
+
+                                       // TODO: LookupNamespaceOrType does more than just lookup. The result
+                                       // cannot be cached or the error reporting won't happen
+                                       if (errors != Compiler.Report.Errors)
+                                               return e;
                                }
                        }
 
@@ -3259,7 +3280,7 @@ namespace Mono.CSharp
                                        }
                                }
 
-                               if (!IsInterface && base_member.IsAbstract && !overrides) {
+                               if (!IsInterface && base_member.IsAbstract && !overrides && !IsStatic) {
                                        Report.SymbolRelatedToPreviousError (base_member);
                                        Report.Error (533, Location, "`{0}' hides inherited abstract member `{1}'",
                                                GetSignatureForError (), base_member.GetSignatureForError ());
index 319151bd093a16b6329431fc1c77b25071afd0cc..2e2f73182d5f0ea307b5326b4240d8cc1daa660f 100644 (file)
@@ -968,10 +968,6 @@ namespace Mono.CSharp
 
                public void Emit (EmitContext ec, MethodSpec method, Arguments Arguments, Location loc)
                {
-                       // Speed up the check by not doing it on not allowed targets
-                       if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.MemberContext))
-                               return;
-
                        EmitPredefined (ec, method, Arguments, loc);
                }
 
index 6eb42cddada0a51de2f96f54fe9c35b0b6cd294e..2931d137f737917aa2fab3e74fe0c6ac1c44b5c2 100644 (file)
@@ -114,32 +114,22 @@ namespace Mono.CSharp {
                        var sn = expr as SimpleName;
                        const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type;
 
-                       //
-                       // Resolve the expression with flow analysis turned off, we'll do the definite
-                       // assignment checks later.  This is because we don't know yet what the expression
-                       // will resolve to - it may resolve to a FieldExpr and in this case we must do the
-                       // definite assignment check on the actual field and not on the whole struct.
-                       //
-                       using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
-                               if (sn != null) {
-                                       expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
-
-                                       //
-                                       // Resolve expression which does have type set as we need expression type
-                                       // with disable flow analysis as we don't know whether left side expression
-                                       // is used as variable or type
-                                       //
-                                       if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
-                                               using (rc.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                                       expr = expr.Resolve (rc);
-                                               }
-                                       } else if (expr is TypeParameterExpr) {
-                                               expr.Error_UnexpectedKind (rc, flags, sn.Location);
-                                               expr = null;
-                                       }
-                               } else {
-                                       expr = expr.Resolve (rc, flags);
+                       if (sn != null) {
+                               expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
+
+                               //
+                               // Resolve expression which does have type set as we need expression type
+                               // with disable flow analysis as we don't know whether left side expression
+                               // is used as variable or type
+                               //
+                               if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
+                                       expr = expr.Resolve (rc);
+                               } else if (expr is TypeParameterExpr) {
+                                       expr.Error_UnexpectedKind (rc, flags, sn.Location);
+                                       expr = null;
                                }
+                       } else {
+                               expr = expr.Resolve (rc, flags);
                        }
 
                        if (expr == null)
index 49c4f5bfe750cd00db623ae6ff23e63398501e9a..5ab84f260afd3ae85e8d9c6ee75f1e70c1582a97 100644 (file)
@@ -69,8 +69,6 @@ namespace Mono.CSharp
        //
        public class BlockContext : ResolveContext
        {
-               FlowBranching current_flow_branching;
-
                readonly TypeSpec return_type;
 
                //
@@ -112,124 +110,17 @@ namespace Mono.CSharp
                                flags |= ResolveContext.Options.BaseInitializer;
                }
 
-               public override FlowBranching CurrentBranching {
-                       get { return current_flow_branching; }
-               }
+               public ExceptionStatement CurrentTryBlock { get; set; }
 
-               public TypeSpec ReturnType {
-                       get { return return_type; }
-               }
+               public LoopStatement EnclosingLoop { get; set; }
 
-               public bool IsUnreachable {
-                       get {
-                               return HasSet (Options.UnreachableScope);
-                       }
-                       set {
-                               flags = value ? flags | Options.UnreachableScope : flags & ~Options.UnreachableScope;
-                       }
-               }
+               public LoopStatement EnclosingLoopOrSwitch { get; set; }
 
-               public bool UnreachableReported {
-                       get {
-                               return HasSet (Options.UnreachableReported);
-                       }
-                       set {
-                               flags = value ? flags | Options.UnreachableReported : flags & ~Options.UnreachableScope;
-                       }
-               }
+               public Switch Switch { get; set; }
 
-               // <summary>
-               //   Starts a new code branching.  This inherits the state of all local
-               //   variables and parameters from the current branching.
-               // </summary>
-               public FlowBranching StartFlowBranching (FlowBranching.BranchingType type, Location loc)
-               {
-                       current_flow_branching = FlowBranching.CreateBranching (CurrentBranching, type, null, loc);
-                       return current_flow_branching;
-               }
-
-               // <summary>
-               //   Starts a new code branching for block `block'.
-               // </summary>
-               public FlowBranching StartFlowBranching (Block block)
-               {
-                       Set (Options.DoFlowAnalysis);
-
-                       current_flow_branching = FlowBranching.CreateBranching (
-                               CurrentBranching, FlowBranching.BranchingType.Block, block, block.StartLocation);
-                       return current_flow_branching;
-               }
-
-               public FlowBranchingTryCatch StartFlowBranching (TryCatch stmt)
-               {
-                       FlowBranchingTryCatch branching = new FlowBranchingTryCatch (CurrentBranching, stmt);
-                       current_flow_branching = branching;
-                       return branching;
-               }
-
-               public FlowBranchingTryFinally StartFlowBranching (TryFinallyBlock stmt)
-               {
-                       FlowBranchingTryFinally branching = new FlowBranchingTryFinally (CurrentBranching, stmt);
-                       current_flow_branching = branching;
-                       return branching;
-               }
-
-               public FlowBranchingLabeled StartFlowBranching (LabeledStatement stmt)
-               {
-                       FlowBranchingLabeled branching = new FlowBranchingLabeled (CurrentBranching, stmt);
-                       current_flow_branching = branching;
-                       return branching;
-               }
-
-               public FlowBranchingIterator StartFlowBranching (Iterator iterator, FlowBranching parent)
-               {
-                       FlowBranchingIterator branching = new FlowBranchingIterator (parent, iterator);
-                       current_flow_branching = branching;
-                       return branching;
-               }
-
-               public FlowBranchingAsync StartFlowBranching (AsyncInitializer asyncBody, FlowBranching parent)
-               {
-                       var branching = new FlowBranchingAsync (parent, asyncBody);
-                       current_flow_branching = branching;
-                       return branching;
-               }
-
-               public FlowBranchingToplevel StartFlowBranching (ParametersBlock stmt, FlowBranching parent)
-               {
-                       FlowBranchingToplevel branching = new FlowBranchingToplevel (parent, stmt);
-                       current_flow_branching = branching;
-                       return branching;
-               }
-
-               // <summary>
-               //   Ends a code branching.  Merges the state of locals and parameters
-               //   from all the children of the ending branching.
-               // </summary>
-               public bool EndFlowBranching ()
-               {
-                       FlowBranching old = current_flow_branching;
-                       current_flow_branching = current_flow_branching.Parent;
-
-                       FlowBranching.UsageVector vector = current_flow_branching.MergeChild (old);
-                       return vector.IsUnreachable;
-               }
-
-               // <summary>
-               //   Kills the current code branching.  This throws away any changed state
-               //   information and should only be used in case of an error.
-               // </summary>
-               // FIXME: this is evil
-               public void KillFlowBranching ()
-               {
-                       current_flow_branching = current_flow_branching.Parent;
-               }
-
-#if !STATIC
-               public void NeedReturnLabel ()
-               {
+               public TypeSpec ReturnType {
+                       get { return return_type; }
                }
-#endif
        }
 
        //
@@ -290,20 +181,9 @@ namespace Mono.CSharp
 
                        LockScope = 1 << 13,
 
-                       UnreachableScope = 1 << 14,
-
-                       UnreachableReported = 1 << 15,
+                       TryScope = 1 << 14,
 
-                       /// <summary>
-                       ///   Whether control flow analysis is enabled
-                       /// </summary>
-                       DoFlowAnalysis = 1 << 20,
-
-                       /// <summary>
-                       ///   Whether control flow analysis is disabled on structs
-                       ///   (only meaningful when DoFlowAnalysis is set)
-                       /// </summary>
-                       OmitStructFlowAnalysis = 1 << 21,
+                       TryWithCatchScope = 1 << 15,
 
                        ///
                        /// Indicates the current context is in probing mode, no errors are reported. 
@@ -372,11 +252,6 @@ namespace Mono.CSharp
 
                public readonly IMemberContext MemberContext;
 
-               /// <summary>
-               ///   If this is non-null, points to the current switch statement
-               /// </summary>
-               public Switch Switch;
-
                public ResolveContext (IMemberContext mc)
                {
                        if (mc == null)
@@ -416,10 +291,6 @@ namespace Mono.CSharp
                        }
                }
 
-               public virtual FlowBranching CurrentBranching {
-                       get { return null; }
-               }
-
                //
                // The current iterator
                //
@@ -443,10 +314,6 @@ namespace Mono.CSharp
                        get { return (flags & Options.ConstantCheckState) != 0; }
                }
 
-               public bool DoFlowAnalysis {
-                       get { return (flags & Options.DoFlowAnalysis) != 0; }
-               }
-
                public bool IsInProbingMode {
                        get {
                                return (flags & Options.ProbingMode) != 0;
@@ -480,7 +347,7 @@ namespace Mono.CSharp
 
                public bool IsVariableCapturingRequired {
                        get {
-                               return !IsInProbingMode && (CurrentBranching == null || !CurrentBranching.CurrentUsageVector.IsUnreachable);
+                               return !IsInProbingMode;
                        }
                }
 
@@ -490,10 +357,6 @@ namespace Mono.CSharp
                        }
                }
 
-               public bool OmitStructFlowAnalysis {
-                       get { return (flags & Options.OmitStructFlowAnalysis) != 0; }
-               }
-
                public Report Report {
                        get {
                                return Module.Compiler.Report;
@@ -516,10 +379,12 @@ namespace Mono.CSharp
 
                        //
                        // Capture only if this or any of child blocks contain await
-                       // or it's a parameter
+                       // or it's a parameter or we need to access variable from 
+                       // different parameter block
                        //
                        if (CurrentAnonymousMethod is AsyncInitializer)
-                               return local.IsParameter || local.Block.Explicit.HasAwait || CurrentBlock.Explicit.HasAwait;
+                               return local.IsParameter || local.Block.Explicit.HasAwait || CurrentBlock.Explicit.HasAwait ||
+                                       local.Block.ParametersBlock != CurrentBlock.ParametersBlock.Original;
 
                        return local.Block.ParametersBlock != CurrentBlock.ParametersBlock.Original;
                }
@@ -571,6 +436,72 @@ namespace Mono.CSharp
                #endregion
        }
 
+       public class FlowAnalysisContext
+       {
+               readonly CompilerContext ctx;
+
+               public FlowAnalysisContext (CompilerContext ctx, ParametersBlock parametersBlock, int definiteAssignmentLength)
+               {
+                       this.ctx = ctx;
+                       this.ParametersBlock = parametersBlock;
+
+                       DefiniteAssignment = definiteAssignmentLength == 0 ?
+                               DefiniteAssignmentBitSet.Empty :
+                               new DefiniteAssignmentBitSet (definiteAssignmentLength);
+               }
+
+               public DefiniteAssignmentBitSet DefiniteAssignment { get; set; }
+
+               public DefiniteAssignmentBitSet DefiniteAssignmentOnTrue { get; set; }
+
+               public DefiniteAssignmentBitSet DefiniteAssignmentOnFalse { get; set; }
+
+               public List<LabeledStatement> LabelStack { get; set; }
+
+               public ParametersBlock ParametersBlock { get; set; }
+
+               public Report Report {
+                       get {
+                               return ctx.Report;
+                       }
+               }
+
+               public DefiniteAssignmentBitSet SwitchInitialDefinitiveAssignment { get; set; }
+
+               public TryFinally TryFinally { get; set; }
+
+               public bool UnreachableReported { get; set; }
+
+               public DefiniteAssignmentBitSet BranchDefiniteAssignment ()
+               {
+                       var dat = DefiniteAssignment;
+                       if (dat != DefiniteAssignmentBitSet.Empty)
+                               DefiniteAssignment = new DefiniteAssignmentBitSet (dat);
+                       return dat;
+               }
+
+               public bool IsDefinitelyAssigned (VariableInfo variable)
+               {
+                       return variable.IsAssigned (DefiniteAssignment);
+               }
+
+               public bool IsStructFieldDefinitelyAssigned (VariableInfo variable, string name)
+               {
+                       return variable.IsStructFieldAssigned (DefiniteAssignment, name);
+               }
+
+               public void SetVariableAssigned (VariableInfo variable, bool generatedAssignment = false)
+               {
+                       variable.SetAssigned (DefiniteAssignment, generatedAssignment);
+               }
+
+               public void SetStructFieldAssigned (VariableInfo variable, string name)
+               {
+                       variable.SetStructFieldAssigned (DefiniteAssignment, name);
+               }
+       }
+
+
        //
        // This class is used during the Statement.Clone operation
        // to remap objects that have been cloned.
@@ -684,8 +615,12 @@ namespace Mono.CSharp
 
                        string path;
                        if (!Path.IsPathRooted (name)) {
-                               string root = Path.GetDirectoryName (comp_unit.SourceFile.FullPathName);
-                               path = Path.Combine (root, name);
+                               var loc = comp_unit.SourceFile;
+                               string root = Path.GetDirectoryName (loc.FullPathName);
+                               path = Path.GetFullPath (Path.Combine (root, name));
+                               var dir = Path.GetDirectoryName (loc.Name);
+                               if (!string.IsNullOrEmpty (dir))
+                                       name = Path.Combine (dir, name);
                        } else
                                path = name;
 
index 90c4a871009e0e74a1b37b619bbb587ec4eaa3a2..a64e4a86a8851e9e1a12ad6680f6c4d6c42c190e 100644 (file)
@@ -5900,12 +5900,12 @@ try_statement
          }
        | TRY block FINALLY block
          {
-               $$ = new TryFinally ((Statement) $2, (Block) $4, GetLocation ($1));
+               $$ = new TryFinally ((Statement) $2, (ExplicitBlock) $4, GetLocation ($1));
                lbag.AddStatement ($$, GetLocation ($3));
          }
        | TRY block catch_clauses FINALLY block
          {
-               $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, Location.Null, true), (Block) $5, GetLocation ($1));
+               $$ = new TryFinally (new TryCatch ((Block) $2, (List<Catch>) $3, Location.Null, true), (ExplicitBlock) $5, GetLocation ($1));
                lbag.AddStatement ($$, GetLocation ($4));
          }
        | TRY block error
@@ -5945,12 +5945,12 @@ opt_identifier
 catch_clause 
        : CATCH block
          {
-               $$ = new Catch ((Block) $2, GetLocation ($1));
+               $$ = new Catch ((ExplicitBlock) $2, GetLocation ($1));
          }
        | CATCH open_parens_any type opt_identifier CLOSE_PARENS
          {
                start_block (GetLocation ($2));
-               var c = new Catch (current_block, GetLocation ($1));
+               var c = new Catch ((ExplicitBlock) current_block, GetLocation ($1));
                c.TypeExpression = (FullNamedExpression) $3;
 
                if ($4 != null) {
@@ -7038,7 +7038,7 @@ public CSharpParser (SeekableStreamReader reader, CompilationSourceFile file, Re
        lang_version = settings.Version;
        yacc_verbose_flag = settings.VerboseParserFlag;
        doc_support = settings.DocumentationFile != null;
-       lexer = new Tokenizer (reader, file, session);
+       lexer = new Tokenizer (reader, file, session, report);
        oob_stack = new Stack<object> ();
        lbag = session.LocationsBag;
        use_global_stacks = session.UseJayGlobalArrays;
index 3f7f49dbfdd1d0710cab10bca8c99f562a9e149c..2018829ed04559aafcf5829061b5792b399d42b1 100644 (file)
@@ -188,6 +188,8 @@ namespace Mono.CSharp
                readonly SeekableStreamReader reader;
                readonly CompilationSourceFile source_file;
                readonly CompilerContext context;
+               readonly Report Report;
+
 
                SourceFile current_source;
                Location hidden_block_start;
@@ -430,7 +432,7 @@ namespace Mono.CSharp
                        }
                }
 
-               public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session)
+               public Tokenizer (SeekableStreamReader input, CompilationSourceFile file, ParserSession session, Report report)
                {
                        this.source_file = file;
                        this.context = file.Compiler;
@@ -439,6 +441,7 @@ namespace Mono.CSharp
                        this.id_builder = session.IDBuilder;
                        this.number_builder = session.NumberBuilder;
                        this.ltb = new LocatedTokenBuffer (session.LocatedTokens);
+                       this.Report = report;
 
                        reader = input;
 
@@ -3730,10 +3733,6 @@ namespace Mono.CSharp
                        return null;
                }
 
-               Report Report {
-                       get { return context.Report; }
-               }
-
                void reset_doc_comment ()
                {
                        xml_comment_buffer.Length = 0;
index cabb7dff00e4939721b22f07060adef398eabdf0..569083e87ccfa8a0f5f85865dd3701dd9a52ee38 100644 (file)
@@ -532,7 +532,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       TypeSpec rt = delegate_method.ReturnType;
+                       TypeSpec rt = method_group.BestCandidateReturnType;
                        if (rt.BuiltinType == BuiltinTypeSpec.Type.Dynamic)
                                rt = ec.BuiltinTypes.Object;
 
@@ -541,7 +541,7 @@ namespace Mono.CSharp {
                                Error_ConversionFailed (ec, delegate_method, ret_expr);
                        }
 
-                       if (delegate_method.IsConditionallyExcluded (ec)) {
+                       if (method_group.IsConditionallyExcluded) {
                                ec.Report.SymbolRelatedToPreviousError (delegate_method);
                                MethodOrOperator m = delegate_method.MemberDefinition as MethodOrOperator;
                                if (m != null && m.IsPartialDefinition) {
@@ -828,6 +828,13 @@ namespace Mono.CSharp {
                        return CreateExpressionFactoryCall (ec, "Invoke", args);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       InstanceExpr.FlowAnalysis (fc);
+                       if (arguments != null)
+                               arguments.FlowAnalysis (fc);
+               }
+
                protected override Expression DoResolve (ResolveContext ec)
                {               
                        TypeSpec del_type = InstanceExpr.Type;
index 9dbd05becde51065ab29cbf91e752e76e82406a4..ad1853a4a4ea530bf1bb1d25ff27c468477487ca 100644 (file)
@@ -57,7 +57,7 @@ namespace Mono.CSharp
                                SeekableStreamReader reader = new SeekableStreamReader (input, ctx.Settings.Encoding);
                                var file = new CompilationSourceFile (module, sourceFile);
 
-                               Tokenizer lexer = new Tokenizer (reader, file, session);
+                               Tokenizer lexer = new Tokenizer (reader, file, session, ctx.Report);
                                int token, tokens = 0, errors = 0;
 
                                while ((token = lexer.token ()) != Token.EOF){
index 2124f0fda088d89e5febb0092edb68e3dd115246..3627610a51c14cc7f27e59b99dd119992220a902 100644 (file)
@@ -450,6 +450,14 @@ namespace Mono.CSharp
                                d.PrepareEmit ();
 
                                site.AddTypeContainer (d);
+
+                               //
+                               // Add new container to inflated site container when the
+                               // member cache already exists
+                               //
+                               if (site.CurrentType is InflatedTypeSpec && index > 0)
+                                       site.CurrentType.MemberCache.AddMember (d.CurrentType);
+
                                del_type = new TypeExpression (d.CurrentType, loc);
                                if (targs_for_instance != null) {
                                        del_type_instance_access = null;
@@ -532,6 +540,11 @@ namespace Mono.CSharp
                        }
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       arguments.FlowAnalysis (fc);
+               }
+
                public static MemberAccess GetBinderNamespace (Location loc)
                {
                        return new MemberAccess (new MemberAccess (
@@ -612,6 +625,11 @@ namespace Mono.CSharp
                                stmt.Emit (ec);
                        }
                }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       invoke.FlowAnalysis (fc);
+               }
        }
 
        class DynamicConversion : DynamicExpressionStatement, IDynamicBinder
index 31c8a8b47edced1240ee43100ce5e32a866a30de..ec0d7a2c60670ce1f4f3caea3dafab0ad30461a8 100644 (file)
@@ -712,13 +712,20 @@ namespace Mono.CSharp {
                {
                        var ctors = MemberCache.FindMembers (type, Constructor.ConstructorName, true);
                        if (ctors == null) {
-                               rc.Report.SymbolRelatedToPreviousError (type);
-                               if (type.IsStruct) {
+                               switch (type.Kind) {
+                               case MemberKind.Struct:
+                                       rc.Report.SymbolRelatedToPreviousError (type);
                                        // Report meaningful error for struct as they always have default ctor in C# context
                                        OverloadResolver.Error_ConstructorMismatch (rc, type, args == null ? 0 : args.Count, loc);
-                               } else {
+                                       break;
+                               case MemberKind.MissingType:
+                               case MemberKind.InternalCompilerType:
+                                       break;
+                               default:
+                                       rc.Report.SymbolRelatedToPreviousError (type);
                                        rc.Report.Error (143, loc, "The class `{0}' has no constructors defined",
                                                type.GetSignatureForError ());
+                                       break;
                                }
 
                                return null;
@@ -923,6 +930,10 @@ namespace Mono.CSharp {
                        ec.Report.Error (1944, loc, "An expression tree cannot contain an unsafe pointer operation");
                }
 
+               public virtual void FlowAnalysis (FlowAnalysisContext fc)
+               {
+               }
+
                /// <summary>
                ///   Returns an expression that can be used to invoke operator true
                ///   on the expression if it exists.
@@ -1175,6 +1186,10 @@ namespace Mono.CSharp {
        /// </summary>
        public abstract class ExpressionStatement : Expression
        {
+               public virtual void MarkReachable (Reachability rc)
+               {
+               }
+
                public ExpressionStatement ResolveStatement (BlockContext ec)
                {
                        Expression e = Resolve (ec);
@@ -1182,7 +1197,7 @@ namespace Mono.CSharp {
                                return null;
 
                        ExpressionStatement es = e as ExpressionStatement;
-                       if (es == null)
+                       if (es == null || e is AnonymousMethodBody)
                                Error_InvalidExpressionStatement (ec);
 
                        //
@@ -1310,6 +1325,11 @@ namespace Mono.CSharp {
                        child.Emit (ec);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       child.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
 #if STATIC
@@ -2141,6 +2161,11 @@ namespace Mono.CSharp {
                        {
                                stm.EmitStatement (ec);
                        }
+
+                       public override void FlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               stm.FlowAnalysis (fc);
+                       }
                }
 
                readonly Expression expr, orig_expr;
@@ -2244,6 +2269,11 @@ namespace Mono.CSharp {
                        expr.EmitBranchable (ec, target, on_true);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        return orig_expr.MakeExpression (ctx);
@@ -2339,7 +2369,38 @@ namespace Mono.CSharp {
                {
                        throw new InternalErrorException ("Missing Resolve call");
                }
+       }
+
+       public class UnreachableExpression : Expression
+       {
+               public UnreachableExpression (Expression expr)
+               {
+                       this.loc = expr.Location;
+               }
+
+               public override Expression CreateExpressionTree (ResolveContext ec)
+               {
+                       // TODO: is it ok
+                       throw new NotImplementedException ();
+               }
 
+               protected override Expression DoResolve (ResolveContext rc)
+               {
+                       throw new NotSupportedException ();
+               }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       fc.Report.Warning (429, 4, loc, "Unreachable expression code detected");
+               }
+
+               public override void Emit (EmitContext ec)
+               {
+               }
+
+               public override void EmitBranchable (EmitContext ec, Label target, bool on_true)
+               {
+               }
        }
 
        //
@@ -2470,14 +2531,7 @@ namespace Mono.CSharp {
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       var e = SimpleNameResolve (rc, null);
-
-                       var fe = e as FieldExpr;
-                       if (fe != null) {
-                               fe.VerifyAssignedStructField (rc, null);
-                       }
-
-                       return e;
+                       return SimpleNameResolve (rc, null);
                }
 
                public override Expression DoResolveLValue (ResolveContext ec, Expression right_side)
@@ -3162,6 +3216,12 @@ namespace Mono.CSharp {
                                member.GetSignatureForError (), qualifier.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (InstanceExpression != null)
+                               InstanceExpression.FlowAnalysis (fc);
+               }
+
                public bool ResolveInstanceExpression (ResolveContext rc, Expression rhs)
                {
                        if (!ResolveInstanceExpressionCore (rc, rhs))
@@ -3183,7 +3243,11 @@ namespace Mono.CSharp {
                                                rc.Report.Error (1648, loc, "Members of readonly field `{0}' cannot be modified (except in a constructor or a variable initializer)",
                                                        fexpr.GetSignatureForError ());
                                        }
-                               } else if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) {
+
+                                       return true;
+                               }
+
+                               if (InstanceExpression is PropertyExpr || InstanceExpression is IndexerExpr || InstanceExpression is Invocation) {
                                        if (rc.CurrentInitializerVariable != null) {
                                                rc.Report.Error (1918, loc, "Members of value type `{0}' cannot be assigned using a property `{1}' object initializer",
                                                        InstanceExpression.Type.GetSignatureForError (), InstanceExpression.GetSignatureForError ());
@@ -3192,6 +3256,18 @@ namespace Mono.CSharp {
                                                        "Cannot modify a value type return value of `{0}'. Consider storing the value in a temporary variable",
                                                        InstanceExpression.GetSignatureForError ());
                                        }
+
+                                       return true;
+                               }
+
+                               var lvr = InstanceExpression as LocalVariableReference;
+                               if (lvr != null) {
+
+                                       if (!lvr.local_info.IsReadonly)
+                                               return true;
+
+                                       rc.Report.Error (1654, loc, "Cannot assign to members of `{0}' because it is a `{1}'",
+                                               InstanceExpression.GetSignatureForError (), lvr.local_info.GetReadOnlyContext ());
                                }
                        }
 
@@ -3248,15 +3324,7 @@ namespace Mono.CSharp {
                                                DeclaringType.GetSignatureForError (), rc.CurrentType.GetSignatureForError ());
                                }
 
-                               InstanceExpression = new This (loc);
-                               if (this is FieldExpr && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
-                                       using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
-                                               InstanceExpression = InstanceExpression.Resolve (rc);
-                                       }
-                               } else {
-                                       InstanceExpression = InstanceExpression.Resolve (rc);
-                               }
-
+                               InstanceExpression = new This (loc).Resolve (rc);
                                return false;
                        }
 
@@ -3264,29 +3332,17 @@ namespace Mono.CSharp {
                        if (me != null) {
                                me.ResolveInstanceExpressionCore (rc, rhs);
 
-                               // Using this check to detect probing instance expression resolve
-                               if (!rc.OmitStructFlowAnalysis) {
-                                       var fe = me as FieldExpr;
-                                       if (fe != null && fe.IsMarshalByRefAccess (rc)) {
-                                               rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
-                                               rc.Report.Warning (1690, 1, loc,
-                                                       "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
-                                                       me.GetSignatureForError ());
-                                       }
+                               var fe = me as FieldExpr;
+                               if (fe != null && fe.IsMarshalByRefAccess (rc)) {
+                                       rc.Report.SymbolRelatedToPreviousError (me.DeclaringType);
+                                       rc.Report.Warning (1690, 1, loc,
+                                               "Cannot call methods, properties, or indexers on `{0}' because it is a value type member of a marshal-by-reference class",
+                                               me.GetSignatureForError ());
                                }
 
                                return true;
                        }
 
-                       //
-                       // Run member-access postponed check once we know that
-                       // the expression is not field expression which is the only
-                       // expression which can use uninitialized this
-                       //
-                       if (InstanceExpression is This && !(this is FieldExpr) && rc.CurrentBlock.ParametersBlock.TopBlock.ThisVariable != null) {
-                               ((This)InstanceExpression).CheckStructThisDefiniteAssignment (rc);
-                       }
-
                        //
                        // Additional checks for l-value member access
                        //
@@ -3501,6 +3557,8 @@ namespace Mono.CSharp {
        /// </summary>
        public class MethodGroupExpr : MemberExpr, OverloadResolver.IBaseMembersProvider
        {
+               static readonly MemberSpec[] Excluded = new MemberSpec[0];
+
                protected IList<MemberSpec> Methods;
                MethodSpec best_candidate;
                TypeSpec best_candidate_return;
@@ -3550,6 +3608,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool IsConditionallyExcluded {
+                       get {
+                               return Methods == Excluded;
+                       }
+               }
+
                public override bool IsInstance {
                        get {
                                if (best_candidate != null)
@@ -3619,7 +3683,7 @@ namespace Mono.CSharp {
                                return null;
                        }
 
-                       if (best_candidate.IsConditionallyExcluded (ec))
+                       if (IsConditionallyExcluded)
                                ec.Report.Error (765, loc,
                                        "Partial methods with only a defining declaration or removed conditional methods cannot be used in an expression tree");
                        
@@ -3744,6 +3808,10 @@ namespace Mono.CSharp {
                                ErrorIsInaccesible (ec, best_candidate.GetSignatureForError (), loc);
                        }
 
+                       // Speed up the check by not doing it on disallowed targets
+                       if (best_candidate_return.Kind == MemberKind.Void && best_candidate.IsConditionallyExcluded (ec))
+                               Methods = Excluded;
+
                        return this;
                }
 
@@ -5266,7 +5334,7 @@ namespace Mono.CSharp {
                                                if (ms.TypeArguments != null)
                                                        constr_ok = new ConstraintChecker (rc.MemberContext).CheckAll (ms.GetGenericMethodDefinition (), ms.TypeArguments, ms.Constraints, loc);
 
-                                               if (ta_count == 0) {
+                                               if (ta_count == 0 && ms.TypeArguments == null) {
                                                        if (custom_errors != null && custom_errors.TypeInferenceFailed (rc, best_candidate))
                                                                return;
 
@@ -5680,18 +5748,14 @@ namespace Mono.CSharp {
                                        // "a.b" is initialized, not whether the whole struct "a" is initialized.
 
                                        if (lvalue_instance) {
-                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                                       bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
+                                               bool out_access = rhs == EmptyExpression.OutAccess || rhs == EmptyExpression.LValueMemberOutAccess;
 
-                                                       Expression right_side =
-                                                               out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
+                                               Expression right_side =
+                                                       out_access ? EmptyExpression.LValueMemberOutAccess : EmptyExpression.LValueMemberAccess;
 
-                                                       InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
-                                               }
+                                               InstanceExpression = InstanceExpression.ResolveLValue (ec, right_side);
                                        } else {
-                                               using (ec.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                                       InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
-                                               }
+                                               InstanceExpression = InstanceExpression.Resolve (ec, ResolveFlags.VariableOrValue);
                                        }
 
                                        if (InstanceExpression == null)
@@ -5704,10 +5768,6 @@ namespace Mono.CSharp {
                        var fb = spec as FixedFieldSpec;
                        IVariableReference var = InstanceExpression as IVariableReference;
 
-                       if (lvalue_instance && var != null && var.VariableInfo != null) {
-                               var.VariableInfo.SetStructFieldAssigned (ec, Name);
-                       }
-
                        if (fb != null) {
                                IFixedExpression fe = InstanceExpression as IFixedExpression;
                                if (!ec.HasSet (ResolveContext.Options.FixedInitializerScope) && (fe == null || !fe.IsFixed)) {
@@ -5731,15 +5791,50 @@ namespace Mono.CSharp {
                        //
                        if (var != null && var.VariableInfo != null && InstanceExpression.Type.IsStruct) {
                                variable_info = var.VariableInfo.GetStructFieldInfo (Name);
-                               if (rhs != null && variable_info != null)
-                                       variable_info.SetStructFieldAssigned (ec, Name);
                        }
 
                        eclass = ExprClass.Variable;
                        return this;
                }
 
-               public void VerifyAssignedStructField (ResolveContext rc, Expression rhs)
+               public void SetFieldAssigned (FlowAnalysisContext fc)
+               {
+                       if (!IsInstance)
+                               return;
+
+                       bool lvalue_instance = spec.DeclaringType.IsStruct;
+                       if (lvalue_instance) {
+                               var var = InstanceExpression as IVariableReference;
+                               if (var != null && var.VariableInfo != null) {
+                                       fc.SetStructFieldAssigned (var.VariableInfo, Name);
+                               }
+                       }
+
+                       var fe = InstanceExpression as FieldExpr;
+                       if (fe != null || lvalue_instance) {
+                               if (fe == null)
+                                       return;
+
+                               /*
+                               while (fe.InstanceExpression is FieldExpr) {
+                                       fe = (FieldExpr) fe.InstanceExpression;
+                                       if (!fe.Spec.DeclaringType.IsStruct)
+                                               continue;
+
+                                       if (fe.VariableInfo != null && fc.IsStructFieldDefinitelyAssigned (fe.VariableInfo, fe.Name)) {
+                                               fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
+                                       }
+                               }
+
+                               fe.InstanceExpression.FlowAnalysis (fc);
+                               */
+                       } else {
+                               InstanceExpression.FlowAnalysis (fc);
+                       }
+               }
+
+
+               public void VerifyAssignedStructField (FlowAnalysisContext fc)
                {
                        var fe = this;
 
@@ -5748,14 +5843,8 @@ namespace Mono.CSharp {
                                if (var != null) {
                                        var vi = var.VariableInfo;
 
-                                       if (vi != null && !vi.IsStructFieldAssigned (rc, fe.Name) && (rhs == null || !fe.type.IsStruct)) {
-                                               if (rhs != null) {
-                                                       rc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
-                                               } else {
-                                                       rc.Report.Error (170, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
-                                               }
-
-                                               return;
+                                       if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, fe.Name) && !fe.type.IsStruct) {
+                                               fc.Report.Warning (1060, 1, fe.loc, "Use of possibly unassigned field `{0}'", fe.Name);
                                        }
                                }
 
@@ -5793,7 +5882,6 @@ namespace Mono.CSharp {
                                        rc.Report.Error (1649, loc, "Members of readonly field `{0}' cannot be passed ref or out (except in a constructor)",
                                                GetSignatureForError ());
                                }
-
                                return null;
                        }
 
@@ -5859,6 +5947,23 @@ namespace Mono.CSharp {
                        return this;
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var var = InstanceExpression as IVariableReference;
+                       if (var != null) {
+                               var vi = var.VariableInfo;
+                               if (vi != null && !fc.IsStructFieldDefinitelyAssigned (vi, Name)) {
+                                       fc.Report.Error (170, loc, "Use of possibly unassigned field `{0}'", Name);
+                                       return;
+                               }
+
+                               if (TypeSpec.IsValueType (InstanceExpression.Type))
+                                       return;
+                       }
+
+                       base.FlowAnalysis (fc);
+               }
+
                public override int GetHashCode ()
                {
                        return spec.GetHashCode ();
@@ -6726,6 +6831,11 @@ namespace Mono.CSharp {
                                DoEmit (ec);
                        }
 
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               return false;
+                       }
+
                        protected override void CloneTo (CloneContext clonectx, Statement target)
                        {
                                // Nothing
@@ -6827,10 +6937,6 @@ namespace Mono.CSharp {
                public override VariableInfo VariableInfo {
                        get { return null; }
                }
-
-               public override void VerifyDefiniteAssignment (ResolveContext rc)
-               {
-               }
        }
 
        /// 
index 5d9a291b1c51f1c3bc99b1dbfa36b37530c8202f..26e4f5d8d90ca2e1d004e5b20c60b9259ccdd78d 100644 (file)
@@ -389,7 +389,7 @@ namespace Mono.CSharp
                                BlockContext bc = new BlockContext (method, method.Block, ctx.BuiltinTypes.Void);
 
                                try {
-                                       method.Block.Resolve (null, bc, method);
+                                       method.Block.Resolve (bc, method);
                                } catch (CompletionResult cr) {
                                        prefix = cr.BaseText;
                                        return cr.Result;
@@ -459,7 +459,7 @@ namespace Mono.CSharp
                //
                InputKind ToplevelOrStatement (SeekableStreamReader seekable)
                {
-                       Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession ());
+                       Tokenizer tokenizer = new Tokenizer (seekable, source_file, new ParserSession (), ctx.Report);
                        
                        // Prefer contextual block keywords over identifiers
                        tokenizer.parsing_block++;
index 7a9155ba50b4e271b15c7c2d3aa95a7fd0ba0086..c8a7999f4dbe17bdb0f11a2412c5c35b8e013ffb 100644 (file)
@@ -83,6 +83,11 @@ namespace Mono.CSharp
                        call.EmitPredefined (ec, oper, arguments, loc);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       arguments.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
 #if STATIC
@@ -572,6 +577,31 @@ namespace Mono.CSharp
                        Expr.EmitSideEffect (ec);
                }
 
+               public static void Error_Ambiguous (ResolveContext rc, string oper, TypeSpec type, Location loc)
+               {
+                       rc.Report.Error (35, loc, "Operator `{0}' is ambiguous on an operand of type `{1}'",
+                               oper, type.GetSignatureForError ());
+               }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (Oper == Operator.AddressOf) {
+                               var vr = Expr as VariableReference;
+                               if (vr != null && vr.VariableInfo != null)
+                                       fc.SetVariableAssigned (vr.VariableInfo);
+
+                               return;
+                       }
+
+                       Expr.FlowAnalysis (fc);
+
+                       if (Oper == Operator.LogicalNot) {
+                               var temp = fc.DefiniteAssignmentOnTrue;
+                               fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse;
+                               fc.DefiniteAssignmentOnFalse = temp;
+                       }
+               }
+
                //
                // Converts operator to System.Linq.Expressions.ExpressionType enum name
                //
@@ -757,8 +787,7 @@ namespace Mono.CSharp
                                int result = OverloadResolver.BetterTypeConversion (ec, best_expr.Type, t);
                                if (result == 0) {
                                        if ((oper_expr is UserOperatorCall || oper_expr is UserCast) && (best_expr is UserOperatorCall || best_expr is UserCast)) {
-                                               ec.Report.Error (35, loc, "Operator `{0}' is ambiguous on an operand of type `{1}'",
-                                                       OperName (Oper), expr.Type.GetSignatureForError ());
+                                               Error_Ambiguous (ec, OperName (Oper), expr.Type, loc);
                                        } else {
                                                Error_OperatorCannotBeApplied (ec, loc, OperName (Oper), expr.Type);
                                        }
@@ -1199,14 +1228,33 @@ namespace Mono.CSharp
 
                                        source = operation;
                                } else {
+                                       Expression best_source = null;
                                        foreach (var t in ec.BuiltinTypes.OperatorsUnaryMutator) {
                                                source = Convert.ImplicitUserConversion (ec, operation, t, loc);
 
                                                // LAMESPEC: It should error on ambiguous operators but that would make us incompatible
-                                               if (source != null) {
-                                                       break;
+                                               if (source == null)
+                                                       continue;
+
+                                               if (best_source == null) {
+                                                       best_source = source;
+                                                       continue;
                                                }
+
+                                               var better = OverloadResolver.BetterTypeConversion (ec, best_source.Type, source.Type);
+                                               if (better == 1)
+                                                       continue;
+
+                                               if (better == 2) {
+                                                       best_source = source;
+                                                       continue;
+                                               }
+
+                                               Unary.Error_Ambiguous (ec, OperName (mode), type, loc);
+                                               break;
                                        }
+
+                                       source = best_source;
                                }
 
                                // ++/-- on enum types
@@ -1274,6 +1322,11 @@ namespace Mono.CSharp
                        EmitCode (ec, false);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                //
                // Converts operator to System.Linq.Expressions.ExpressionType enum name
                //
@@ -1296,6 +1349,11 @@ namespace Mono.CSharp
                }
 #endif
 
+               public static string OperName (Mode oper)
+               {
+                       return (oper & Mode.IsDecrement) != 0 ? "--" : "++";
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        UnaryMutator target = (UnaryMutator) t;
@@ -1367,6 +1425,11 @@ namespace Mono.CSharp
                        return this;
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                protected abstract string OperatorName { get; }
 
                protected override void CloneTo (CloneContext clonectx, Expression t)
@@ -2518,6 +2581,49 @@ namespace Mono.CSharp
                        Error_OperatorCannotBeApplied (ec, left, right, OperName (oper), loc);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if ((oper & Operator.LogicalMask) == 0) {
+                               left.FlowAnalysis (fc);
+                               right.FlowAnalysis (fc);
+                               return;
+                       }
+
+                       //
+                       // Optimized version when on-true/on-false data are not needed
+                       //
+                       bool set_on_true_false;
+                       if (fc.DefiniteAssignmentOnTrue == null && fc.DefiniteAssignmentOnFalse == null) {
+                               fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignment;
+                               set_on_true_false = false;
+                       } else {
+                               set_on_true_false = true;
+                       }
+
+                       left.FlowAnalysis (fc);
+                       var left_fc = fc.DefiniteAssignment;
+                       var left_fc_ontrue = fc.DefiniteAssignmentOnTrue;
+                       var left_fc_onfalse = fc.DefiniteAssignmentOnFalse;
+
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment = new DefiniteAssignmentBitSet (
+                               oper == Operator.LogicalOr ? left_fc_onfalse : left_fc_ontrue);
+                       right.FlowAnalysis (fc);
+                       fc.DefiniteAssignment = left_fc;
+
+                       if (!set_on_true_false) {
+                               fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignmentOnTrue = null;
+                               return;
+                       }
+
+                       if (oper == Operator.LogicalOr) {
+                               fc.DefiniteAssignmentOnTrue = new DefiniteAssignmentBitSet (left_fc_ontrue);
+                               fc.DefiniteAssignmentOnFalse = left_fc_onfalse | fc.DefiniteAssignmentOnFalse;
+                       } else {
+                               fc.DefiniteAssignmentOnTrue = left_fc_ontrue | fc.DefiniteAssignmentOnTrue;
+                               fc.DefiniteAssignmentOnFalse = new DefiniteAssignmentBitSet (left_fc_onfalse);
+                       }
+               }
+
                //
                // Converts operator to System.Linq.Expressions.ExpressionType enum name
                //
@@ -4890,6 +4996,11 @@ namespace Mono.CSharp
                        }
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       arguments.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        if (arguments.Count != 2)
@@ -5259,32 +5370,8 @@ namespace Mono.CSharp
                protected override Expression DoResolve (ResolveContext ec)
                {
                        expr = expr.Resolve (ec);
-
-                       //
-                       // Unreachable code needs different resolve path. For instance for await
-                       // expression to not generate unreachable resumable statement
-                       //
-                       Constant c = expr as Constant;
-                       if (c != null && ec.CurrentBranching != null) {
-                               bool unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
-
-                               if (c.IsDefaultValue) {
-                                       ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true;
-                                       true_expr = true_expr.Resolve (ec);
-                                       ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable;
-
-                                       false_expr = false_expr.Resolve (ec);
-                               } else {
-                                       true_expr = true_expr.Resolve (ec);
-
-                                       ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true;
-                                       false_expr = false_expr.Resolve (ec);
-                                       ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable;
-                               }
-                       } else {
-                               true_expr = true_expr.Resolve (ec);
-                               false_expr = false_expr.Resolve (ec);
-                       }
+                       true_expr = true_expr.Resolve (ec);
+                       false_expr = false_expr.Resolve (ec);
 
                        if (true_expr == null || false_expr == null || expr == null)
                                return null;
@@ -5345,8 +5432,9 @@ namespace Mono.CSharp
                                                true_type.GetSignatureForError (), false_type.GetSignatureForError ());
                                        return null;
                                }
-                       }                       
+                       }
 
+                       Constant c = expr as Constant;
                        if (c != null) {
                                bool is_false = c.IsDefaultValue;
 
@@ -5392,6 +5480,28 @@ namespace Mono.CSharp
                        ec.MarkLabel (end_target);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
+
+                       expr.FlowAnalysis (fc);
+                       var da_true = fc.DefiniteAssignmentOnTrue;
+                       var da_false = fc.DefiniteAssignmentOnFalse;
+
+                       fc.DefiniteAssignment = new DefiniteAssignmentBitSet (da_true);
+                       true_expr.FlowAnalysis (fc);
+                       var true_fc = fc.DefiniteAssignment;
+
+                       fc.DefiniteAssignment = new DefiniteAssignmentBitSet (da_false);
+                       false_expr.FlowAnalysis (fc);
+
+                       fc.DefiniteAssignment &= true_fc;
+                       if (fc.DefiniteAssignmentOnTrue != null)
+                               fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignment;
+                       if (fc.DefiniteAssignmentOnFalse != null)
+                               fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        Conditional target = (Conditional) t;
@@ -5409,7 +5519,6 @@ namespace Mono.CSharp
                #region Abstract
                public abstract HoistedVariable GetHoistedVariable (AnonymousExpression ae);
                public abstract void SetHasAddressTaken ();
-               public abstract void VerifyDefiniteAssignment (ResolveContext rc);
 
                public abstract bool IsLockedByStatement { get; set; }
 
@@ -5642,17 +5751,17 @@ namespace Mono.CSharp
 
                #endregion
 
-               public override void VerifyDefiniteAssignment (ResolveContext rc)
+               public override void FlowAnalysis (FlowAnalysisContext fc)
                {
                        VariableInfo variable_info = VariableInfo;
                        if (variable_info == null)
                                return;
 
-                       if (variable_info.IsAssigned (rc))
+                       if (fc.IsDefinitelyAssigned (variable_info))
                                return;
 
-                       rc.Report.Error (165, loc, "Use of unassigned local variable `{0}'", Name);
-                       variable_info.SetAssigned (rc);
+                       fc.Report.Error (165, loc, "Use of unassigned local variable `{0}'", Name);
+                       variable_info.SetAssigned (fc.DefiniteAssignment, true);
                }
 
                public override void SetHasAddressTaken ()
@@ -5689,8 +5798,6 @@ namespace Mono.CSharp
                {
                        local_info.SetIsUsed ();
 
-                       VerifyDefiniteAssignment (ec);
-
                        DoResolveBase (ec);
                        return this;
                }
@@ -5705,22 +5812,22 @@ namespace Mono.CSharp
                                local_info.SetIsUsed ();
 
                        if (local_info.IsReadonly && !ec.HasAny (ResolveContext.Options.FieldInitializerScope | ResolveContext.Options.UsingInitializerScope)) {
-                               int code;
-                               string msg;
-                               if (rhs == EmptyExpression.OutAccess) {
-                                       code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
-                               } else if (rhs == EmptyExpression.LValueMemberAccess) {
-                                       code = 1654; msg = "Cannot assign to members of `{0}' because it is a `{1}'";
-                               } else if (rhs == EmptyExpression.LValueMemberOutAccess) {
-                                       code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'";
-                               } else if (rhs == EmptyExpression.UnaryAddress) {
-                                       code = 459; msg = "Cannot take the address of {1} `{0}'";
+                               if (rhs == EmptyExpression.LValueMemberAccess) {
+                                       // CS1654 already reported
                                } else {
-                                       code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'";
+                                       int code;
+                                       string msg;
+                                       if (rhs == EmptyExpression.OutAccess) {
+                                               code = 1657; msg = "Cannot pass `{0}' as a ref or out argument because it is a `{1}'";
+                                       } else if (rhs == EmptyExpression.LValueMemberOutAccess) {
+                                               code = 1655; msg = "Cannot pass members of `{0}' as ref or out arguments because it is a `{1}'";
+                                       } else if (rhs == EmptyExpression.UnaryAddress) {
+                                               code = 459; msg = "Cannot take the address of {1} `{0}'";
+                                       } else {
+                                               code = 1656; msg = "Cannot assign to `{0}' because it is a `{1}'";
+                                       }
+                                       ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ());
                                }
-                               ec.Report.Error (code, loc, msg, Name, local_info.GetReadOnlyContext ());
-                       } else if (VariableInfo != null) {
-                               VariableInfo.SetAssigned (ec);
                        }
 
                        if (eclass == ExprClass.Unresolved)
@@ -5840,15 +5947,6 @@ namespace Mono.CSharp
                        Parameter.HasAddressTaken = true;
                }
 
-               void SetAssigned (ResolveContext ec)
-               {
-                       if (Parameter.HoistedVariant != null)
-                               Parameter.HoistedVariant.IsAssigned = true;
-
-                       if (HasOutModifier && ec.DoFlowAnalysis)
-                               ec.CurrentBranching.SetAssigned (VariableInfo);
-               }
-
                bool DoResolveBase (ResolveContext ec)
                {
                        if (eclass != ExprClass.Unresolved)
@@ -5914,7 +6012,6 @@ namespace Mono.CSharp
                        if (!DoResolveBase (ec))
                                return null;
 
-                       VerifyDefiniteAssignment (ec);
                        return this;
                }
 
@@ -5923,21 +6020,23 @@ namespace Mono.CSharp
                        if (!DoResolveBase (ec))
                                return null;
 
-                       SetAssigned (ec);
+                       if (Parameter.HoistedVariant != null)
+                               Parameter.HoistedVariant.IsAssigned = true;
+
                        return base.DoResolveLValue (ec, right_side);
                }
 
-               public override void VerifyDefiniteAssignment (ResolveContext rc)
+               public override void FlowAnalysis (FlowAnalysisContext fc)
                {
                        VariableInfo variable_info = VariableInfo;
                        if (variable_info == null)
                                return;
 
-                       if (variable_info.IsAssigned (rc))
+                       if (fc.IsDefinitelyAssigned (variable_info))
                                return;
 
-                       rc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name);
-                       variable_info.SetAssigned (rc);
+                       fc.Report.Error (269, loc, "Use of unassigned out parameter `{0}'", Name);
+                       fc.SetVariableAssigned (variable_info);
                }
        }
        
@@ -6014,7 +6113,17 @@ namespace Mono.CSharp
 
                        var emg = MethodGroup as ExtensionMethodGroupExpr;
                        if (emg != null) {
-                               return MethodGroupExpr.CreatePredefined (candidate, candidate.DeclaringType, MethodGroup.Location);
+                               var mg = MethodGroupExpr.CreatePredefined (candidate, candidate.DeclaringType, MethodGroup.Location);
+                               if (candidate.IsGeneric) {
+                                       var targs = new TypeExpression [candidate.Arity];
+                                       for (int i = 0; i < targs.Length; ++i) {
+                                               targs[i] = new TypeExpression (candidate.TypeArguments[i], MethodGroup.Location);
+                                       }
+
+                                       mg.SetTypeArguments (null, new TypeArguments (targs));
+                               }
+
+                               return mg;
                        }
 
                        return MethodGroup;
@@ -6191,6 +6300,17 @@ namespace Mono.CSharp
                        return mg.OverloadResolve (ec, ref arguments, null, OverloadResolver.Restrictions.None);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (mg.IsConditionallyExcluded)
+                               return;
+
+                       mg.FlowAnalysis (fc);
+
+                       if (arguments != null)
+                               arguments.FlowAnalysis (fc);
+               }
+
                public override string GetSignatureForError ()
                {
                        return mg.GetSignatureForError ();
@@ -6231,6 +6351,9 @@ namespace Mono.CSharp
 
                public override void Emit (EmitContext ec)
                {
+                       if (mg.IsConditionallyExcluded)
+                               return;
+
                        mg.EmitCall (ec, arguments);
                }
                
@@ -6616,6 +6739,12 @@ namespace Mono.CSharp
                                ec.Emit (OpCodes.Pop);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (arguments != null)
+                               arguments.FlowAnalysis (fc);
+               }
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        EmitAddressOf (ec, mode);
@@ -6776,6 +6905,11 @@ namespace Mono.CSharp
                {
                        throw new InternalErrorException ("Missing Resolve call");
                }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       throw new InternalErrorException ("Missing Resolve call");
+               }
                
                public override object Accept (StructuralVisitor visitor)
                {
@@ -7037,6 +7171,17 @@ namespace Mono.CSharp
                        ec.Report.Error (248, loc, "Cannot create an array with a negative size");
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       foreach (var arg in arguments)
+                               arg.FlowAnalysis (fc);
+
+                       if (array_data != null) {
+                               foreach (var ad in array_data)
+                                       ad.FlowAnalysis (fc);
+                       }
+               }
+
                bool InitializersContainAwait ()
                {
                        if (array_data == null)
@@ -7681,7 +7826,7 @@ namespace Mono.CSharp
 
                #endregion
 
-               public void CheckStructThisDefiniteAssignment (ResolveContext rc)
+               void CheckStructThisDefiniteAssignment (FlowAnalysisContext fc)
                {
                        //
                        // It's null for all cases when we don't need to check `this'
@@ -7690,13 +7835,10 @@ namespace Mono.CSharp
                        if (variable_info == null)
                                return;
 
-                       if (rc.OmitStructFlowAnalysis)
+                       if (fc.IsDefinitelyAssigned (variable_info))
                                return;
 
-                       if (!variable_info.IsAssigned (rc)) {
-                               rc.Report.Error (188, loc,
-                                       "The `this' object cannot be used before all of its fields are assigned to");
-                       }
+                       fc.Report.Error (188, loc, "The `this' object cannot be used before all of its fields are assigned to");
                }
 
                protected virtual void Error_ThisNotAvailable (ResolveContext ec)
@@ -7712,6 +7854,11 @@ namespace Mono.CSharp
                        }
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       CheckStructThisDefiniteAssignment (fc);
+               }
+
                public override HoistedVariable GetHoistedVariable (AnonymousExpression ae)
                {
                        if (ae == null)
@@ -7769,9 +7916,6 @@ namespace Mono.CSharp
                protected override Expression DoResolve (ResolveContext ec)
                {
                        ResolveBase (ec);
-
-                       CheckStructThisDefiniteAssignment (ec);
-
                        return this;
                }
 
@@ -7780,9 +7924,6 @@ namespace Mono.CSharp
                        if (eclass == ExprClass.Unresolved)
                                ResolveBase (ec);
 
-                       if (variable_info != null)
-                               variable_info.SetAssigned (ec);
-
                        if (type.IsClass){
                                if (right_side == EmptyExpression.UnaryAddress)
                                        ec.Report.Error (459, loc, "Cannot take the address of `this' because it is read-only");
@@ -7818,10 +7959,6 @@ namespace Mono.CSharp
                {
                        // Nothing
                }
-
-               public override void VerifyDefiniteAssignment (ResolveContext rc)
-               {
-               }
                
                public override object Accept (StructuralVisitor visitor)
                {
@@ -8604,50 +8741,25 @@ namespace Mono.CSharp
 
                protected override Expression DoResolve (ResolveContext rc)
                {
-                       var e = DoResolveName (rc, null);
-
-                       if (!rc.OmitStructFlowAnalysis) {
-                               var fe = e as FieldExpr;
-                               if (fe != null) {
-                                       fe.VerifyAssignedStructField (rc, null);
-                               }
-                       }
+                       var e = LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess);
+                       if (e != null)
+                               e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.MethodGroup);
 
                        return e;
                }
 
                public override Expression DoResolveLValue (ResolveContext rc, Expression rhs)
                {
-                       var e = DoResolveName (rc, rhs);
+                       var e = LookupNameExpression (rc, MemberLookupRestrictions.None);
 
-                       if (!rc.OmitStructFlowAnalysis) {
-                               var fe = e as FieldExpr;
-                               if (fe != null && fe.InstanceExpression is FieldExpr) {
-                                       fe = (FieldExpr) fe.InstanceExpression;
-                                       fe.VerifyAssignedStructField (rc, rhs);
-                               }
-                       }
-
-                       return e;
-               }
-
-               Expression DoResolveName (ResolveContext rc, Expression right_side)
-               {
-                       Expression e = LookupNameExpression (rc, right_side == null ? MemberLookupRestrictions.ReadAccess : MemberLookupRestrictions.None);
-                       if (e == null)
+                       if (e is TypeExpr) {
+                               e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc);
                                return null;
-
-                       if (right_side != null) {
-                               if (e is TypeExpr) {
-                                       e.Error_UnexpectedKind (rc, ResolveFlags.VariableOrValue, loc);
-                                       return null;
-                               }
-
-                               e = e.ResolveLValue (rc, right_side);
-                       } else {
-                               e = e.Resolve (rc, ResolveFlags.VariableOrValue | ResolveFlags.Type | ResolveFlags.MethodGroup);
                        }
 
+                       if (e != null)
+                               e = e.ResolveLValue (rc, rhs);
+
                        return e;
                }
 
@@ -8672,32 +8784,22 @@ namespace Mono.CSharp
                        var sn = expr as SimpleName;
                        const ResolveFlags flags = ResolveFlags.VariableOrValue | ResolveFlags.Type;
 
-                       //
-                       // Resolve the expression with flow analysis turned off, we'll do the definite
-                       // assignment checks later.  This is because we don't know yet what the expression
-                       // will resolve to - it may resolve to a FieldExpr and in this case we must do the
-                       // definite assignment check on the actual field and not on the whole struct.
-                       //
-                       using (rc.Set (ResolveContext.Options.OmitStructFlowAnalysis)) {
-                               if (sn != null) {
-                                       expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
+                       if (sn != null) {
+                               expr = sn.LookupNameExpression (rc, MemberLookupRestrictions.ReadAccess | MemberLookupRestrictions.ExactArity);
 
-                                       //
-                                       // Resolve expression which does have type set as we need expression type
-                                       // with disable flow analysis as we don't know whether left side expression
-                                       // is used as variable or type
-                                       //
-                                       if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
-                                               using (rc.With (ResolveContext.Options.DoFlowAnalysis, false)) {
-                                                       expr = expr.Resolve (rc);
-                                               }
-                                       } else if (expr is TypeParameterExpr) {
-                                               expr.Error_UnexpectedKind (rc, flags, sn.Location);
-                                               expr = null;
-                                       }
-                               } else {
-                                       expr = expr.Resolve (rc, flags);
+                               //
+                               // Resolve expression which does have type set as we need expression type
+                               // with disable flow analysis as we don't know whether left side expression
+                               // is used as variable or type
+                               //
+                               if (expr is VariableReference || expr is ConstantExpr || expr is Linq.TransparentMemberAccess) {
+                                       expr = expr.Resolve (rc);
+                               } else if (expr is TypeParameterExpr) {
+                                       expr.Error_UnexpectedKind (rc, flags, sn.Location);
+                                       expr = null;
                                }
+                       } else {
+                               expr = expr.Resolve (rc, flags);
                        }
 
                        if (expr == null)
@@ -8725,16 +8827,6 @@ namespace Mono.CSharp
                                if (me != null)
                                        me.ResolveInstanceExpression (rc, null);
 
-                               //
-                               // Run defined assigned checks on expressions resolved with
-                               // disabled flow-analysis
-                               //
-                               if (sn != null) {
-                                       var vr = expr as VariableReference;
-                                       if (vr != null)
-                                               vr.VerifyDefiniteAssignment (rc);
-                               }
-
                                Arguments args = new Arguments (1);
                                args.Add (new Argument (expr));
                                return new DynamicMemberBinder (Name, args, loc);
@@ -8765,16 +8857,6 @@ namespace Mono.CSharp
                                                                emg.SetTypeArguments (rc, targs);
                                                        }
 
-                                                       //
-                                                       // Run defined assigned checks on expressions resolved with
-                                                       // disabled flow-analysis
-                                                       //
-                                                       if (sn != null && !errorMode) {
-                                                               var vr = expr as VariableReference;
-                                                               if (vr != null)
-                                                                       vr.VerifyDefiniteAssignment (rc);
-                                                       }
-
                                                        // TODO: it should really skip the checks bellow
                                                        return emg.Resolve (rc);
                                                }
@@ -8847,16 +8929,6 @@ namespace Mono.CSharp
                                me.SetTypeArguments (rc, targs);
                        }
 
-                       //
-                       // Run defined assigned checks on expressions resolved with
-                       // disabled flow-analysis
-                       //
-                       if (sn != null && !(me is FieldExpr && TypeSpec.IsValueType (expr_type))) {
-                               var vr = expr as VariableReference;
-                               if (vr != null)
-                                       vr.VerifyDefiniteAssignment (rc);
-                       }
-
                        return me;
                }
 
@@ -9069,6 +9141,11 @@ namespace Mono.CSharp
                                Expr.EmitBranchable (ec, target, on_true);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Expr.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        using (ctx.With (BuilderContext.Options.CheckedScope, true)) {
@@ -9141,6 +9218,11 @@ namespace Mono.CSharp
                                Expr.EmitBranchable (ec, target, on_true);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Expr.FlowAnalysis (fc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        UnCheckedExpr target = (UnCheckedExpr) t;
@@ -9279,6 +9361,12 @@ namespace Mono.CSharp
                        Report.Error (1742, na.Location, "An element access expression cannot use named argument");
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Expr.FlowAnalysis (fc);
+                       Arguments.FlowAnalysis (fc);
+               }
+
                public override string GetSignatureForError ()
                {
                        return Expr.GetSignatureForError ();
@@ -9381,6 +9469,11 @@ namespace Mono.CSharp
                        ec.Report.Warning (251, 2, loc, "Indexing an array with a negative index (array indices always start at zero)");
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       ea.FlowAnalysis (fc);
+               }
+
                //
                // Load the array arguments into the stack.
                //
@@ -9678,6 +9771,13 @@ namespace Mono.CSharp
                        }
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       // TODO: Check the order
+                       base.FlowAnalysis (fc);
+                       arguments.FlowAnalysis (fc);
+               }
+
                public override string GetSignatureForError ()
                {
                        return best_candidate.GetSignatureForError ();
@@ -10088,6 +10188,11 @@ namespace Mono.CSharp
                        ec.Emit (OpCodes.Call, method);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       source.FlowAnalysis (fc);
+               }
+
                public override string GetSignatureForError ()
                {
                        return TypeManager.CSharpSignature (method);
@@ -10789,6 +10894,12 @@ namespace Mono.CSharp
                                e.EmitStatement (ec);
                        }
                }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       foreach (var initializer in initializers)
+                               initializer.FlowAnalysis (fc);
+               }
        }
        
        //
@@ -10983,6 +11094,12 @@ namespace Mono.CSharp
                        return instance;
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       base.FlowAnalysis (fc);
+                       initializers.FlowAnalysis (fc);
+               }
+
                public override object Accept (StructuralVisitor visitor)
                {
                        return visitor.Visit (this);
index 3e2b2c82dab33511775ee9740b9964bab188c3b2..4f54f268d29295abe4a7cdb611a95bb264cdce15 100644 (file)
@@ -17,1055 +17,6 @@ using System.Collections.Generic;
 
 namespace Mono.CSharp
 {
-       // <summary>
-       //   A new instance of this class is created every time a new block is resolved
-       //   and if there's branching in the block's control flow.
-       // </summary>
-       public abstract class FlowBranching
-       {
-               // <summary>
-               //   The type of a FlowBranching.
-               // </summary>
-               public enum BranchingType : byte {
-                       // Normal (conditional or toplevel) block.
-                       Block,
-
-                       // Conditional.
-                       Conditional,
-
-                       // A loop block.
-                       Loop,
-
-                       // The statement embedded inside a loop
-                       Embedded,
-
-                       // part of a block headed by a jump target
-                       Labeled,
-
-                       // TryCatch block.
-                       TryCatch,
-
-                       // TryFinally, Using, Lock, CollectionForeach
-                       Exception,
-
-                       // Switch block.
-                       Switch,
-
-                       // The toplevel block of a function
-                       Toplevel,
-
-                       // An iterator block
-                       Iterator
-               }
-
-               // <summary>
-               //   The type of one sibling of a branching.
-               // </summary>
-               public enum SiblingType : byte {
-                       Block,
-                       Conditional,
-                       SwitchSection,
-                       Try,
-                       Catch,
-                       Finally
-               }
-
-               public static FlowBranching CreateBranching (FlowBranching parent, BranchingType type, Block block, Location loc)
-               {
-                       switch (type) {
-                       case BranchingType.Exception:
-                       case BranchingType.Labeled:
-                       case BranchingType.Toplevel:
-                       case BranchingType.TryCatch:
-                               throw new InvalidOperationException ();
-
-                       case BranchingType.Switch:
-                               return new FlowBranchingBreakable (parent, type, SiblingType.SwitchSection, block, loc);
-
-                       case BranchingType.Block:
-                               return new FlowBranchingBlock (parent, type, SiblingType.Block, block, loc);
-
-                       case BranchingType.Loop:
-                               return new FlowBranchingBreakable (parent, type, SiblingType.Conditional, block, loc);
-
-                       case BranchingType.Embedded:
-                               return new FlowBranchingContinuable (parent, type, SiblingType.Conditional, block, loc);
-
-                       default:
-                               return new FlowBranchingBlock (parent, type, SiblingType.Conditional, block, loc);
-                       }
-               }
-
-               // <summary>
-               //   The type of this flow branching.
-               // </summary>
-               public readonly BranchingType Type;
-
-               // <summary>
-               //   The block this branching is contained in.  This may be null if it's not
-               //   a top-level block and it doesn't declare any local variables.
-               // </summary>
-               public readonly Block Block;
-
-               // <summary>
-               //   The parent of this branching or null if this is the top-block.
-               // </summary>
-               public readonly FlowBranching Parent;
-
-               // <summary>
-               //   Start-Location of this flow branching.
-               // </summary>
-               public readonly Location Location;
-
-               static int next_id;
-               int id;
-
-               // <summary>
-               //   The vector contains a BitArray with information about which local variables
-               //   and parameters are already initialized at the current code position.
-               // </summary>
-               public class UsageVector {
-                       // <summary>
-                       //   The type of this branching.
-                       // </summary>
-                       public readonly SiblingType Type;
-
-                       // <summary>
-                       //   Start location of this branching.
-                       // </summary>
-                       public Location Location;
-
-                       // <summary>
-                       //   This is only valid for SwitchSection, Try, Catch and Finally.
-                       // </summary>
-                       public readonly Block Block;
-
-                       // <summary>
-                       //   The number of locals in this block.
-                       // </summary>
-                       public readonly int CountLocals;
-
-                       // <summary>
-                       //   If not null, then we inherit our state from this vector and do a
-                       //   copy-on-write.  If null, then we're the first sibling in a top-level
-                       //   block and inherit from the empty vector.
-                       // </summary>
-                       public readonly UsageVector InheritsFrom;
-
-                       // <summary>
-                       //   This is used to construct a list of UsageVector's.
-                       // </summary>
-                       public UsageVector Next;
-
-                       //
-                       // Private.
-                       //
-                       MyBitVector locals;
-                       bool is_unreachable;
-
-                       static int next_id;
-                       int id;
-
-                       //
-                       // Normally, you should not use any of these constructors.
-                       //
-                       public UsageVector (SiblingType type, UsageVector parent, Block block, Location loc, int num_locals)
-                       {
-                               this.Type = type;
-                               this.Block = block;
-                               this.Location = loc;
-                               this.InheritsFrom = parent;
-                               this.CountLocals = num_locals;
-
-                               locals = num_locals == 0 
-                                       ? MyBitVector.Empty
-                                       : new MyBitVector (parent == null ? MyBitVector.Empty : parent.locals, num_locals);
-
-                               if (parent != null)
-                                       is_unreachable = parent.is_unreachable;
-
-                               id = ++next_id;
-
-                       }
-
-                       public UsageVector (SiblingType type, UsageVector parent, Block block, Location loc)
-                               : this (type, parent, block, loc, parent.CountLocals)
-                       { }
-
-                       private UsageVector (MyBitVector locals, bool is_unreachable, Block block, Location loc)
-                       {
-                               this.Type = SiblingType.Block;
-                               this.Location = loc;
-                               this.Block = block;
-
-                               this.is_unreachable = is_unreachable;
-
-                               this.locals = locals;
-
-                               id = ++next_id;
-
-                       }
-
-                       // <summary>
-                       //   This does a deep copy of the usage vector.
-                       // </summary>
-                       public UsageVector Clone ()
-                       {
-                               UsageVector retval = new UsageVector (Type, null, Block, Location, CountLocals);
-
-                               retval.locals = locals.Clone ();
-                               retval.is_unreachable = is_unreachable;
-
-                               return retval;
-                       }
-
-                       public bool IsAssigned (VariableInfo var, bool ignoreReachability)
-                       {
-                               if (!ignoreReachability && !var.IsParameter && IsUnreachable)
-                                       return true;
-
-                               return var.IsAssigned (locals);
-                       }
-
-                       public void SetAssigned (VariableInfo var)
-                       {
-                               if (!var.IsParameter && IsUnreachable)
-                                       return;
-
-                               var.SetAssigned (locals);
-                       }
-
-                       public bool IsFieldAssigned (VariableInfo var, string name)
-                       {
-                               if (/*!var.IsParameter &&*/ IsUnreachable)
-                                       return true;
-
-                               return var.IsStructFieldAssigned (locals, name);
-                       }
-
-                       public void SetFieldAssigned (VariableInfo var, string name)
-                       {
-                               if (/*!var.IsParameter &&*/ IsUnreachable)
-                                       return;
-
-                               var.SetStructFieldAssigned (locals, name);
-                       }
-
-                       public bool IsUnreachable {
-                               get {
-                                       return is_unreachable;
-                               }
-                               set {
-                                       is_unreachable = value;
-                               }
-                       }
-
-                       public void ResetBarrier ()
-                       {
-                               is_unreachable = false;
-                       }
-
-                       public void Goto ()
-                       {
-                               is_unreachable = true;
-                       }
-
-                       public static UsageVector MergeSiblings (UsageVector sibling_list, Location loc)
-                       {
-                               if (sibling_list.Next == null)
-                                       return sibling_list;
-
-                               MyBitVector locals = null;
-                               bool is_unreachable = sibling_list.is_unreachable;
-
-                               if (!sibling_list.IsUnreachable)
-                                       locals &= sibling_list.locals;
-
-                               for (UsageVector child = sibling_list.Next; child != null; child = child.Next) {
-                                       is_unreachable &= child.is_unreachable;
-
-                                       if (!child.IsUnreachable)
-                                               locals &= child.locals;
-                               }
-
-                               return new UsageVector (locals, is_unreachable, null, loc);
-                       }
-
-                       // <summary>
-                       //   Merges a child branching.
-                       // </summary>
-                       public UsageVector MergeChild (UsageVector child, bool overwrite)
-                       {
-                               Report.Debug (2, "    MERGING CHILD EFFECTS", this, child, Type);
-
-                               bool new_isunr = child.is_unreachable;
-
-                               //
-                               // We've now either reached the point after the branching or we will
-                               // never get there since we always return or always throw an exception.
-                               //
-                               // If we can reach the point after the branching, mark all locals and
-                               // parameters as initialized which have been initialized in all branches
-                               // we need to look at (see above).
-                               //
-
-                               if ((Type == SiblingType.SwitchSection) && !new_isunr) {
-                                       Report.Error (163, Location,
-                                                     "Control cannot fall through from one " +
-                                                     "case label to another");
-                                       return child;
-                               }
-
-                               locals |= child.locals;
-
-                               // throw away un-necessary information about variables in child blocks
-                               if (locals.Count != CountLocals)
-                                       locals = new MyBitVector (locals, CountLocals);
-
-                               if (overwrite)
-                                       is_unreachable = new_isunr;
-                               else
-                                       is_unreachable |= new_isunr;
-
-                               return child;
-                       }
-
-                       public void MergeOrigins (UsageVector o_vectors)
-                       {
-                               Report.Debug (1, "  MERGING BREAK ORIGINS", this);
-
-                               if (o_vectors == null)
-                                       return;
-
-                               if (IsUnreachable && locals != null)
-                                       locals.SetAll (true);
-
-                               for (UsageVector vector = o_vectors; vector != null; vector = vector.Next) {
-                                       Report.Debug (1, "    MERGING BREAK ORIGIN", vector);
-                                       if (vector.IsUnreachable)
-                                               continue;
-                                       locals &= vector.locals;
-                                       is_unreachable &= vector.is_unreachable;
-                               }
-
-                               Report.Debug (1, "  MERGING BREAK ORIGINS DONE", this);
-                       }
-
-                       //
-                       // Debugging stuff.
-                       //
-
-                       public override string ToString ()
-                       {
-                               return String.Format ("Vector ({0},{1},{2}-{3})", Type, id, is_unreachable, locals);
-                       }
-               }
-
-               // <summary>
-               //   Creates a new flow branching which is contained in `parent'.
-               //   You should only pass non-null for the `block' argument if this block
-               //   introduces any new variables - in this case, we need to create a new
-               //   usage vector with a different size than our parent's one.
-               // </summary>
-               protected FlowBranching (FlowBranching parent, BranchingType type, SiblingType stype,
-                                        Block block, Location loc)
-               {
-                       Parent = parent;
-                       Block = block;
-                       Location = loc;
-                       Type = type;
-                       id = ++next_id;
-
-                       UsageVector vector;
-                       if (Block != null) {
-                               UsageVector parent_vector = parent != null ? parent.CurrentUsageVector : null;
-                               vector = new UsageVector (stype, parent_vector, Block, loc, Block.AssignableSlots);
-                       } else {
-                               vector = new UsageVector (stype, Parent.CurrentUsageVector, null, loc);
-                       }
-
-                       AddSibling (vector);
-               }
-
-               public abstract UsageVector CurrentUsageVector {
-                       get;
-               }                               
-
-               // <summary>
-               //   Creates a sibling of the current usage vector.
-               // </summary>
-               public void CreateSibling (Block block, SiblingType type)
-               {
-                       UsageVector vector = new UsageVector (
-                               type, Parent.CurrentUsageVector, block, Location);
-                       AddSibling (vector);
-
-                       Report.Debug (1, "  CREATED SIBLING", CurrentUsageVector);
-               }
-
-               public void CreateSibling ()
-               {
-                       CreateSibling (null, SiblingType.Conditional);
-               }
-
-               protected abstract void AddSibling (UsageVector uv);
-
-               protected abstract UsageVector Merge ();
-
-               public UsageVector MergeChild (FlowBranching child)
-               {
-                       return CurrentUsageVector.MergeChild (child.Merge (), true);
-               }
-
-               public virtual bool CheckRethrow (Location loc)
-               {
-                       return Parent.CheckRethrow (loc);
-               }
-
-               public virtual bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
-               {
-                       return Parent.AddResumePoint (stmt, current, out pc);
-               }
-
-               // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
-               public virtual bool AddBreakOrigin (UsageVector vector, Location loc)
-               {
-                       return Parent.AddBreakOrigin (vector, loc);
-               }
-
-               // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
-               public virtual bool AddContinueOrigin (UsageVector vector, Location loc)
-               {
-                       return Parent.AddContinueOrigin (vector, loc);
-               }
-
-               // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
-               public virtual bool AddReturnOrigin (UsageVector vector, ExitStatement stmt)
-               {
-                       return Parent.AddReturnOrigin (vector, stmt);
-               }
-
-               // returns true if we crossed an unwind-protected region (try/catch/finally, lock, using, ...)
-               public virtual bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       return Parent.AddGotoOrigin (vector, goto_stmt);
-               }
-
-               public bool IsAssigned (VariableInfo vi)
-               {
-                       return CurrentUsageVector.IsAssigned (vi, false);
-               }
-
-               public bool IsStructFieldAssigned (VariableInfo vi, string field_name)
-               {
-                       return CurrentUsageVector.IsAssigned (vi, false) || CurrentUsageVector.IsFieldAssigned (vi, field_name);
-               }
-
-               protected static Report Report {
-                       get { return RootContext.ToplevelTypes.Compiler.Report; }
-               }
-
-               public void SetAssigned (VariableInfo vi)
-               {
-                       CurrentUsageVector.SetAssigned (vi);
-               }
-
-               public void SetFieldAssigned (VariableInfo vi, string name)
-               {
-                       CurrentUsageVector.SetFieldAssigned (vi, name);
-               }
-
-#if DEBUG
-               public override string ToString ()
-               {
-                       StringBuilder sb = new StringBuilder ();
-                       sb.Append (GetType ());
-                       sb.Append (" (");
-
-                       sb.Append (id);
-                       sb.Append (",");
-                       sb.Append (Type);
-                       if (Block != null) {
-                               sb.Append (" - ");
-                               sb.Append (Block.ID);
-                               sb.Append (" - ");
-                               sb.Append (Block.StartLocation);
-                       }
-                       sb.Append (" - ");
-                       // sb.Append (Siblings.Length);
-                       // sb.Append (" - ");
-                       sb.Append (CurrentUsageVector);
-                       sb.Append (")");
-                       return sb.ToString ();
-               }
-#endif
-
-               public string Name {
-                       get { return String.Format ("{0} ({1}:{2}:{3})", GetType (), id, Type, Location); }
-               }
-       }
-
-       public class FlowBranchingBlock : FlowBranching
-       {
-               UsageVector sibling_list = null;
-
-               public FlowBranchingBlock (FlowBranching parent, BranchingType type,
-                                          SiblingType stype, Block block, Location loc)
-                       : base (parent, type, stype, block, loc)
-               { }
-
-               public override UsageVector CurrentUsageVector {
-                       get { return sibling_list; }
-               }
-
-               protected override void AddSibling (UsageVector sibling)
-               {
-                       if (sibling_list != null && sibling_list.Type == SiblingType.Block)
-                               throw new InternalErrorException ("Blocks don't have sibling flow paths");
-                       sibling.Next = sibling_list;
-                       sibling_list = sibling;
-               }
-
-               public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       LabeledStatement stmt = Block == null ? null : Block.LookupLabel (goto_stmt.Target);
-                       if (stmt == null)
-                               return Parent.AddGotoOrigin (vector, goto_stmt);
-
-                       // forward jump
-                       goto_stmt.SetResolvedTarget (stmt);
-                       stmt.AddUsageVector (vector);
-                       return false;
-               }
-               
-               public static void Error_UnknownLabel (Location loc, string label, Report Report)
-               {
-                       Report.Error(159, loc, "The label `{0}:' could not be found within the scope of the goto statement",
-                               label);
-               }
-
-               protected override UsageVector Merge ()
-               {
-                       Report.Debug (2, "  MERGING SIBLINGS", Name);
-                       UsageVector vector = UsageVector.MergeSiblings (sibling_list, Location);
-                       Report.Debug (2, "  MERGING SIBLINGS DONE", Name, vector);
-                       return vector;
-               }
-       }
-
-       public class FlowBranchingBreakable : FlowBranchingBlock
-       {
-               UsageVector break_origins;
-
-               public FlowBranchingBreakable (FlowBranching parent, BranchingType type, SiblingType stype, Block block, Location loc)
-                       : base (parent, type, stype, block, loc)
-               { }
-
-               public override bool AddBreakOrigin (UsageVector vector, Location loc)
-               {
-                       vector = vector.Clone ();
-                       vector.Next = break_origins;
-                       break_origins = vector;
-                       return false;
-               }
-
-               protected override UsageVector Merge ()
-               {
-                       UsageVector vector = base.Merge ();
-                       vector.MergeOrigins (break_origins);
-                       return vector;
-               }
-       }
-
-       public class FlowBranchingContinuable : FlowBranchingBlock
-       {
-               UsageVector continue_origins;
-
-               public FlowBranchingContinuable (FlowBranching parent, BranchingType type, SiblingType stype, Block block, Location loc)
-                       : base (parent, type, stype, block, loc)
-               { }
-
-               public override bool AddContinueOrigin (UsageVector vector, Location loc)
-               {
-                       vector = vector.Clone ();
-                       vector.Next = continue_origins;
-                       continue_origins = vector;
-                       return false;
-               }
-
-               protected override UsageVector Merge ()
-               {
-                       UsageVector vector = base.Merge ();
-                       vector.MergeOrigins (continue_origins);
-                       return vector;
-               }
-       }
-
-       public class FlowBranchingLabeled : FlowBranchingBlock
-       {
-               LabeledStatement stmt;
-               UsageVector actual;
-
-               public FlowBranchingLabeled (FlowBranching parent, LabeledStatement stmt)
-                       : base (parent, BranchingType.Labeled, SiblingType.Conditional, null, stmt.loc)
-               {
-                       this.stmt = stmt;
-                       CurrentUsageVector.MergeOrigins (stmt.JumpOrigins);
-                       actual = CurrentUsageVector.Clone ();
-
-                       // stand-in for backward jumps
-                       CurrentUsageVector.ResetBarrier ();
-               }
-
-               public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       if (goto_stmt.Target != stmt.Name)
-                               return Parent.AddGotoOrigin (vector, goto_stmt);
-
-                       // backward jump
-                       goto_stmt.SetResolvedTarget (stmt);
-                       actual.MergeOrigins (vector.Clone ());
-
-                       return false;
-               }
-
-               protected override UsageVector Merge ()
-               {
-                       UsageVector vector = base.Merge ();
-
-                       if (actual.IsUnreachable)
-                               Report.Warning (162, 2, stmt.loc, "Unreachable code detected");
-
-                       actual.MergeChild (vector, false);
-                       return actual;
-               }
-       }
-
-       public class FlowBranchingIterator : FlowBranchingBlock
-       {
-               readonly Iterator iterator;
-
-               public FlowBranchingIterator (FlowBranching parent, Iterator iterator)
-                       : base (parent, BranchingType.Iterator, SiblingType.Block, iterator.Block, iterator.Location)
-               {
-                       this.iterator = iterator;
-               }
-
-               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
-               {
-                       pc = iterator.AddResumePoint (current);
-                       return false;
-               }
-       }
-
-       public class FlowBranchingToplevel : FlowBranchingBlock
-       {
-               UsageVector return_origins;
-
-               public FlowBranchingToplevel (FlowBranching parent, ParametersBlock stmt)
-                       : base (parent, BranchingType.Toplevel, SiblingType.Conditional, stmt, stmt.loc)
-               {
-               }
-
-               public override bool CheckRethrow (Location loc)
-               {
-                       Report.Error (156, loc, "A throw statement with no arguments is not allowed outside of a catch clause");
-                       return false;
-               }
-
-               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
-               {
-                       throw new InternalErrorException ("A yield in a non-iterator block");
-               }
-
-               public override bool AddBreakOrigin (UsageVector vector, Location loc)
-               {
-                       Report.Error (139, loc, "No enclosing loop out of which to break or continue");
-                       return false;
-               }
-
-               public override bool AddContinueOrigin (UsageVector vector, Location loc)
-               {
-                       Report.Error (139, loc, "No enclosing loop out of which to break or continue");
-                       return false;
-               }
-
-               public override bool AddReturnOrigin (UsageVector vector, ExitStatement stmt)
-               {
-                       vector = vector.Clone ();
-                       vector.Location = stmt.loc;
-                       vector.Next = return_origins;
-                       return_origins = vector;
-                       return false;
-               }
-
-               public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       string name = goto_stmt.Target;
-                       LabeledStatement s = Block.LookupLabel (name);
-                       if (s != null)
-                               throw new InternalErrorException ("Shouldn't get here");
-
-                       if (Parent == null) {
-                               Error_UnknownLabel (goto_stmt.loc, name, Report);
-                               return false;
-                       }
-
-                       int errors = Report.Errors;
-                       Parent.AddGotoOrigin (vector, goto_stmt);
-                       if (errors == Report.Errors)
-                               Report.Error (1632, goto_stmt.loc, "Control cannot leave the body of an anonymous method");
-                       return false;
-               }
-
-               protected override UsageVector Merge ()
-               {
-                       for (UsageVector origin = return_origins; origin != null; origin = origin.Next)
-                               Block.ParametersBlock.CheckOutParameters (origin);
-
-                       UsageVector vector = base.Merge ();
-                       Block.ParametersBlock.CheckOutParameters (vector);
-                       // Note: we _do_not_ merge in the return origins
-                       return vector;
-               }
-
-               public bool End ()
-               {
-                       return Merge ().IsUnreachable;
-               }
-       }
-
-       public class FlowBranchingTryCatch : FlowBranchingBlock
-       {
-               readonly TryCatch tc;
-
-               public FlowBranchingTryCatch (FlowBranching parent, TryCatch stmt)
-                       : base (parent, BranchingType.Block, SiblingType.Try, null, stmt.loc)
-               {
-                       this.tc = stmt;
-               }
-
-               public override bool CheckRethrow (Location loc)
-               {
-                       return CurrentUsageVector.Next != null || Parent.CheckRethrow (loc);
-               }
-
-               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
-               {
-                       int errors = Report.Errors;
-                       Parent.AddResumePoint (stmt, tc.IsTryCatchFinally ? current : tc, out pc);
-                       if (errors == Report.Errors) {
-                               if (stmt is AwaitStatement) {
-                                       if (CurrentUsageVector.Next != null) {
-                                               Report.Error (1985, stmt.loc, "The `await' operator cannot be used in the body of a catch clause");
-                                       } else {
-                                               this.tc.AddResumePoint (current, pc);
-                                       }
-                               } else {
-                                       if (CurrentUsageVector.Next == null)
-                                               Report.Error (1626, stmt.loc, "Cannot yield a value in the body of a try block with a catch clause");
-                                       else
-                                               Report.Error (1631, stmt.loc, "Cannot yield a value in the body of a catch clause");
-                               }
-                       }
-
-                       return true;
-               }
-
-               public override bool AddBreakOrigin (UsageVector vector, Location loc)
-               {
-                       Parent.AddBreakOrigin (vector, loc);
-                       tc.SomeCodeFollows ();
-                       return true;
-               }
-
-               public override bool AddContinueOrigin (UsageVector vector, Location loc)
-               {
-                       Parent.AddContinueOrigin (vector, loc);
-                       tc.SomeCodeFollows ();
-                       return true;
-               }
-
-               public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt)
-               {
-                       Parent.AddReturnOrigin (vector, exit_stmt);
-                       tc.SomeCodeFollows ();
-                       return true;
-               }
-
-               public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       Parent.AddGotoOrigin (vector, goto_stmt);
-                       return true;
-               }
-       }
-
-       public class FlowBranchingAsync : FlowBranchingBlock
-       {
-               readonly AsyncInitializer async_init;
-
-               public FlowBranchingAsync (FlowBranching parent, AsyncInitializer async_init)
-                       : base (parent, BranchingType.Block, SiblingType.Try, null, async_init.Location)
-               {
-                       this.async_init = async_init;
-               }
-/*
-               public override bool CheckRethrow (Location loc)
-               {
-                       return CurrentUsageVector.Next != null || Parent.CheckRethrow (loc);
-               }
-*/
-               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
-               {
-                       pc = async_init.AddResumePoint (current);
-                       return true;
-               }
-
-               public override bool AddBreakOrigin (UsageVector vector, Location loc)
-               {
-                       Parent.AddBreakOrigin (vector, loc);
-                       return true;
-               }
-
-               public override bool AddContinueOrigin (UsageVector vector, Location loc)
-               {
-                       Parent.AddContinueOrigin (vector, loc);
-                       return true;
-               }
-
-               public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt)
-               {
-                       Parent.AddReturnOrigin (vector, exit_stmt);
-                       return true;
-               }
-
-               public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       Parent.AddGotoOrigin (vector, goto_stmt);
-                       return true;
-               }
-       }
-
-       public class FlowBranchingTryFinally : FlowBranching
-       {
-               ExceptionStatement stmt;
-               UsageVector current_vector;
-               UsageVector try_vector;
-               UsageVector finally_vector;
-
-               abstract class SavedOrigin {
-                       public readonly SavedOrigin Next;
-                       public readonly UsageVector Vector;
-
-                       protected SavedOrigin (SavedOrigin next, UsageVector vector)
-                       {
-                               Next = next;
-                               Vector = vector.Clone ();
-                       }
-
-                       protected abstract void DoPropagateFinally (FlowBranching parent);
-                       public void PropagateFinally (UsageVector finally_vector, FlowBranching parent)
-                       {
-                               if (finally_vector != null)
-                                       Vector.MergeChild (finally_vector, false);
-                               DoPropagateFinally (parent);
-                       }
-               }
-
-               class BreakOrigin : SavedOrigin {
-                       Location Loc;
-                       public BreakOrigin (SavedOrigin next, UsageVector vector, Location loc)
-                               : base (next, vector)
-                       {
-                               Loc = loc;
-                       }
-
-                       protected override void DoPropagateFinally (FlowBranching parent)
-                       {
-                               parent.AddBreakOrigin (Vector, Loc);
-                       }
-               }
-
-               class ContinueOrigin : SavedOrigin {
-                       Location Loc;
-                       public ContinueOrigin (SavedOrigin next, UsageVector vector, Location loc)
-                               : base (next, vector)
-                       {
-                               Loc = loc;
-                       }
-
-                       protected override void DoPropagateFinally (FlowBranching parent)
-                       {
-                               parent.AddContinueOrigin (Vector, Loc);
-                       }
-               }
-
-               class ReturnOrigin : SavedOrigin {
-                       public ExitStatement Stmt;
-
-                       public ReturnOrigin (SavedOrigin next, UsageVector vector, ExitStatement stmt)
-                               : base (next, vector)
-                       {
-                               Stmt = stmt;
-                       }
-
-                       protected override void DoPropagateFinally (FlowBranching parent)
-                       {
-                               parent.AddReturnOrigin (Vector, Stmt);
-                       }
-               }
-
-               class GotoOrigin : SavedOrigin {
-                       public Goto Stmt;
-
-                       public GotoOrigin (SavedOrigin next, UsageVector vector, Goto stmt)
-                               : base (next, vector)
-                       {
-                               Stmt = stmt;
-                       }
-
-                       protected override void DoPropagateFinally (FlowBranching parent)
-                       {
-                               parent.AddGotoOrigin (Vector, Stmt);
-                       }
-               }
-
-               SavedOrigin saved_origins;
-
-               public FlowBranchingTryFinally (FlowBranching parent,
-                                              ExceptionStatement stmt)
-                       : base (parent, BranchingType.Exception, SiblingType.Try,
-                               null, stmt.loc)
-               {
-                       this.stmt = stmt;
-               }
-
-               protected override void AddSibling (UsageVector sibling)
-               {
-                       switch (sibling.Type) {
-                       case SiblingType.Try:
-                               try_vector = sibling;
-                               break;
-                       case SiblingType.Finally:
-                               finally_vector = sibling;
-                               break;
-                       default:
-                               throw new InvalidOperationException ();
-                       }
-                       current_vector = sibling;
-               }
-
-               public override UsageVector CurrentUsageVector {
-                       get { return current_vector; }
-               }
-
-               public override bool CheckRethrow (Location loc)
-               {
-                       if (!Parent.CheckRethrow (loc))
-                               return false;
-                       if (finally_vector == null)
-                               return true;
-                       Report.Error (724, loc, "A throw statement with no arguments is not allowed inside of a finally clause nested inside of the innermost catch clause");
-                       return false;
-               }
-
-               public override bool AddResumePoint (ResumableStatement stmt, ResumableStatement current, out int pc)
-               {
-                       int errors = Report.Errors;
-                       Parent.AddResumePoint (stmt, this.stmt, out pc);
-                       if (errors == Report.Errors) {
-                               if (finally_vector == null)
-                                       this.stmt.AddResumePoint (current, pc);
-                               else {
-                                       if (stmt is AwaitStatement) {
-                                               Report.Error (1984, stmt.loc, "The `await' operator cannot be used in the body of a finally clause");
-                                       } else {
-                                               Report.Error (1625, stmt.loc, "Cannot yield in the body of a finally clause");
-                                       }
-                               }
-                       }
-                       return true;
-               }
-
-               public override bool AddBreakOrigin (UsageVector vector, Location loc)
-               {
-                       if (finally_vector != null) {
-                               int errors = Report.Errors;
-                               Parent.AddBreakOrigin (vector, loc);
-                               if (errors == Report.Errors)
-                                       Report.Error (157, loc, "Control cannot leave the body of a finally clause");
-                       } else {
-                               saved_origins = new BreakOrigin (saved_origins, vector, loc);
-                       }
-
-                       // either the loop test or a back jump will follow code
-                       stmt.SomeCodeFollows ();
-                       return true;
-               }
-
-               public override bool AddContinueOrigin (UsageVector vector, Location loc)
-               {
-                       if (finally_vector != null) {
-                               int errors = Report.Errors;
-                               Parent.AddContinueOrigin (vector, loc);
-                               if (errors == Report.Errors)
-                                       Report.Error (157, loc, "Control cannot leave the body of a finally clause");
-                       } else {
-                               saved_origins = new ContinueOrigin (saved_origins, vector, loc);
-                       }
-
-                       // either the loop test or a back jump will follow code
-                       stmt.SomeCodeFollows ();
-                       return true;
-               }
-
-               public override bool AddReturnOrigin (UsageVector vector, ExitStatement exit_stmt)
-               {
-                       if (finally_vector != null) {
-                               int errors = Report.Errors;
-                               Parent.AddReturnOrigin (vector, exit_stmt);
-                               if (errors == Report.Errors)
-                                       exit_stmt.Error_FinallyClause (Report);
-                       } else {
-                               saved_origins = new ReturnOrigin (saved_origins, vector, exit_stmt);
-                       }
-
-                       // sets ec.NeedReturnLabel()
-                       stmt.SomeCodeFollows ();
-                       return true;
-               }
-
-               public override bool AddGotoOrigin (UsageVector vector, Goto goto_stmt)
-               {
-                       LabeledStatement s = current_vector.Block == null ? null : current_vector.Block.LookupLabel (goto_stmt.Target);
-                       if (s != null)
-                               throw new InternalErrorException ("Shouldn't get here");
-
-                       if (finally_vector != null) {
-                               int errors = Report.Errors;
-                               Parent.AddGotoOrigin (vector, goto_stmt);
-                               if (errors == Report.Errors)
-                                       Report.Error (157, goto_stmt.loc, "Control cannot leave the body of a finally clause");
-                       } else {
-                               saved_origins = new GotoOrigin (saved_origins, vector, goto_stmt);
-                       }
-                       return true;
-               }
-
-               protected override UsageVector Merge ()
-               {
-                       UsageVector vector = try_vector.Clone ();
-
-                       if (finally_vector != null)
-                               vector.MergeChild (finally_vector, false);
-
-                       for (SavedOrigin origin = saved_origins; origin != null; origin = origin.Next)
-                               origin.PropagateFinally (finally_vector, Parent);
-
-                       return vector;
-               }
-       }
-
        // <summary>
        //   This is used by the flow analysis code to keep track of the type of local variables.
        //
@@ -1178,23 +129,22 @@ namespace Mono.CSharp
                //   A struct's constructor must always assign all fields.
                //   This method checks whether it actually does so.
                // </summary>
-               public bool IsFullyInitialized (BlockContext ec, VariableInfo vi, Location loc)
+               public bool IsFullyInitialized (FlowAnalysisContext fc, VariableInfo vi, Location loc)
                {
                        if (struct_info == null)
                                return true;
 
                        bool ok = true;
-                       FlowBranching branching = ec.CurrentBranching;
                        for (int i = 0; i < struct_info.Count; i++) {
-                               var field = struct_info.Fields [i];
+                               var field = struct_info.Fields[i];
 
-                               if (!branching.IsStructFieldAssigned (vi, field.Name)) {
+                               if (!fc.IsStructFieldDefinitelyAssigned (vi, field.Name)) {
                                        if (field.MemberDefinition is Property.BackingField) {
-                                               ec.Report.Error (843, loc,
+                                               fc.Report.Error (843, loc,
                                                        "An automatically implemented property `{0}' must be fully assigned before control leaves the constructor. Consider calling the default struct contructor from a constructor initializer",
                                                        field.GetSignatureForError ());
                                        } else {
-                                               ec.Report.Error (171, loc,
+                                               fc.Report.Error (171, loc,
                                                        "Field `{0}' must be fully assigned before control leaves the constructor",
                                                        field.GetSignatureForError ());
                                        }
@@ -1401,12 +351,7 @@ namespace Mono.CSharp
                        return info;
                }
 
-               public bool IsAssigned (ResolveContext ec)
-               {
-                       return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (this);
-               }
-
-               public bool IsAssigned (MyBitVector vector)
+               public bool IsAssigned (DefiniteAssignmentBitSet vector)
                {
                        if (vector == null)
                                return true;
@@ -1445,23 +390,18 @@ namespace Mono.CSharp
                                        return false;
                        }
                        
-                       vector [Offset] = true;
+                       vector.Set (Offset);
                        return true;
                }
 
                public bool IsEverAssigned { get; set; }
 
-               public bool IsStructFieldAssigned (ResolveContext ec, string name)
+               public bool IsFullyInitialized (FlowAnalysisContext fc, Location loc)
                {
-                       return !ec.DoFlowAnalysis || ec.CurrentBranching.IsStructFieldAssigned (this, name);
+                       return TypeInfo.IsFullyInitialized (fc, this, loc);
                }
 
-               public bool IsFullyInitialized (BlockContext bc, Location loc)
-               {
-                       return TypeInfo.IsFullyInitialized (bc, this, loc);
-               }
-
-               public bool IsStructFieldAssigned (MyBitVector vector, string field_name)
+               public bool IsStructFieldAssigned (DefiniteAssignmentBitSet vector, string field_name)
                {
                        int field_idx = TypeInfo.GetFieldIndex (field_name);
 
@@ -1471,31 +411,20 @@ namespace Mono.CSharp
                        return vector [Offset + field_idx];
                }
 
-               public void SetStructFieldAssigned (ResolveContext ec, string name)
-               {
-                       if (ec.DoFlowAnalysis)
-                               ec.CurrentBranching.SetFieldAssigned (this, name);
-               }
-
-               public void SetAssigned (ResolveContext ec)
-               {
-                       if (ec.DoFlowAnalysis)
-                               ec.CurrentBranching.SetAssigned (this);
-               }
-
-               public void SetAssigned (MyBitVector vector)
+               public void SetAssigned (DefiniteAssignmentBitSet vector, bool generatedAssignment)
                {
                        if (Length == 1)
-                               vector[Offset] = true;
+                               vector.Set (Offset);
                        else
-                               vector.SetRange (Offset, Length);
+                               vector.Set (Offset, Length);
 
-                       IsEverAssigned = true;
+                       if (!generatedAssignment)
+                               IsEverAssigned = true;
                }
 
-               public void SetStructFieldAssigned (MyBitVector vector, string field_name)
+               public void SetStructFieldAssigned (DefiniteAssignmentBitSet vector, string field_name)
                {
-                       if (vector[Offset])
+                       if (vector [Offset])
                                return;
 
                        int field_idx = TypeInfo.GetFieldIndex (field_name);
@@ -1505,15 +434,15 @@ namespace Mono.CSharp
 
                        var complex_field = TypeInfo.GetStructField (field_name);
                        if (complex_field != null) {
-                               vector.SetRange (Offset + complex_field.Offset, complex_field.TotalLength);
+                               vector.Set (Offset + complex_field.Offset, complex_field.TotalLength);
                        } else {
-                               vector[Offset + field_idx] = true;
+                               vector.Set (Offset + field_idx);
                        }
 
                        IsEverAssigned = true;
 
                        //
-                       // Each field must be assigned
+                       // Each field must be assigned before setting master bit
                        //
                        for (int i = Offset + 1; i < TypeInfo.TotalLength + Offset; i++) {
                                if (!vector[i])
@@ -1524,7 +453,7 @@ namespace Mono.CSharp
                        // Set master struct flag to assigned when all tested struct
                        // fields have been assigned
                        //
-                       vector[Offset] = true;
+                       vector.Set (Offset);
                }
 
                public VariableInfo GetStructFieldInfo (string fieldName)
@@ -1539,274 +468,211 @@ namespace Mono.CSharp
 
                public override string ToString ()
                {
-                       return String.Format ("VariableInfo ({0}:{1}:{2}:{3}:{4})",
-                                             Name, TypeInfo, Offset, Length, IsParameter);
+                       return String.Format ("Name={0} Offset={1} Length={2} {3})", Name, Offset, Length, TypeInfo);
                }
        }
 
-       // <summary>
-       //   This is a special bit vector which can inherit from another bit vector doing a
-       //   copy-on-write strategy.  The inherited vector may have a smaller size than the
-       //   current one.
-       // </summary>
-       public class MyBitVector {
-               public readonly int Count;
-               public static readonly MyBitVector Empty = new MyBitVector ();
-
-               // Invariant: vector != null => vector.Count == Count
-               // Invariant: vector == null || shared == null
-               //            i.e., at most one of 'vector' and 'shared' can be non-null.  They can both be null -- that means all-ones
-               // The object in 'shared' cannot be modified, while 'vector' can be freely modified
-               System.Collections.BitArray vector, shared;
+       public struct Reachability
+       {
+               readonly bool unreachable;
 
-               MyBitVector ()
+               Reachability (bool unreachable)
                {
-                       shared = new System.Collections.BitArray (0, false);
+                       this.unreachable = unreachable;
+               }
+
+               public bool IsUnreachable {
+                       get {
+                               return unreachable;
+                       }
                }
 
-               public MyBitVector (MyBitVector InheritsFrom, int Count)
+               public static Reachability CreateUnreachable ()
                {
-                       if (InheritsFrom != null)
-                               shared = InheritsFrom.MakeShared (Count);
+                       return new Reachability (true);
+               }
 
-                       this.Count = Count;
+               public static Reachability operator & (Reachability a, Reachability b)
+               {
+                   return new Reachability (a.unreachable && b.unreachable);
                }
 
-               System.Collections.BitArray MakeShared (int new_count)
+               public static Reachability operator | (Reachability a, Reachability b)
                {
-                       // Post-condition: vector == null
+                       return new Reachability (a.unreachable | b.unreachable);
+               }
+       }
 
-                       // ensure we don't leak out dirty bits from the BitVector we inherited from
-                       if (new_count > Count &&
-                           ((shared != null && shared.Count > Count) ||
-                            (shared == null && vector == null)))
-                               initialize_vector ();
+       //
+       // Special version of bit array. Many operations can be simplified because
+       // we are always dealing with arrays of same sizes
+       //
+       public class DefiniteAssignmentBitSet
+       {
+               const uint copy_on_write_flag = 1u << 31;
 
-                       if (vector != null) {
-                               shared = vector;
-                               vector = null;
-                       }
+               uint bits;
 
-                       return shared;
-               }
+               // Used when bits overflows
+               int[] large_bits;
 
-               // <summary>
-               //   Get/set bit `index' in the bit vector.
-               // </summary>
-               public bool this [int index] {
-                       get {
-                               if (index >= Count)
-                                       // FIXME: Disabled due to missing anonymous method flow analysis
-                                       // throw new ArgumentOutOfRangeException ();
-                                       return true; 
-
-                               if (vector != null)
-                                       return vector [index];
-                               if (shared == null)
-                                       return true;
-                               if (index < shared.Count)
-                                       return shared [index];
-                               return false;
-                       }
+               public static readonly DefiniteAssignmentBitSet Empty = new DefiniteAssignmentBitSet (0);
 
-                       set {
-                               // Only copy the vector if we're actually modifying it.
-                               if (this [index] != value) {
-                                       if (vector == null)
-                                               initialize_vector ();
-                                       vector [index] = value;
-                               }
-                       }
+               public DefiniteAssignmentBitSet (int length)
+               {
+                       if (length > 31)
+                               large_bits = new int[(length + 31) / 32];
                }
 
-               // <summary>
-               //   Performs an `or' operation on the bit vector.  The `new_vector' may have a
-               //   different size than the current one.
-               // </summary>
-               private MyBitVector Or (MyBitVector new_vector)
+               public DefiniteAssignmentBitSet (DefiniteAssignmentBitSet source)
                {
-                       if (Count == 0 || new_vector.Count == 0)
-                               return this;
-
-                       var o = new_vector.vector != null ? new_vector.vector : new_vector.shared;
-
-                       if (o == null) {
-                               int n = new_vector.Count;
-                               if (n < Count) {
-                                       for (int i = 0; i < n; ++i)
-                                               this [i] = true;
-                               } else {
-                                       SetAll (true);
-                               }
-                               return this;
+                       if (source.large_bits != null) {
+                               large_bits = source.large_bits;
+                               bits = source.bits | copy_on_write_flag;
+                       } else {
+                               bits = source.bits & ~copy_on_write_flag;
                        }
+               }
 
-                       if (Count == o.Count) {
-                               if (vector == null) {
-                                       if (shared == null)
-                                               return this;
-                                       initialize_vector ();
-                               }
-                               vector.Or (o);
-                               return this;
-                       }
+               public static DefiniteAssignmentBitSet operator & (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
+               {
+                       if (AreEqual (a, b))
+                               return a;
 
-                       int min = o.Count;
-                       if (Count < min)
-                               min = Count;
+                       DefiniteAssignmentBitSet res;
+                       if (a.large_bits == null) {
+                               res = new DefiniteAssignmentBitSet (a);
+                               res.bits &= (b.bits & ~copy_on_write_flag);
+                               return res;
+                       }
 
-                       for (int i = 0; i < min; i++) {
-                               if (o [i])
-                                       this [i] = true;
+                       res = new DefiniteAssignmentBitSet (a);
+                       res.Clone ();
+                       var dest = res.large_bits;
+                       var src = b.large_bits;
+                       for (int i = 0; i < dest.Length; ++i) {
+                               dest[i] &= src[i];
                        }
 
-                       return this;
+                       return res;
                }
 
-               // <summary>
-               //   Performs an `and' operation on the bit vector.  The `new_vector' may have
-               //   a different size than the current one.
-               // </summary>
-               private MyBitVector And (MyBitVector new_vector)
+               public static DefiniteAssignmentBitSet operator | (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
                {
-                       if (Count == 0)
-                               return this;
-
-                       var o = new_vector.vector != null ? new_vector.vector : new_vector.shared;
+                       if (AreEqual (a, b))
+                               return a;
 
-                       if (o == null) {
-                               for (int i = new_vector.Count; i < Count; ++i)
-                                       this [i] = false;
-                               return this;
+                       DefiniteAssignmentBitSet res;
+                       if (a.large_bits == null) {
+                               res = new DefiniteAssignmentBitSet (a);
+                               res.bits |= b.bits;
+                               res.bits &= ~copy_on_write_flag;
+                               return res;
                        }
 
-                       if (o.Count == 0) {
-                               SetAll (false);
-                               return this;
-                       }
+                       res = new DefiniteAssignmentBitSet (a);
+                       res.Clone ();
+                       var dest = res.large_bits;
+                       var src = b.large_bits;
 
-                       if (Count == o.Count) {
-                               if (vector == null) {
-                                       if (shared == null) {
-                                               shared = new_vector.MakeShared (Count);
-                                               return this;
-                                       }
-                                       initialize_vector ();
-                               }
-                               vector.And (o);
-                               return this;
+                       for (int i = 0; i < dest.Length; ++i) {
+                               dest[i] |= src[i];
                        }
 
-                       int min = o.Count;
-                       if (Count < min)
-                               min = Count;
+                       return res;
+               }
 
-                       for (int i = 0; i < min; i++) {
-                               if (! o [i])
-                                       this [i] = false;
-                       }
+               public static DefiniteAssignmentBitSet And (List<DefiniteAssignmentBitSet> das)
+               {
+                       if (das.Count == 0)
+                               throw new ArgumentException ("Empty das");
 
-                       for (int i = min; i < Count; i++)
-                               this [i] = false;
+                       DefiniteAssignmentBitSet res = das[0];
+                       for (int i = 1; i < das.Count; ++i) {
+                               res &= das[i];
+                       }
 
-                       return this;
+                       return res;
                }
 
-               public static MyBitVector operator & (MyBitVector a, MyBitVector b)
-               {
-                       if (a == b)
-                               return a;
-                       if (a == null)
-                               return b.Clone ();
-                       if (b == null)
-                               return a.Clone ();
-                       if (a.Count > b.Count)
-                               return a.Clone ().And (b);
-                       else
-                               return b.Clone ().And (a);                                      
+               bool CopyOnWrite {
+                       get {
+                               return (bits & copy_on_write_flag) != 0;
+                       }
                }
 
-               public static MyBitVector operator | (MyBitVector a, MyBitVector b)
-               {
-                       if (a == b)
-                               return a;
-                       if (a == null)
-                               return new MyBitVector (null, b.Count);
-                       if (b == null)
-                               return new MyBitVector (null, a.Count);
-                       if (a.Count > b.Count)
-                               return a.Clone ().Or (b);
-                       else
-                               return b.Clone ().Or (a);
+               int Length {
+                       get {
+                               return large_bits == null ? 31 : large_bits.Length * 32;
+                       }
                }
 
-               public MyBitVector Clone ()
+               public void Set (int index)
                {
-                       return Count == 0 ? Empty : new MyBitVector (this, Count);
+                       if (CopyOnWrite && !this[index])
+                               Clone ();
+
+                       SetBit (index);
                }
 
-               public void SetRange (int offset, int length)
+               public void Set (int index, int length)
                {
-                       if (offset > Count || offset + length > Count)
-                               throw new ArgumentOutOfRangeException ("flow-analysis");
-
-                       if (shared == null && vector == null)
-                               return;
+                       for (int i = 0; i < length; ++i) {
+                               if (CopyOnWrite && !this[index + i])
+                                       Clone ();
 
-                       int i = 0;
-                       if (shared != null) {
-                               if (offset + length <= shared.Count) {
-                                       for (; i < length; ++i)
-                                               if (!shared [i+offset])
-                                                   break;
-                                       if (i == length)
-                                               return;
-                               }
-                               initialize_vector ();
+                               SetBit (index + i);
                        }
-                       for (; i < length; ++i)
-                               vector [i+offset] = true;
+               }
 
+               public bool this[int index] {
+                       get {
+                               return GetBit (index);
+                       }
                }
 
-               public void SetAll (bool value)
+               public override string ToString ()
                {
-                       // Don't clobber Empty
-                       if (Count == 0)
-                               return;
-                       shared = value ? null : Empty.MakeShared (Count);
-                       vector = null;
+                       var length = Length;
+                       StringBuilder sb = new StringBuilder (length);
+                       for (int i = 0; i < length; ++i) {
+                               sb.Append (this[i] ? '1' : '0');
+                       }
+
+                       return sb.ToString ();
                }
 
-               void initialize_vector ()
+               void Clone ()
                {
-                       // Post-condition: vector != null
-                       if (shared == null) {
-                               vector = new System.Collections.BitArray (Count, true);
-                               return;
-                       }
+                       large_bits = (int[]) large_bits.Clone ();
+               }
 
-                       vector = new System.Collections.BitArray (shared);
-                       if (Count != vector.Count)
-                               vector.Length = Count;
-                       shared = null;
+               bool GetBit (int index)
+               {
+                       return large_bits == null ?
+                               (bits & (1 << index)) != 0 :
+                               (large_bits[index >> 5] & (1 << (index & 31))) != 0;
                }
 
-               StringBuilder Dump (StringBuilder sb)
+               void SetBit (int index)
                {
-                       var dump = vector == null ? shared : vector;
-                       if (dump == null)
-                               return sb.Append ("/");
-                       if (dump == shared)
-                               sb.Append ("=");
-                       for (int i = 0; i < dump.Count; i++)
-                               sb.Append (dump [i] ? "1" : "0");
-                       return sb;
+                       if (large_bits == null)
+                               bits = (uint) ((int) bits | (1 << index));
+                       else
+                               large_bits[index >> 5] |= (1 << (index & 31));
                }
 
-               public override string ToString ()
+               static bool AreEqual (DefiniteAssignmentBitSet a, DefiniteAssignmentBitSet b)
                {
-                       return Dump (new StringBuilder ("{")).Append ("}").ToString ();
+                       if (a.large_bits == null)
+                               return (a.bits & ~copy_on_write_flag) == (b.bits & ~copy_on_write_flag);
+
+                       for (int i = 0; i < a.large_bits.Length; ++i) {
+                               if (a.large_bits[i] != b.large_bits[i])
+                                       return false;
+                       }
+
+                       return true;
                }
        }
 }
index 5a24c6898b5f8d0744eef1d11519e4320171d818..e14578dfe39ac23d37b4d32d38673c55ec9aaa5f 100644 (file)
@@ -486,6 +486,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                public string Name {
                        get {
                                return MemberName.Name;
@@ -2906,7 +2912,6 @@ namespace Mono.CSharp {
                readonly TypeSpec[] tp_args;
                readonly TypeSpec[] fixed_types;
                readonly List<BoundInfo>[] bounds;
-               bool failed;
 
                // TODO MemberCache: Could it be TypeParameterSpec[] ??
                public TypeInferenceContext (TypeSpec[] typeArguments)
@@ -3125,9 +3130,6 @@ namespace Mono.CSharp {
                        if (fixed_types[i] != null)
                                throw new InternalErrorException ("Type argument has been already fixed");
 
-                       if (failed)
-                               return false;
-
                        var candidates = bounds [i];
                        if (candidates == null)
                                return false;
@@ -3451,10 +3453,9 @@ namespace Mono.CSharp {
                                                }
 
                                                //
-                                               // This should always cause type inference failure
+                                               // Break when candidate arguments are ambiguous
                                                //
-                                               failed = true;
-                                               return 1;
+                                               return 0;
                                        }
 
                                        //
index 3204ed11a085b849c962ef4b2cc31b8c75b322dc..1a74b3148e5014df63adc4a1c3f7154b086352e2 100644 (file)
@@ -124,6 +124,9 @@ namespace Mono.CSharp
                        Namespace ns = targetNamespace;
                        string prev_namespace = null;
                        foreach (var t in types) {
+                               if (!t.__IsTypeForwarder)
+                                       continue;
+
                                // IsMissing tells us the type has been forwarded and target assembly is missing 
                                if (!t.__IsMissing)
                                        continue;
index 72538a2da18ecf16cded87dfe6ee278b9feffbfa..125404f6d920693b7289b968bde5a15fae1ff9c1 100644 (file)
@@ -1798,6 +1798,16 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+#if STATIC
+                               return ((MetaType) provider).__IsCyclicTypeForwarder;
+#else
+                               return false;
+#endif
+                       }
+               }
+
                public override string Name {
                        get {
                                if (name == null) {
@@ -1919,20 +1929,24 @@ namespace Mono.CSharp
                                if (caller.Kind != MemberKind.MissingType)
                                        report.SymbolRelatedToPreviousError (caller);
 
-                               if (t.MemberDefinition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
+                               var definition = t.MemberDefinition;
+                               if (definition.DeclaringAssembly == ctx.Module.DeclaringAssembly) {
                                        report.Error (1683, loc,
                                                "Reference to type `{0}' claims it is defined in this assembly, but it is not defined in source or any added modules",
                                                name);
-                               } else if (t.MemberDefinition.DeclaringAssembly.IsMissing) {
-                                       if (t.MemberDefinition.IsTypeForwarder) {
+                               } else if (definition.DeclaringAssembly.IsMissing) {
+                                       if (definition.IsTypeForwarder) {
                                                report.Error (1070, loc,
                                                        "The type `{0}' has been forwarded to an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
-                                                       name, t.MemberDefinition.DeclaringAssembly.FullName);
+                                                       name, definition.DeclaringAssembly.FullName);
                                        } else {
                                                report.Error (12, loc,
                                                        "The type `{0}' is defined in an assembly that is not referenced. Consider adding a reference to assembly `{1}'",
-                                                       name, t.MemberDefinition.DeclaringAssembly.FullName);
+                                                       name, definition.DeclaringAssembly.FullName);
                                        }
+                               } else if (definition.IsTypeForwarder) {
+                                       report.Error (731, loc, "The type forwarder for type `{0}' in assembly `{1}' has circular dependency",
+                                               name, definition.DeclaringAssembly.FullName);
                                } else {
                                        report.Error (1684, loc,
                                                "Reference to type `{0}' claims it is defined assembly `{1}', but it could not be found",
@@ -2231,6 +2245,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                public string Namespace {
                        get {
                                return null;
index 82ded9174c551a96a680ea7c2495cc9e9087b52c..0d3c19af9a7de9d59a3a7280ef022ff61b73d8f8 100644 (file)
@@ -29,6 +29,7 @@ namespace Mono.CSharp
                protected bool unwind_protect;
                protected T machine_initializer;
                int resume_pc;
+               ExceptionStatement inside_try_block;
 
                protected YieldStatement (Expression expr, Location l)
                {
@@ -51,6 +52,15 @@ namespace Mono.CSharp
                        machine_initializer.InjectYield (ec, expr, resume_pc, unwind_protect, resume_point);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+
+                       RegisterResumePoint ();
+
+                       return false;
+               }
+
                public override bool Resolve (BlockContext bc)
                {
                        expr = expr.Resolve (bc);
@@ -58,12 +68,20 @@ namespace Mono.CSharp
                                return false;
 
                        machine_initializer = bc.CurrentAnonymousMethod as T;
-
-                       if (!bc.CurrentBranching.CurrentUsageVector.IsUnreachable)
-                               unwind_protect = bc.CurrentBranching.AddResumePoint (this, this, out resume_pc);
-
+                       inside_try_block = bc.CurrentTryBlock;
                        return true;
                }
+
+               public void RegisterResumePoint ()
+               {
+                       if (inside_try_block == null) {
+                               resume_pc = machine_initializer.AddResumePoint (this);
+                       } else {
+                               resume_pc = inside_try_block.AddResumePoint (this, resume_pc, machine_initializer);
+                               unwind_protect = true;
+                               inside_try_block = null;
+                       }
+               }
        }
 
        public class Yield : YieldStatement<Iterator>
@@ -73,14 +91,19 @@ namespace Mono.CSharp
                {
                }
 
-               public static bool CheckContext (ResolveContext ec, Location loc)
+               public static bool CheckContext (BlockContext bc, Location loc)
                {
-                       if (!ec.CurrentAnonymousMethod.IsIterator) {
-                               ec.Report.Error (1621, loc,
+                       if (!bc.CurrentAnonymousMethod.IsIterator) {
+                               bc.Report.Error (1621, loc,
                                        "The yield statement cannot be used inside anonymous method blocks");
                                return false;
                        }
 
+                       if (bc.HasSet (ResolveContext.Options.FinallyScope)) {
+                               bc.Report.Error (1625, loc, "Cannot yield in the body of a finally clause");
+                               return false;
+                       }
+
                        return true;
                }
 
@@ -89,6 +112,14 @@ namespace Mono.CSharp
                        if (!CheckContext (bc, loc))
                                return false;
 
+                       if (bc.HasAny (ResolveContext.Options.TryWithCatchScope)) {
+                               bc.Report.Error (1626, loc, "Cannot yield a value in the body of a try block with a catch clause");
+                       }
+
+                       if (bc.HasSet (ResolveContext.Options.CatchScope)) {
+                               bc.Report.Error (1631, loc, "Cannot yield a value in the body of a catch clause");
+                       }
+
                        if (!base.Resolve (bc))
                                return false;
 
@@ -117,9 +148,10 @@ namespace Mono.CSharp
                        loc = l;
                }
 
-               public override void Error_FinallyClause (Report Report)
-               {
-                       Report.Error (1625, loc, "Cannot yield in the body of a finally clause");
+               protected override bool IsLocalExit {
+                       get {
+                               return false;
+                       }
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement target)
@@ -127,16 +159,27 @@ namespace Mono.CSharp
                        throw new NotSupportedException ();
                }
 
-               protected override bool DoResolve (BlockContext ec)
+               protected override bool DoResolve (BlockContext bc)
                {
-                       iterator = ec.CurrentIterator;
-                       return Yield.CheckContext (ec, loc);
+                       iterator = bc.CurrentIterator;
+                       return Yield.CheckContext (bc, loc);
                }
 
                protected override void DoEmit (EmitContext ec)
                {
                        iterator.EmitYieldBreak (ec, unwind_protect);
                }
+
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return true;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Reachability.CreateUnreachable ();
+               }
                
                public override object Accept (StructuralVisitor visitor)
                {
@@ -265,7 +308,6 @@ namespace Mono.CSharp
                                        if (new_storey != null)
                                                new_storey = Convert.ImplicitConversionRequired (ec, new_storey, host_method.MemberType, loc);
 
-                                       ec.CurrentBranching.CurrentUsageVector.Goto ();
                                        return true;
                                }
 
@@ -293,10 +335,21 @@ namespace Mono.CSharp
                                        new_storey.Emit (ec);
                                        ec.Emit (OpCodes.Ret);
                                }
+
+                               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                               {
+                                       throw new NotImplementedException ();
+                               }
+
+                               public override Reachability MarkReachable (Reachability rc)
+                               {
+                                       base.MarkReachable (rc);
+                                       return Reachability.CreateUnreachable ();
+                               }
                        }
 
                        GetEnumeratorMethod (IteratorStorey host, FullNamedExpression returnType, MemberName name)
-                               : base (host, null, returnType, Modifiers.DEBUGGER_HIDDEN, name)
+                               : base (host, null, returnType, Modifiers.DEBUGGER_HIDDEN, name, ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis)
                        {
                        }
 
@@ -310,7 +363,6 @@ namespace Mono.CSharp
                                var m = new GetEnumeratorMethod (host, returnType, name);
                                var stmt = statement ?? new GetEnumeratorStatement (host, m);
                                m.block.AddStatement (stmt);
-                               m.block.IsCompilerGenerated = true;
                                return m;
                        }
                }
@@ -342,16 +394,20 @@ namespace Mono.CSharp
                                        ec.CurrentAnonymousMethod = iterator;
                                        iterator.EmitDispose (ec);
                                }
+
+                               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                               {
+                                       throw new NotImplementedException ();
+                               }
                        }
 
                        public DisposeMethod (IteratorStorey host)
                                : base (host, null, new TypeExpression (host.Compiler.BuiltinTypes.Void, host.Location), Modifiers.PUBLIC | Modifiers.DEBUGGER_HIDDEN,
-                                       new MemberName ("Dispose", host.Location))
+                                       new MemberName ("Dispose", host.Location), ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis)
                        {
                                host.Members.Add (this);
 
                                Block.AddStatement (new DisposeMethodStatement (host.Iterator));
-                               Block.IsCompilerGenerated = true;
                        }
                }
 
@@ -546,9 +602,8 @@ namespace Mono.CSharp
 
                        var name = new MemberName ("Current", null, explicit_iface, Location);
 
-                       ToplevelBlock get_block = new ToplevelBlock (Compiler, Location) {
-                               IsCompilerGenerated = true
-                       };
+                       ToplevelBlock get_block = new ToplevelBlock (Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location,
+                               Block.Flags.CompilerGenerated | Block.Flags.NoFlowAnalysis);
                        get_block.AddStatement (new Return (new DynamicFieldExpr (CurrentField, Location), Location));
                                
                        Property current = new Property (this, type, Modifiers.DEBUGGER_HIDDEN | Modifiers.COMPILER_GENERATED, name, null);
@@ -567,9 +622,8 @@ namespace Mono.CSharp
                                ParametersCompiled.EmptyReadOnlyParameters, null);
                        Members.Add (reset);
 
-                       reset.Block = new ToplevelBlock (Compiler, Location) {
-                               IsCompilerGenerated = true
-                       };
+                       reset.Block = new ToplevelBlock (Compiler, reset.ParameterInfo, Location,
+                               Block.Flags.CompilerGenerated | Block.Flags.NoFlowAnalysis);
 
                        TypeSpec ex_type = Module.PredefinedTypes.NotSupportedException.Resolve ();
                        if (ex_type == null)
@@ -590,12 +644,13 @@ namespace Mono.CSharp
        {
                readonly StateMachineInitializer expr;
 
-               public StateMachineMethod (StateMachine host, StateMachineInitializer expr, FullNamedExpression returnType, Modifiers mod, MemberName name)
+               public StateMachineMethod (StateMachine host, StateMachineInitializer expr, FullNamedExpression returnType,
+                       Modifiers mod, MemberName name, ToplevelBlock.Flags blockFlags)
                        : base (host, returnType, mod | Modifiers.COMPILER_GENERATED,
                          name, ParametersCompiled.EmptyReadOnlyParameters, null)
                {
                        this.expr = expr;
-                       Block = new ToplevelBlock (host.Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null);
+                       Block = new ToplevelBlock (host.Compiler, ParametersCompiled.EmptyReadOnlyParameters, Location.Null, blockFlags);
                }
 
                public override EmitContext CreateEmitContext (ILGenerator ig, SourceMethodBuilder sourceMethod)
@@ -642,6 +697,21 @@ namespace Mono.CSharp
                                // Don't create sequence point
                                DoEmit (ec);
                        }
+
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               return state_machine.ReturnType.Kind != MemberKind.Void;
+                       }
+
+                       public override Reachability MarkReachable (Reachability rc)
+                       {
+                               base.MarkReachable (rc);
+
+                               if (state_machine.ReturnType.Kind != MemberKind.Void)
+                                       rc = Reachability.CreateUnreachable ();
+
+                               return rc;
+                       }
                }
 
                public readonly TypeDefinition Host;
@@ -706,34 +776,33 @@ namespace Mono.CSharp
                        throw new NotSupportedException ("ET");
                }
 
-               protected virtual BlockContext CreateBlockContext (ResolveContext rc)
+               protected virtual BlockContext CreateBlockContext (BlockContext bc)
                {
-                       var ctx = new BlockContext (rc, block, ((BlockContext) rc).ReturnType);
+                       var ctx = new BlockContext (bc, block, bc.ReturnType);
                        ctx.CurrentAnonymousMethod = this;
+
+                       ctx.AssignmentInfoOffset = bc.AssignmentInfoOffset;
+                       ctx.EnclosingLoop = bc.EnclosingLoop;
+                       ctx.EnclosingLoopOrSwitch = bc.EnclosingLoopOrSwitch;
+                       ctx.Switch = bc.Switch;
+
                        return ctx;
                }
 
-               protected override Expression DoResolve (ResolveContext ec)
+               protected override Expression DoResolve (ResolveContext rc)
                {
-                       var ctx = CreateBlockContext (ec);
+                       var bc = (BlockContext) rc;
+                       var ctx = CreateBlockContext (bc);
 
                        Block.Resolve (ctx);
 
-                       //
-                       // Explicit return is required for Task<T> state machine
-                       //
-                       var task_storey = storey as AsyncTaskStorey;
-                       if (task_storey == null || (task_storey.ReturnType != null && !task_storey.ReturnType.IsGenericTask))
-                               ctx.CurrentBranching.CurrentUsageVector.Goto ();
-
-                       ctx.EndFlowBranching ();
-
-                       if (!ec.IsInProbingMode) {
-                               var move_next = new StateMachineMethod (storey, this, new TypeExpression (ReturnType, loc), Modifiers.PUBLIC, new MemberName ("MoveNext", loc));
+                       if (!rc.IsInProbingMode) {
+                               var move_next = new StateMachineMethod (storey, this, new TypeExpression (ReturnType, loc), Modifiers.PUBLIC, new MemberName ("MoveNext", loc), 0);
                                move_next.Block.AddStatement (new MoveNextBodyStatement (this));
                                storey.AddEntryMethod (move_next);
                        }
 
+                       bc.AssignmentInfoOffset = ctx.AssignmentInfoOffset;
                        eclass = ExprClass.Value;
                        return this;
                }
@@ -936,6 +1005,11 @@ namespace Mono.CSharp
                                throw new NotSupportedException ();
                        }
 
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               throw new NotSupportedException ();
+                       }
+
                        protected override void DoEmit (EmitContext ec)
                        {
                                //
@@ -985,8 +1059,8 @@ namespace Mono.CSharp
                                Modifiers.COMPILER_GENERATED, new MemberName (CompilerGeneratedContainer.MakeName (null, null, "Finally", finally_hosts_counter++), loc),
                                ParametersCompiled.EmptyReadOnlyParameters, null);
 
-                       method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc);
-                       method.Block.IsCompilerGenerated = true;
+                       method.Block = new ToplevelBlock (method.Compiler, method.ParameterInfo, loc,
+                               ToplevelBlock.Flags.CompilerGenerated | ToplevelBlock.Flags.NoFlowAnalysis);
                        method.Block.AddStatement (new TryFinallyBlockProxyStatement (this, block));
 
                        // Cannot it add to storey because it'd be emitted before nested
@@ -1097,13 +1171,6 @@ namespace Mono.CSharp
                        ec.MarkLabel (resume_point);
                }
 
-               protected override BlockContext CreateBlockContext (ResolveContext rc)
-               {
-                       var bc = base.CreateBlockContext (rc);
-                       bc.StartFlowBranching (this, rc.CurrentBranching);
-                       return bc;
-               }
-
                public static void CreateIterator (IMethodData method, TypeDefinition parent, Modifiers modifiers)
                {
                        bool is_enumerable;
index a1c5ab2f914f4bed7b7938ca2f1f93a4463c3d35..da339fa873deb3bbf4daf7ed4dadc7973a52d31a 100644 (file)
@@ -811,9 +811,8 @@ namespace Mono.CSharp.Linq
                }
 
                public QueryBlock (Block parent, Location start)
-                       : base (parent, ParametersCompiled.EmptyReadOnlyParameters, start)
+                       : base (parent, ParametersCompiled.EmptyReadOnlyParameters, start, Flags.CompilerGenerated)
                {
-                       flags |= Flags.CompilerGenerated;
                }
 
                public void AddRangeVariable (RangeVariable variable)
index 03568fa9230613951753346426259123f20e93b0..8a1e28d441fb1c6b4fcf5e6474b5ee88f5e84b98 100644 (file)
@@ -205,6 +205,8 @@ namespace Mono.CSharp {
                TypeSpec[] targs;
                TypeParameterSpec[] constraints;
 
+               public static readonly MethodSpec Excluded = new MethodSpec (MemberKind.Method, InternalType.FakeInternalType, null, null, ParametersCompiled.EmptyReadOnlyParameters, 0);
+
                public MethodSpec (MemberKind kind, TypeSpec declaringType, IMethodDefinition details, TypeSpec returnType,
                        AParametersCollection parameters, Modifiers modifiers)
                        : base (kind, declaringType, details, modifiers)
@@ -1464,7 +1466,7 @@ namespace Mono.CSharp {
                                } else {
                                        //
                                        // It is legal to have "this" initializers that take no arguments
-                                       // in structs, they are just no-ops.
+                                       // in structs
                                        //
                                        // struct D { public D (int a) : this () {}
                                        //
@@ -1485,9 +1487,17 @@ namespace Mono.CSharp {
 
                public override void Emit (EmitContext ec)
                {
-                       // It can be null for static initializers
-                       if (base_ctor == null)
+                       //
+                       // It can be null for struct initializers or System.Object
+                       //
+                       if (base_ctor == null) {
+                               if (type == ec.BuiltinTypes.Object)
+                                       return;
+
+                               ec.Emit (OpCodes.Ldarg_0);
+                               ec.Emit (OpCodes.Initobj, type);
                                return;
+                       }
                        
                        var call = new CallEmitter ();
                        call.InstanceExpression = new CompilerGeneratedThis (type, loc); 
@@ -1498,6 +1508,12 @@ namespace Mono.CSharp {
                {
                        Emit (ec);
                }
+
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (argument_list != null)
+                               argument_list.FlowAnalysis (fc);
+               }
        }
 
        public class ConstructorBaseInitializer : ConstructorInitializer {
@@ -1742,7 +1758,7 @@ namespace Mono.CSharp {
                                        }
                                }
 
-                               if (block.Resolve (null, bc, this)) {
+                               if (block.Resolve (bc, this)) {
                                        debug_builder = Parent.CreateMethodSymbolEntry ();
                                        EmitContext ec = new EmitContext (this, ConstructorBuilder.GetILGenerator (), bc.ReturnType, debug_builder);
                                        ec.With (EmitContext.Options.ConstructorScope, true);
@@ -2131,7 +2147,7 @@ namespace Mono.CSharp {
                        ToplevelBlock block = method.Block;
                        if (block != null) {
                                BlockContext bc = new BlockContext (method, block, method.ReturnType);
-                               if (block.Resolve (null, bc, method)) {
+                               if (block.Resolve (bc, method)) {
                                        debug_builder = member.Parent.CreateMethodSymbolEntry ();
                                        EmitContext ec = method.CreateEmitContext (MethodBuilder.GetILGenerator (), debug_builder);
 
index 6a6f17e8e9d7ceee288929f262704b4b5ad924f6..26db3a4d93d1aab7fb88e2b0d39e353304ff6377 100644 (file)
@@ -353,11 +353,20 @@ namespace Mono.CSharp {
                                        }
 
                                        if (best.MemberDefinition.IsImported && ts.MemberDefinition.IsImported) {
+                                               if (ts.Kind == MemberKind.MissingType)
+                                                       continue;
+
+                                               if (best.Kind == MemberKind.MissingType) {
+                                                       best = ts;
+                                                       continue;
+                                               }
+
                                                if (mode == LookupMode.Normal) {
                                                        ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (best);
                                                        ctx.Module.Compiler.Report.SymbolRelatedToPreviousError (ts);
                                                        ctx.Module.Compiler.Report.Error (433, loc, "The imported type `{0}' is defined multiple times", ts.GetSignatureForError ());
                                                }
+
                                                break;
                                        }
 
index 1732a9b9c5c46edda117e4104b1d1637ad617bda..5b846b59b2fae432de070df5d7a51286424ea80c 100644 (file)
@@ -201,6 +201,11 @@ namespace Mono.CSharp.Nullable
                        return uw != null && expr.Equals (uw.expr);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                public Expression Original {
                        get {
                                return expr;
@@ -480,6 +485,11 @@ namespace Mono.CSharp.Nullable
                        ec.MarkLabel (end_label);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+               }
+
                public void AddressOf (EmitContext ec, AddressOp mode)
                {
                        unwrap.AddressOf (ec, mode);
@@ -1008,6 +1018,11 @@ namespace Mono.CSharp.Nullable
                        ec.MarkLabel (end_label);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Binary.FlowAnalysis (fc);
+               }
+
                public override SLE.Expression MakeExpression (BuilderContext ctx)
                {
                        return Binary.MakeExpression (ctx, Left, Right);
@@ -1221,6 +1236,14 @@ namespace Mono.CSharp.Nullable
                        ec.MarkLabel (end_label);
                }
 
+               public override void FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       left.FlowAnalysis (fc);
+                       var left_da = fc.BranchDefiniteAssignment ();
+                       right.FlowAnalysis (fc);
+                       fc.DefiniteAssignment = left_da;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Expression t)
                {
                        NullCoalescingOperator target = (NullCoalescingOperator) t;
index b9bb8302eaca16d14aba215ba3268124e1577bb6..7090c4a7aefb05e22389c3728c0b2250e10bd39b 100644 (file)
@@ -24,6 +24,13 @@ namespace Mono.CSharp {
        
        public abstract class Statement {
                public Location loc;
+               protected bool reachable;
+
+               public bool IsUnreachable {
+                       get {
+                               return !reachable;
+                       }
+               }
                
                /// <summary>
                ///   Resolves the statement, true means that all sub-statements
@@ -34,44 +41,6 @@ namespace Mono.CSharp {
                        return true;
                }
 
-               /// <summary>
-               ///   We already know that the statement is unreachable, but we still
-               ///   need to resolve it to catch errors.
-               /// </summary>
-               public virtual bool ResolveUnreachable (BlockContext ec, bool warn)
-               {
-                       //
-                       // This conflicts with csc's way of doing this, but IMHO it's
-                       // the right thing to do.
-                       //
-                       // If something is unreachable, we still check whether it's
-                       // correct.  This means that you cannot use unassigned variables
-                       // in unreachable code, for instance.
-                       //
-
-                       bool unreachable = false;
-                       if (warn && !ec.UnreachableReported) {
-
-                               // TODO: This is wrong, need to form of flow-analysis branch specific flag
-                               // or multiple unrelared unreachable code won't be reported
-                               // if (false) { // ok } if (false) { // not reported }
-                               ec.UnreachableReported = true;
-                               unreachable = true;
-                               ec.Report.Warning (162, 2, loc, "Unreachable code detected");
-                       }
-
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       bool ok = Resolve (ec);
-                       ec.KillFlowBranching ();
-
-                       if (unreachable) {
-                               ec.UnreachableReported = false;
-                       }
-
-                       return ok;
-               }
-                               
                /// <summary>
                ///   Return value indicates whether all code paths emitted return.
                /// </summary>
@@ -110,6 +79,66 @@ namespace Mono.CSharp {
                {
                        return visitor.Visit (this);
                }
+
+               //
+               // Return value indicates whether statement has unreachable end
+               //
+               protected abstract bool DoFlowAnalysis (FlowAnalysisContext fc);
+
+               public bool FlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (reachable) {
+                               fc.UnreachableReported = false;
+                               var res = DoFlowAnalysis (fc);
+                               fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null;
+                               return res;
+                       }
+
+                       //
+                       // Special handling cases
+                       //
+                       if (this is Block) {
+                               return DoFlowAnalysis (fc);
+                       }
+
+                       if (this is EmptyStatement)
+                               return true;
+
+                       if (fc.UnreachableReported)
+                               return true;
+
+                       fc.Report.Warning (162, 2, loc, "Unreachable code detected");
+                       fc.UnreachableReported = true;
+                       return true;
+               }
+
+               public virtual Reachability MarkReachable (Reachability rc)
+               {
+                       if (!rc.IsUnreachable)
+                               reachable = true;
+
+                       return rc;
+               }
+
+               protected void CheckExitBoundaries (BlockContext bc, Block scope)
+               {
+                       if (bc.CurrentBlock.ParametersBlock.Original != scope.ParametersBlock.Original) {
+                               bc.Report.Error (1632, loc, "Control cannot leave the body of an anonymous method");
+                               return;
+                       }
+
+                       for (var b = bc.CurrentBlock; b != null && b != scope; b = b.Parent) {
+                               if (b.IsFinallyBlock) {
+                                       Error_FinallyClauseExit (bc);
+                                       break;
+                               }
+                       }
+               }
+
+               protected void Error_FinallyClauseExit (BlockContext bc)
+               {
+                       bc.Report.Error (157, loc, "Control cannot leave the body of a finally clause");
+               }
        }
 
        public sealed class EmptyStatement : Statement
@@ -118,13 +147,8 @@ namespace Mono.CSharp {
                {
                        this.loc = loc;
                }
-               
-               public override bool Resolve (BlockContext ec)
-               {
-                       return true;
-               }
 
-               public override bool ResolveUnreachable (BlockContext ec, bool warn)
+               public override bool Resolve (BlockContext ec)
                {
                        return true;
                }
@@ -138,6 +162,11 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ();
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return false;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement target)
                {
                        // nothing needed.
@@ -148,13 +177,13 @@ namespace Mono.CSharp {
                        return visitor.Visit (this);
                }
        }
-       
+
        public class If : Statement {
                Expression expr;
                public Statement TrueStatement;
                public Statement FalseStatement;
 
-               bool is_true_ret;
+               bool true_returns, false_returns;
 
                public If (Expression bool_expr, Statement true_statement, Location l)
                        : this (bool_expr, true_statement, null, l)
@@ -180,51 +209,13 @@ namespace Mono.CSharp {
                
                public override bool Resolve (BlockContext ec)
                {
-                       bool ok = true;
-
                        expr = expr.Resolve (ec);
-                       if (expr == null) {
-                               ok = false;
-                       } else {
-                               //
-                               // Dead code elimination
-                               //
-                               if (expr is Constant) {
-                                       bool take = !((Constant) expr).IsDefaultValue;
-                                       if (take) {
-                                               if (!TrueStatement.Resolve (ec))
-                                                       return false;
 
-                                               if ((FalseStatement != null) &&
-                                                       !FalseStatement.ResolveUnreachable (ec, true))
-                                                       return false;
-                                               FalseStatement = null;
-                                       } else {
-                                               if (!TrueStatement.ResolveUnreachable (ec, true))
-                                                       return false;
-                                               TrueStatement = null;
-
-                                               if ((FalseStatement != null) &&
-                                                       !FalseStatement.Resolve (ec))
-                                                       return false;
-                                       }
+                       var ok = TrueStatement.Resolve (ec);
 
-                                       return true;
-                               }
-                       }
-
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
-                       
-                       ok &= TrueStatement.Resolve (ec);
-
-                       is_true_ret = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
-
-                       ec.CurrentBranching.CreateSibling ();
-
-                       if (FalseStatement != null)
+                       if (FalseStatement != null) {
                                ok &= FalseStatement.Resolve (ec);
-                                       
-                       ec.EndFlowBranching ();
+                       }
 
                        return ok;
                }
@@ -258,7 +249,7 @@ namespace Mono.CSharp {
                                bool branch_emitted = false;
                                
                                end = ec.DefineLabel ();
-                               if (!is_true_ret){
+                               if (!true_returns){
                                        ec.Emit (OpCodes.Br, end);
                                        branch_emitted = true;
                                }
@@ -273,6 +264,80 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
+
+                       expr.FlowAnalysis (fc);
+
+                       var da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse);
+
+                       fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue;
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null;
+
+                       var res = TrueStatement.FlowAnalysis (fc);
+
+                       if (FalseStatement == null) {
+                               if (true_returns)
+                                       fc.DefiniteAssignment = da_false;
+                               else
+                                       fc.DefiniteAssignment &= da_false;
+                               return false;
+                       }
+
+                       if (true_returns) {
+                               fc.DefiniteAssignment = da_false;
+                               return FalseStatement.FlowAnalysis (fc);
+                       }
+
+                       var da_true = fc.DefiniteAssignment;
+
+                       fc.DefiniteAssignment = da_false;
+                       res &= FalseStatement.FlowAnalysis (fc);
+
+                       if (!TrueStatement.IsUnreachable) {
+                               if (false_returns || FalseStatement.IsUnreachable)
+                                       fc.DefiniteAssignment = da_true;
+                               else
+                                       fc.DefiniteAssignment &= da_true;
+                       }
+
+                       return res;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (rc.IsUnreachable)
+                               return rc;
+
+                       base.MarkReachable (rc);
+
+                       var c = expr as Constant;
+                       if (c != null) {
+                               bool take = !c.IsDefaultValue;
+                               if (take) {
+                                       rc = TrueStatement.MarkReachable (rc);
+                               } else {
+                                       if (FalseStatement != null)
+                                               rc = FalseStatement.MarkReachable (rc);
+                               }
+
+                               return rc;
+                       }
+
+                       var true_rc = TrueStatement.MarkReachable (rc);
+                       true_returns = true_rc.IsUnreachable;
+       
+                       if (FalseStatement == null)
+                               return rc;
+
+                       var false_rc = FalseStatement.MarkReachable (rc);
+                       false_returns = false_rc.IsUnreachable;
+
+                       return true_rc & false_rc;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        If target = (If) t;
@@ -289,14 +354,15 @@ namespace Mono.CSharp {
                }
        }
 
-       public class Do : Statement {
+       public class Do : LoopStatement
+       {
                public Expression expr;
-               public Statement  EmbeddedStatement;
+               bool iterator_reachable, end_reachable;
 
                public Do (Statement statement, BooleanExpression bool_expr, Location doLocation, Location whileLocation)
+                       : base (statement)
                {
                        expr = bool_expr;
-                       EmbeddedStatement = statement;
                        loc = doLocation;
                        WhileLocation = whileLocation;
                }
@@ -305,32 +371,11 @@ namespace Mono.CSharp {
                        get; private set;
                }
 
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
-                       bool ok = true;
-
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
+                       var ok = base.Resolve (bc);
 
-                       bool was_unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
-
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc);
-                       if (!EmbeddedStatement.Resolve (ec))
-                               ok = false;
-                       ec.EndFlowBranching ();
-
-                       if (ec.CurrentBranching.CurrentUsageVector.IsUnreachable && !was_unreachable)
-                               ec.Report.Warning (162, 2, expr.Location, "Unreachable code detected");
-
-                       expr = expr.Resolve (ec);
-                       if (expr == null)
-                               ok = false;
-                       else if (expr is Constant){
-                               bool infinite = !((Constant) expr).IsDefaultValue;
-                               if (infinite)
-                                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       }
-
-                       ec.EndFlowBranching ();
+                       expr = expr.Resolve (bc);
 
                        return ok;
                }
@@ -345,7 +390,7 @@ namespace Mono.CSharp {
                        ec.LoopEnd = ec.DefineLabel ();
                                
                        ec.MarkLabel (loop);
-                       EmbeddedStatement.Emit (ec);
+                       Statement.Emit (ec);
                        ec.MarkLabel (ec.LoopBegin);
 
                        // Mark start of while condition
@@ -370,11 +415,52 @@ namespace Mono.CSharp {
                        ec.LoopEnd = old_end;
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var res = Statement.FlowAnalysis (fc);
+
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
+                       expr.FlowAnalysis (fc);
+
+                       fc.DefiniteAssignment = fc.DefiniteAssignmentOnFalse;
+
+                       if (res && !iterator_reachable)
+                               return !end_reachable;
+
+                       if (!end_reachable) {
+                               var c = expr as Constant;
+                               if (c != null && !c.IsDefaultValue)
+                                       return true;
+                       }
+
+                       return false;
+               }
+               
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       
+                       var body_rc = Statement.MarkReachable (rc);
+
+                       if (body_rc.IsUnreachable && !iterator_reachable) {
+                               expr = new UnreachableExpression (expr);
+                               return end_reachable ? rc : Reachability.CreateUnreachable ();
+                       }
+
+                       if (!end_reachable) {
+                               var c = expr as Constant;
+                               if (c != null && !c.IsDefaultValue)
+                                       return Reachability.CreateUnreachable ();
+                       }
+
+                       return rc;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Do target = (Do) t;
 
-                       target.EmbeddedStatement = EmbeddedStatement.Clone (clonectx);
+                       target.Statement = Statement.Clone (clonectx);
                        target.expr = expr.Clone (clonectx);
                }
                
@@ -382,58 +468,46 @@ namespace Mono.CSharp {
                {
                        return visitor.Visit (this);
                }
+
+               public override void SetEndReachable ()
+               {
+                       end_reachable = true;
+               }
+
+               public override void SetIteratorReachable ()
+               {
+                       iterator_reachable = true;
+               }
        }
 
-       public class While : Statement {
+       public class While : LoopStatement
+       {
                public Expression expr;
-               public Statement Statement;
-               bool infinite, empty;
+               bool empty, infinite, end_reachable;
+               List<DefiniteAssignmentBitSet> end_reachable_das;
 
                public While (BooleanExpression bool_expr, Statement statement, Location l)
+                       : base (statement)
                {
                        this.expr = bool_expr;
-                       Statement = statement;
                        loc = l;
                }
 
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
                        bool ok = true;
 
-                       expr = expr.Resolve (ec);
+                       expr = expr.Resolve (bc);
                        if (expr == null)
                                ok = false;
 
-                       //
-                       // Inform whether we are infinite or not
-                       //
-                       if (expr is Constant){
-                               bool value = !((Constant) expr).IsDefaultValue;
-
-                               if (value == false){
-                                       if (!Statement.ResolveUnreachable (ec, true))
-                                               return false;
-                                       empty = true;
-                                       return true;
-                               }
-
-                               infinite = true;
+                       var c = expr as Constant;
+                       if (c != null) {
+                               empty = c.IsDefaultValue;
+                               infinite = !empty;
                        }
 
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
-                       if (!infinite)
-                               ec.CurrentBranching.CreateSibling ();
-
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc);
-                       if (!Statement.Resolve (ec))
-                               ok = false;
-                       ec.EndFlowBranching ();
-
-                       // There's no direct control flow from the end of the embedded statement to the end of the loop
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-
-                       ec.EndFlowBranching ();
-
+                       ok &= base.Resolve (bc);
                        return ok;
                }
                
@@ -489,6 +563,60 @@ namespace Mono.CSharp {
                        ec.LoopEnd = old_end;
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
+       
+                       expr.FlowAnalysis (fc);
+
+                       fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue;
+                       var da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse);
+                       fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null;
+
+                       Statement.FlowAnalysis (fc);
+
+                       //
+                       // Special case infinite while with breaks
+                       //
+                       if (end_reachable_das != null) {
+                               da_false = DefiniteAssignmentBitSet.And (end_reachable_das);
+                               end_reachable_das = null;
+                       }
+
+                       fc.DefiniteAssignment = da_false;
+
+                       if (infinite && !end_reachable)
+                               return true;
+
+                       return false;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (rc.IsUnreachable)
+                               return rc;
+
+                       base.MarkReachable (rc);
+
+                       //
+                       // Special case unreachable while body
+                       //
+                       if (empty) {
+                               Statement.MarkReachable (Reachability.CreateUnreachable ());
+                               return rc;
+                       }
+
+                       Statement.MarkReachable (rc);
+
+                       //
+                       // When infinite while end is unreachable via break anything what follows is unreachable too
+                       //
+                       if (infinite && !end_reachable)
+                               return Reachability.CreateUnreachable ();
+
+                       return rc;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        While target = (While) t;
@@ -501,13 +629,31 @@ namespace Mono.CSharp {
                {
                        return visitor.Visit (this);
                }
+
+               public override void AddEndDefiniteAssignment (FlowAnalysisContext fc)
+               {
+                       if (!infinite)
+                               return;
+
+                       if (end_reachable_das == null)
+                               end_reachable_das = new List<DefiniteAssignmentBitSet> ();
+
+                       end_reachable_das.Add (fc.DefiniteAssignment);
+               }
+
+               public override void SetEndReachable ()
+               {
+                       end_reachable = true;
+               }
        }
 
-       public class For : Statement
+       public class For : LoopStatement
        {
-               bool infinite, empty;
+               bool infinite, empty, iterator_reachable, end_reachable;
+               List<DefiniteAssignmentBitSet> end_reachable_das;
                
                public For (Location l)
+                       : base (null)
                {
                        loc = l;
                }
@@ -524,68 +670,86 @@ namespace Mono.CSharp {
                        get; set;
                }
 
-               public Statement Statement {
-                       get; set;
-               }
-
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
-                       bool ok = true;
-
-                       if (Initializer != null) {
-                               if (!Initializer.Resolve (ec))
-                                       ok = false;
-                       }
+                       Initializer.Resolve (bc);
 
                        if (Condition != null) {
-                               Condition = Condition.Resolve (ec);
-                               if (Condition == null)
-                                       ok = false;
-                               else if (Condition is Constant) {
-                                       bool value = !((Constant) Condition).IsDefaultValue;
-
-                                       if (value == false){
-                                               if (!Statement.ResolveUnreachable (ec, true))
-                                                       return false;
-                                               if ((Iterator != null) &&
-                                                       !Iterator.ResolveUnreachable (ec, false))
-                                                       return false;
+                               Condition = Condition.Resolve (bc);
+                               var condition_constant = Condition as Constant;
+                               if (condition_constant != null) {
+                                       if (condition_constant.IsDefaultValue) {
                                                empty = true;
-                                               return true;
+                                       } else {
+                                               infinite = true;
                                        }
-
-                                       infinite = true;
                                }
-                       } else
+                       } else {
                                infinite = true;
+                       }
 
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
-                       if (!infinite)
-                               ec.CurrentBranching.CreateSibling ();
+                       base.Resolve (bc);
 
-                       bool was_unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
+                       Iterator.Resolve (bc);
 
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc);
-                       if (!Statement.Resolve (ec))
-                               ok = false;
-                       ec.EndFlowBranching ();
+                       return true;
+               }
 
-                       if (Iterator != null){
-                               if (ec.CurrentBranching.CurrentUsageVector.IsUnreachable) {
-                                       if (!Iterator.ResolveUnreachable (ec, !was_unreachable))
-                                               ok = false;
-                               } else {
-                                       if (!Iterator.Resolve (ec))
-                                               ok = false;
-                               }
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Initializer.FlowAnalysis (fc);
+
+                       DefiniteAssignmentBitSet da_false;
+                       if (Condition != null) {
+                               fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = fc.DefiniteAssignment;
+
+                               Condition.FlowAnalysis (fc);
+                               fc.DefiniteAssignment = fc.DefiniteAssignmentOnTrue;
+                               da_false = new DefiniteAssignmentBitSet (fc.DefiniteAssignmentOnFalse);
+                               fc.DefiniteAssignmentOnTrue = fc.DefiniteAssignmentOnFalse = null;
+                       } else {
+                               da_false = fc.BranchDefiniteAssignment ();
                        }
 
-                       // There's no direct control flow from the end of the embedded statement to the end of the loop
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
+                       Statement.FlowAnalysis (fc);
 
-                       ec.EndFlowBranching ();
+                       Iterator.FlowAnalysis (fc);
 
-                       return ok;
+                       //
+                       // Special case infinite for with breaks
+                       //
+                       if (end_reachable_das != null) {
+                               da_false = DefiniteAssignmentBitSet.And (end_reachable_das);
+                               end_reachable_das = null;
+                       }
+
+                       fc.DefiniteAssignment = da_false;
+
+                       if (infinite && !end_reachable)
+                               return true;
+
+                       return false;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       Initializer.MarkReachable (rc);
+
+                       var body_rc = Statement.MarkReachable (rc);
+                       if (!body_rc.IsUnreachable || iterator_reachable) {
+                               Iterator.MarkReachable (rc);
+                       }
+
+                       //
+                       // When infinite for end is unreachable via break anything what follows is unreachable too
+                       //
+                       if (infinite && !end_reachable) {
+                               return Reachability.CreateUnreachable ();
+                       }
+
+                       return rc;
                }
 
                protected override void DoEmit (EmitContext ec)
@@ -658,6 +822,64 @@ namespace Mono.CSharp {
                {
                        return visitor.Visit (this);
                }
+
+               public override void AddEndDefiniteAssignment (FlowAnalysisContext fc)
+               {
+                       if (!infinite)
+                               return;
+
+                       if (end_reachable_das == null)
+                               end_reachable_das = new List<DefiniteAssignmentBitSet> ();
+
+                       end_reachable_das.Add (fc.DefiniteAssignment);
+               }
+
+               public override void SetEndReachable ()
+               {
+                       end_reachable = true;
+               }
+
+               public override void SetIteratorReachable ()
+               {
+                       iterator_reachable = true;
+               }
+       }
+
+       public abstract class LoopStatement : Statement
+       {
+               protected LoopStatement (Statement statement)
+               {
+                       Statement = statement;
+               }
+
+               public Statement Statement { get; set; }
+
+               public override bool Resolve (BlockContext bc)
+               {
+                       var prev_loop = bc.EnclosingLoop;
+                       var prev_los = bc.EnclosingLoopOrSwitch;
+                       bc.EnclosingLoopOrSwitch = bc.EnclosingLoop = this;
+                       Statement.Resolve (bc);
+                       bc.EnclosingLoopOrSwitch = prev_los;
+                       bc.EnclosingLoop = prev_loop;
+
+                       return true;
+               }
+
+               //
+               // Needed by possibly infinite loops statements (for, while) and switch statment
+               //
+               public virtual void AddEndDefiniteAssignment (FlowAnalysisContext fc)
+               {
+               }
+
+               public virtual void SetEndReachable ()
+               {
+               }
+
+               public virtual void SetIteratorReachable ()
+               {
+               }
        }
        
        public class StatementExpression : Statement
@@ -693,6 +915,19 @@ namespace Mono.CSharp {
                        expr.EmitStatement (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+                       return false;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       expr.MarkReachable (rc);
+                       return rc;
+               }
+
                public override bool Resolve (BlockContext ec)
                {
                        expr = expr.ResolveStatement (ec);
@@ -732,6 +967,11 @@ namespace Mono.CSharp {
                        throw new NotSupportedException ();
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return false;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement target)
                {
                        var t = (StatementErrorExpression) target;
@@ -784,6 +1024,25 @@ namespace Mono.CSharp {
                                s.Emit (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       foreach (var s in statements)
+                               s.FlowAnalysis (fc);
+
+                       return false;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       Reachability res = rc;
+                       foreach (var s in statements)
+                               res = s.MarkReachable (rc);
+
+                       return res;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement target)
                {
                        StatementList t = (StatementList) target;
@@ -799,23 +1058,54 @@ namespace Mono.CSharp {
                }
        }
 
-       // A 'return' or a 'yield break'
+       //
+       // For statements which require special handling when inside try or catch block
+       //
        public abstract class ExitStatement : Statement
        {
                protected bool unwind_protect;
-               protected abstract bool DoResolve (BlockContext ec);
 
-               public virtual void Error_FinallyClause (Report Report)
+               protected abstract bool DoResolve (BlockContext bc);
+               protected abstract bool IsLocalExit { get; }
+
+               public override bool Resolve (BlockContext bc)
                {
-                       Report.Error (157, loc, "Control cannot leave the body of a finally clause");
+                       var res = DoResolve (bc);
+
+                       if (!IsLocalExit) {
+                               //
+                               // We are inside finally scope but is it the scope we are exiting
+                               //
+                               if (bc.HasSet (ResolveContext.Options.FinallyScope)) {
+
+                                       for (var b = bc.CurrentBlock; b != null; b = b.Parent) {
+                                               if (b.IsFinallyBlock) {
+                                                       Error_FinallyClauseExit (bc);
+                                                       break;
+                                               }
+
+                                               if (b is ParametersBlock)
+                                                       break;
+                                       }
+                               }
+                       }
+
+                       unwind_protect = bc.HasAny (ResolveContext.Options.TryScope | ResolveContext.Options.CatchScope);
+                       return res;
                }
 
-               public sealed override bool Resolve (BlockContext ec)
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
                {
-                       var res = DoResolve (ec);
-                       unwind_protect = ec.CurrentBranching.AddReturnOrigin (ec.CurrentBranching.CurrentUsageVector, this);
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return res;
+                       if (IsLocalExit)
+                               return true;
+
+                       if (fc.TryFinally != null) {
+                           fc.TryFinally.RegisterForControlExitCheck (new DefiniteAssignmentBitSet (fc.DefiniteAssignment));
+                       } else {
+                           fc.ParametersBlock.CheckControlExit (fc);
+                       }
+
+                       return true;
                }
        }
 
@@ -843,12 +1133,20 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool IsLocalExit {
+                       get {
+                               return false;
+                       }
+               }
+
                #endregion
 
                protected override bool DoResolve (BlockContext ec)
                {
+                       var block_return_type = ec.ReturnType;
+
                        if (expr == null) {
-                               if (ec.ReturnType.Kind == MemberKind.Void)
+                               if (block_return_type.Kind == MemberKind.Void)
                                        return true;
 
                                //
@@ -864,21 +1162,23 @@ namespace Mono.CSharp {
                                                expr = EmptyExpression.Null;
                                                return true;
                                        }
+
+                                       if (storey.ReturnType.IsGenericTask)
+                                               block_return_type = storey.ReturnType.TypeArguments[0];
                                }
 
                                if (ec.CurrentIterator != null) {
                                        Error_ReturnFromIterator (ec);
-                               } else if (ec.ReturnType != InternalType.ErrorType) {
+                               } else if (block_return_type != InternalType.ErrorType) {
                                        ec.Report.Error (126, loc,
                                                "An object of a type convertible to `{0}' is required for the return statement",
-                                               ec.ReturnType.GetSignatureForError ());
+                                               block_return_type.GetSignatureForError ());
                                }
 
                                return false;
                        }
 
                        expr = expr.Resolve (ec);
-                       TypeSpec block_return_type = ec.ReturnType;
 
                        AnonymousExpression am = ec.CurrentAnonymousMethod;
                        if (am == null) {
@@ -1007,7 +1307,7 @@ namespace Mono.CSharp {
                                                ec.EmitEpilogue ();
                                        }
 
-                                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, async_body.BodyEnd);
+                                       ec.Emit (OpCodes.Leave, async_body.BodyEnd);
                                        return;
                                }
 
@@ -1026,12 +1326,27 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (expr != null)
+                               expr.FlowAnalysis (fc);
+
+                       base.DoFlowAnalysis (fc);
+                       return true;
+               }
+
                void Error_ReturnFromIterator (ResolveContext rc)
                {
                        rc.Report.Error (1622, loc,
                                "Cannot return a value from iterators. Use the yield return statement to return a value, or yield break to end the iteration");
                }
 
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Reachability.CreateUnreachable ();
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Return target = (Return) t;
@@ -1046,18 +1361,12 @@ namespace Mono.CSharp {
                }
        }
 
-       public class Goto : Statement {
+       public class Goto : ExitStatement
+       {
                string target;
                LabeledStatement label;
-               bool unwind_protect;
+               TryFinally try_finally;
 
-               public override bool Resolve (BlockContext ec)
-               {
-                       unwind_protect = ec.CurrentBranching.AddGotoOrigin (ec.CurrentBranching.CurrentUsageVector, this);
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return true;
-               }
-               
                public Goto (string label, Location l)
                {
                        loc = l;
@@ -1068,10 +1377,67 @@ namespace Mono.CSharp {
                        get { return target; }
                }
 
-               public void SetResolvedTarget (LabeledStatement label)
+               protected override bool IsLocalExit {
+                       get {
+                               return true;
+                       }
+               }
+
+               protected override bool DoResolve (BlockContext bc)
                {
-                       this.label = label;
-                       label.AddReference ();
+                       label = bc.CurrentBlock.LookupLabel (target);
+                       if (label == null) {
+                               Error_UnknownLabel (bc, target, loc);
+                               return false;
+                       }
+
+                       try_finally = bc.CurrentTryBlock as TryFinally;
+
+                       CheckExitBoundaries (bc, label.Block);
+
+                       return true;
+               }
+
+               public static void Error_UnknownLabel (BlockContext bc, string label, Location loc)
+               {
+                       bc.Report.Error (159, loc, "The label `{0}:' could not be found within the scope of the goto statement",
+                               label);
+               }
+
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (fc.LabelStack == null) {
+                               fc.LabelStack = new List<LabeledStatement> ();
+                       } else if (fc.LabelStack.Contains (label)) {
+                               return true;
+                       }
+
+                       fc.LabelStack.Add (label);
+                       label.Block.ScanGotoJump (label, fc);
+                       fc.LabelStack.Remove (label);
+                       return true;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (rc.IsUnreachable)
+                               return rc;
+
+                       base.MarkReachable (rc);
+
+                       if (try_finally != null) {
+                               if (try_finally.FinallyBlock.HasReachableClosingBrace) {
+                                       label.AddGotoReference (rc, false);
+                               } else {
+                                       label.AddGotoReference (rc, true);
+                               }
+
+                               try_finally = null;
+                       } else {
+                               label.AddGotoReference (rc, false);
+                       }
+
+                       return Reachability.CreateUnreachable ();
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement target)
@@ -1083,6 +1449,7 @@ namespace Mono.CSharp {
                {
                        if (label == null)
                                throw new InternalErrorException ("goto emitted before target resolved");
+
                        Label l = label.LabelTarget (ec);
                        ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, l);
                }
@@ -1097,10 +1464,9 @@ namespace Mono.CSharp {
                string name;
                bool defined;
                bool referenced;
+               bool finalTarget;
                Label label;
                Block block;
-
-               FlowBranching.UsageVector vectors;
                
                public LabeledStatement (string name, Block block, Location l)
                {
@@ -1129,51 +1495,68 @@ namespace Mono.CSharp {
                        get { return name; }
                }
 
-               public bool IsDefined {
-                       get { return defined; }
-               }
-
-               public bool HasBeenReferenced {
-                       get { return referenced; }
-               }
+               protected override void CloneTo (CloneContext clonectx, Statement target)
+               {
+                       var t = (LabeledStatement) target;
 
-               public FlowBranching.UsageVector JumpOrigins {
-                       get { return vectors; }
+                       t.block = clonectx.RemapBlockCopy (block);
                }
 
-               public void AddUsageVector (FlowBranching.UsageVector vector)
+               public override bool Resolve (BlockContext bc)
                {
-                       vector = vector.Clone ();
-                       vector.Next = vectors;
-                       vectors = vector;
+                       return true;
                }
 
-               protected override void CloneTo (CloneContext clonectx, Statement target)
+               protected override void DoEmit (EmitContext ec)
                {
-                       // nothing to clone
+                       LabelTarget (ec);
+                       ec.MarkLabel (label);
+
+                       if (finalTarget)
+                               ec.Emit (OpCodes.Br_S, label);
                }
 
-               public override bool Resolve (BlockContext ec)
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
                {
-                       // this flow-branching will be terminated when the surrounding block ends
-                       ec.StartFlowBranching (this);
-                       return true;
+                       if (!referenced) {
+                               fc.Report.Warning (164, 2, loc, "This label has not been referenced");
+                       }
+
+                       return false;
                }
 
-               protected override void DoEmit (EmitContext ec)
+               public override Reachability MarkReachable (Reachability rc)
                {
-                       if (!HasBeenReferenced)
-                               ec.Report.Warning (164, 2, loc, "This label has not been referenced");
+                       base.MarkReachable (rc);
 
-                       LabelTarget (ec);
-                       ec.MarkLabel (label);
+                       if (referenced)
+                               rc = new Reachability ();
+
+                       return rc;
                }
 
-               public void AddReference ()
+               public void AddGotoReference (Reachability rc, bool finalTarget)
                {
+                       if (referenced)
+                               return;
+
                        referenced = true;
+                       MarkReachable (rc);
+
+                       //
+                       // Label is final target when goto jumps out of try block with
+                       // finally clause. In that case we need leave with target but in C#
+                       // terms the label is unreachable. Using finalTarget we emit
+                       // explicit label not just marker
+                       //
+                       if (finalTarget) {
+                               this.finalTarget = true;
+                               return;
+                       }
+
+                       block.ScanGotoJump (this);
                }
-               
+
                public override object Accept (StructuralVisitor visitor)
                {
                        return visitor.Visit (this);
@@ -1184,37 +1567,44 @@ namespace Mono.CSharp {
        /// <summary>
        ///   `goto default' statement
        /// </summary>
-       public class GotoDefault : Statement {
-               
+       public class GotoDefault : SwitchGoto
+       {               
                public GotoDefault (Location l)
+                       : base (l)
                {
-                       loc = l;
-               }
-
-               protected override void CloneTo (CloneContext clonectx, Statement target)
-               {
-                       // nothing to clone
                }
 
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-
-                       if (ec.Switch == null) {
-                               ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+                       if (bc.Switch == null) {
+                               Error_GotoCaseRequiresSwitchBlock (bc);
                                return false;
                        }
 
-                       ec.Switch.RegisterGotoCase (null, null);
+                       bc.Switch.RegisterGotoCase (null, null);
+                       base.Resolve (bc);
 
                        return true;
                }
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.Emit (OpCodes.Br, ec.Switch.DefaultLabel.GetILLabel (ec));
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.Switch.DefaultLabel.GetILLabel (ec));
                }
-               
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (!rc.IsUnreachable) {
+                               var label = switch_statement.DefaultLabel;
+                               if (label.IsUnreachable) {
+                                       label.MarkReachable (rc);
+                                       switch_statement.Block.ScanGotoJump (label);
+                               }
+                       }
+
+                       return base.MarkReachable (rc);
+               }
+
                public override object Accept (StructuralVisitor visitor)
                {
                        return visitor.Visit (this);
@@ -1224,32 +1614,31 @@ namespace Mono.CSharp {
        /// <summary>
        ///   `goto case' statement
        /// </summary>
-       public class GotoCase : Statement {
+       public class GotoCase : SwitchGoto
+       {
                Expression expr;
                
                public GotoCase (Expression e, Location l)
+                       : base (l)
                {
                        expr = e;
-                       loc = l;
                }
 
                public Expression Expr {
                        get {
-                               return this.expr;
+                               return expr;
                        }
                }
 
                public SwitchLabel Label { get; set; }
-               
+
                public override bool Resolve (BlockContext ec)
                {
-                       if (ec.Switch == null){
-                               ec.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+                       if (ec.Switch == null) {
+                               Error_GotoCaseRequiresSwitchBlock (ec);
                                return false;
                        }
 
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-
                        Constant c = expr.ResolveLabelConstant (ec);
                        if (c == null) {
                                return false;
@@ -1274,12 +1663,15 @@ namespace Mono.CSharp {
                        }
 
                        ec.Switch.RegisterGotoCase (this, res);
+                       base.Resolve (ec);
+                       expr = res;
+
                        return true;
                }
 
                protected override void DoEmit (EmitContext ec)
                {
-                       ec.Emit (OpCodes.Br, Label.GetILLabel (ec));
+                       ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, Label.GetILLabel (ec));
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement t)
@@ -1288,12 +1680,67 @@ namespace Mono.CSharp {
 
                        target.expr = expr.Clone (clonectx);
                }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (!rc.IsUnreachable) {
+                               var label = switch_statement.FindLabel ((Constant) expr);
+                               if (label.IsUnreachable) {
+                                       label.MarkReachable (rc);
+                                       switch_statement.Block.ScanGotoJump (label);
+                               }
+                       }
+
+                       return base.MarkReachable (rc);
+               }
                
                public override object Accept (StructuralVisitor visitor)
                {
                        return visitor.Visit (this);
                }
        }
+
+       public abstract class SwitchGoto : Statement
+       {
+               protected bool unwind_protect;
+               protected Switch switch_statement;
+
+               protected SwitchGoto (Location loc)
+               {
+                       this.loc = loc;
+               }
+
+               protected override void CloneTo (CloneContext clonectx, Statement target)
+               {
+                       // Nothing to clone
+               }
+
+               public override bool Resolve (BlockContext bc)
+               {
+                       CheckExitBoundaries (bc, bc.Switch.Block);
+
+                       unwind_protect = bc.HasAny (ResolveContext.Options.TryScope | ResolveContext.Options.CatchScope);
+                       switch_statement = bc.Switch;
+
+                       return true;
+               }
+
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return true;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Reachability.CreateUnreachable ();
+               }
+
+               protected void Error_GotoCaseRequiresSwitchBlock (BlockContext bc)
+               {
+                       bc.Report.Error (153, loc, "A goto case is only valid inside a switch statement");
+               }
+       }
        
        public class Throw : Statement {
                Expression expr;
@@ -1313,12 +1760,22 @@ namespace Mono.CSharp {
                public override bool Resolve (BlockContext ec)
                {
                        if (expr == null) {
-                               ec.CurrentBranching.CurrentUsageVector.Goto ();
-                               return ec.CurrentBranching.CheckRethrow (loc);
+                               if (!ec.HasSet (ResolveContext.Options.CatchScope)) {
+                                       ec.Report.Error (156, loc, "A throw statement with no arguments is not allowed outside of a catch clause");
+                               } else if (ec.HasSet (ResolveContext.Options.FinallyScope)) {
+                                       for (var b = ec.CurrentBlock; b != null && !b.IsCatchBlock; b = b.Parent) {
+                                               if (b.IsFinallyBlock) {
+                                                       ec.Report.Error (724, loc,
+                                                               "A throw statement with no arguments is not allowed inside of a finally clause nested inside of the innermost catch clause");
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               return true;
                        }
 
                        expr = expr.Resolve (ec, ResolveFlags.Type | ResolveFlags.VariableOrValue);
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
 
                        if (expr == null)
                                return false;
@@ -1343,6 +1800,20 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (expr != null)
+                               expr.FlowAnalysis (fc);
+
+                       return true;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Reachability.CreateUnreachable ();
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Throw target = (Throw) t;
@@ -1357,20 +1828,16 @@ namespace Mono.CSharp {
                }
        }
 
-       public class Break : Statement {
-               
+       public class Break : LocalExitStatement
+       {               
                public Break (Location l)
+                       : base (l)
                {
-                       loc = l;
                }
-
-               bool unwind_protect;
-
-               public override bool Resolve (BlockContext ec)
+               
+               public override object Accept (StructuralVisitor visitor)
                {
-                       unwind_protect = ec.CurrentBranching.AddBreakOrigin (ec.CurrentBranching.CurrentUsageVector, loc);
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return true;
+                       return visitor.Visit (this);
                }
 
                protected override void DoEmit (EmitContext ec)
@@ -1378,46 +1845,99 @@ namespace Mono.CSharp {
                        ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopEnd);
                }
 
-               protected override void CloneTo (CloneContext clonectx, Statement t)
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
                {
-                       // nothing needed
+                       enclosing_loop.AddEndDefiniteAssignment (fc);
+                       return true;
                }
-               
-               public override object Accept (StructuralVisitor visitor)
+
+               protected override bool DoResolve (BlockContext bc)
                {
-                       return visitor.Visit (this);
+                       enclosing_loop = bc.EnclosingLoopOrSwitch;
+                       return base.DoResolve (bc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       if (!rc.IsUnreachable)
+                               enclosing_loop.SetEndReachable ();
+
+                       return Reachability.CreateUnreachable ();
                }
        }
 
-       public class Continue : Statement {
-               
+       public class Continue : LocalExitStatement
+       {               
                public Continue (Location l)
+                       : base (l)
                {
-                       loc = l;
                }
 
-               bool unwind_protect;
-
-               public override bool Resolve (BlockContext ec)
+               public override object Accept (StructuralVisitor visitor)
                {
-                       unwind_protect = ec.CurrentBranching.AddContinueOrigin (ec.CurrentBranching.CurrentUsageVector, loc);
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-                       return true;
+                       return visitor.Visit (this);
                }
 
+
                protected override void DoEmit (EmitContext ec)
                {
                        ec.Emit (unwind_protect ? OpCodes.Leave : OpCodes.Br, ec.LoopBegin);
                }
 
+               protected override bool DoResolve (BlockContext bc)
+               {
+                       enclosing_loop = bc.EnclosingLoop;
+                       return base.DoResolve (bc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       if (!rc.IsUnreachable)
+                               enclosing_loop.SetIteratorReachable ();
+
+                       return Reachability.CreateUnreachable ();
+               }
+       }
+
+       public abstract class LocalExitStatement : ExitStatement
+       {
+               protected LoopStatement enclosing_loop;
+
+               protected LocalExitStatement (Location loc)
+               {
+                       this.loc = loc;
+               }
+
+               protected override bool IsLocalExit {
+                       get {
+                               return true;
+                       }
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        // nothing needed.
                }
-               
-               public override object Accept (StructuralVisitor visitor)
+
+               protected override bool DoResolve (BlockContext bc)
                {
-                       return visitor.Visit (this);
+                       if (enclosing_loop == null) {
+                               bc.Report.Error (139, loc, "No enclosing loop out of which to break or continue");
+                               return false;
+                       }
+
+                       var block = enclosing_loop.Statement as Block;
+
+                       // Don't need to do extra checks for simple statements loops
+                       if (block != null) {
+                               CheckExitBoundaries (bc, block);
+                       }
+
+                       return true;
                }
        }
 
@@ -1679,6 +2199,30 @@ namespace Mono.CSharp {
                        }
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (Initializer != null)
+                               Initializer.FlowAnalysis (fc);
+
+                       if (declarators != null) {
+                               foreach (var d in declarators) {
+                                       if (d.Initializer != null)
+                                               d.Initializer.FlowAnalysis (fc);
+                               }
+                       }
+
+                       return false;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       var init = initializer as ExpressionStatement;
+                       if (init != null)
+                               init.MarkReachable (rc);
+
+                       return base.MarkReachable (rc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement target)
                {
                        BlockVariable t = (BlockVariable) target;
@@ -1749,7 +2293,7 @@ namespace Mono.CSharp {
        //
        // The information about a user-perceived local variable
        //
-       public class LocalVariable : INamedBlockVariable, ILocalVariable
+       public sealed class LocalVariable : INamedBlockVariable, ILocalVariable
        {
                [Flags]
                public enum Flags
@@ -1762,8 +2306,7 @@ namespace Mono.CSharp {
                        ForeachVariable = 1 << 5,
                        FixedVariable = 1 << 6,
                        UsingVariable = 1 << 7,
-//                     DefinitelyAssigned = 1 << 8,
-                       IsLocked = 1 << 9,
+                       IsLocked = 1 << 8,
 
                        ReadonlyMask = ForeachVariable | FixedVariable | UsingVariable
                }
@@ -2001,23 +2544,20 @@ namespace Mono.CSharp {
                        throw new InternalErrorException ("Variable is not readonly");
                }
 
-               public bool IsThisAssigned (BlockContext ec, Block block)
+               public bool IsThisAssigned (FlowAnalysisContext fc, Block block)
                {
                        if (VariableInfo == null)
                                throw new Exception ();
 
-                       if (!ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo))
+                       if (IsAssigned (fc))
                                return true;
 
-                       return VariableInfo.IsFullyInitialized (ec, block.StartLocation);
+                       return VariableInfo.IsFullyInitialized (fc, block.StartLocation);
                }
 
-               public bool IsAssigned (BlockContext ec)
+               public bool IsAssigned (FlowAnalysisContext fc)
                {
-                       if (VariableInfo == null)
-                               throw new Exception ();
-
-                       return !ec.DoFlowAnalysis || ec.CurrentBranching.IsAssigned (VariableInfo);
+                       return fc.IsDefinitelyAssigned (VariableInfo);
                }
 
                public void PrepareAssignmentAnalysis (BlockContext bc)
@@ -2069,7 +2609,7 @@ namespace Mono.CSharp {
                public enum Flags
                {
                        Unchecked = 1,
-                       HasRet = 8,
+                       ReachableEnd = 8,
                        Unsafe = 16,
                        HasCapturedVariable = 64,
                        HasCapturedThis = 1 << 7,
@@ -2079,7 +2619,10 @@ namespace Mono.CSharp {
                        Resolved = 1 << 11,
                        YieldBlock = 1 << 12,
                        AwaitBlock = 1 << 13,
-                       Iterator = 1 << 14
+                       FinallyBlock = 1 << 14,
+                       CatchBlock = 1 << 15,
+                       Iterator = 1 << 20,
+                       NoFlowAnalysis = 1 << 21
                }
 
                public Block Parent;
@@ -2137,15 +2680,6 @@ namespace Mono.CSharp {
 
                #region Properties
 
-               public bool HasUnreachableClosingBrace {
-                       get {
-                               return (flags & Flags.HasRet) != 0;
-                       }
-                       set {
-                               flags = value ? flags | Flags.HasRet : flags & ~Flags.HasRet;
-                       }
-               }
-
                public Block Original {
                        get {
                                return original;
@@ -2160,6 +2694,19 @@ namespace Mono.CSharp {
                        set { flags = value ? flags | Flags.CompilerGenerated : flags & ~Flags.CompilerGenerated; }
                }
 
+
+               public bool IsCatchBlock {
+                       get {
+                               return (flags & Flags.CatchBlock) != 0;
+                       }
+               }
+
+               public bool IsFinallyBlock {
+                       get {
+                               return (flags & Flags.FinallyBlock) != 0;
+                       }
+               }
+
                public bool Unchecked {
                        get { return (flags & Flags.Unchecked) != 0; }
                        set { flags = value ? flags | Flags.Unchecked : flags & ~Flags.Unchecked; }
@@ -2260,161 +2807,192 @@ namespace Mono.CSharp {
                        statements.Add (s);
                }
 
-               public int AssignableSlots {
-                       get {
-                               // FIXME: HACK, we don't know the block available variables count now, so set this high enough
-                               return 4096;
-//                             return assignable_slots;
-                       }
+               public LabeledStatement LookupLabel (string name)
+               {
+                       return ParametersBlock.GetLabel (name, this);
                }
 
-               public LabeledStatement LookupLabel (string name)
+               public override Reachability MarkReachable (Reachability rc)
                {
-                       return ParametersBlock.TopBlock.GetLabel (name, this);
+                       if (rc.IsUnreachable)
+                               return rc;
+
+                       base.MarkReachable (rc);
+
+                       if (scope_initializers != null) {
+                               foreach (var si in scope_initializers)
+                                       si.MarkReachable (rc);
+                       }
+
+                       foreach (var s in statements) {
+                               rc = s.MarkReachable (rc);
+                               if (rc.IsUnreachable) {
+                                       if ((flags & Flags.ReachableEnd) != 0)
+                                               return new Reachability ();
+
+                                       return rc;
+                               }
+                       }
+
+                       flags |= Flags.ReachableEnd;
+
+                       return rc;
                }
 
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
                        if ((flags & Flags.Resolved) != 0)
                                return true;
 
-                       Block prev_block = ec.CurrentBlock;
-                       bool ok = true;
-                       bool unreachable = ec.IsUnreachable;
-                       bool prev_unreachable = unreachable;
-
-                       ec.CurrentBlock = this;
-                       ec.StartFlowBranching (this);
+                       Block prev_block = bc.CurrentBlock;
+                       bc.CurrentBlock = this;
 
                        //
                        // Compiler generated scope statements
                        //
                        if (scope_initializers != null) {
                                for (resolving_init_idx = 0; resolving_init_idx < scope_initializers.Count; ++resolving_init_idx) {
-                                       scope_initializers[resolving_init_idx.Value].Resolve (ec);
+                                       scope_initializers[resolving_init_idx.Value].Resolve (bc);
                                }
 
                                resolving_init_idx = null;
                        }
 
-                       //
-                       // This flag is used to notate nested statements as unreachable from the beginning of this block.
-                       // For the purposes of this resolution, it doesn't matter that the whole block is unreachable 
-                       // from the beginning of the function.  The outer Resolve() that detected the unreachability is
-                       // responsible for handling the situation.
-                       //
+                       bool ok = true;
                        int statement_count = statements.Count;
                        for (int ix = 0; ix < statement_count; ix++){
                                Statement s = statements [ix];
 
-                               //
-                               // Warn if we detect unreachable code.
-                               //
-                               if (unreachable) {
-                                       if (s is EmptyStatement)
-                                               continue;
-
-                                       if (!ec.UnreachableReported && !(s is LabeledStatement) && !(s is SwitchLabel)) {
-                                               ec.Report.Warning (162, 2, s.loc, "Unreachable code detected");
-                                               ec.UnreachableReported = true;
-                                       }
-                               }
-
-                               //
-                               // Note that we're not using ResolveUnreachable() for unreachable
-                               // statements here.  ResolveUnreachable() creates a temporary
-                               // flow branching and kills it afterwards.  This leads to problems
-                               // if you have two unreachable statements where the first one
-                               // assigns a variable and the second one tries to access it.
-                               //
-
-                               if (!s.Resolve (ec)) {
+                               if (!s.Resolve (bc)) {
                                        ok = false;
-                                       if (!ec.IsInProbingMode)
+                                       if (!bc.IsInProbingMode)
                                                statements [ix] = new EmptyStatement (s.loc);
 
                                        continue;
                                }
+                       }
 
-                               if (unreachable && !(s is LabeledStatement) && !(s is SwitchLabel) && !(s is Block))
-                                       statements [ix] = new EmptyStatement (s.loc);
+                       bc.CurrentBlock = prev_block;
 
-                               unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable;
-                               if (unreachable) {
-                                       ec.IsUnreachable = true;
-                               } else if (ec.IsUnreachable)
-                                       ec.IsUnreachable = false;
-                       }
+                       flags |= Flags.Resolved;
+                       return ok;
+               }
 
-                       if (unreachable != prev_unreachable) {
-                               ec.IsUnreachable = prev_unreachable;
-                               ec.UnreachableReported = false;
+               protected override void DoEmit (EmitContext ec)
+               {
+                       for (int ix = 0; ix < statements.Count; ix++){
+                               statements [ix].Emit (ec);
                        }
+               }
 
-                       while (ec.CurrentBranching is FlowBranchingLabeled)
-                               ec.EndFlowBranching ();
-
-                       bool flow_unreachable = ec.EndFlowBranching ();
+               public override void Emit (EmitContext ec)
+               {
+                       if (scope_initializers != null)
+                               EmitScopeInitializers (ec);
 
-                       ec.CurrentBlock = prev_block;
+                       DoEmit (ec);
+               }
 
-                       if (flow_unreachable)
-                               flags |= Flags.HasRet;
+               protected void EmitScopeInitializers (EmitContext ec)
+               {
+                       foreach (Statement s in scope_initializers)
+                               s.Emit (ec);
+               }
 
-                       // If we're a non-static `struct' constructor which doesn't have an
-                       // initializer, then we must initialize all of the struct's fields.
-                       if (this == ParametersBlock.TopBlock && !ParametersBlock.TopBlock.IsThisAssigned (ec) && !flow_unreachable)
-                               ok = false;
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (scope_initializers != null) {
+                               foreach (var si in scope_initializers)
+                                       si.FlowAnalysis (fc);
+                       }
 
-                       flags |= Flags.Resolved;
-                       return ok;
+                       return DoFlowAnalysis (fc, 0);  
                }
 
-               public override bool ResolveUnreachable (BlockContext ec, bool warn)
+               bool DoFlowAnalysis (FlowAnalysisContext fc, int startIndex)
                {
-                       bool unreachable = false;
-                       if (warn && !ec.UnreachableReported) {
-                               ec.UnreachableReported = true;
-                               unreachable = true;
-                               ec.Report.Warning (162, 2, loc, "Unreachable code detected");
-                       }
+                       bool end_unreachable = !reachable;
+                       for (; startIndex < statements.Count; ++startIndex) {
+                               var s = statements[startIndex];
 
-                       var fb = ec.StartFlowBranching (FlowBranching.BranchingType.Block, loc);
-                       fb.CurrentUsageVector.IsUnreachable = true;
-                       bool ok = Resolve (ec);
-                       ec.KillFlowBranching ();
+                               end_unreachable = s.FlowAnalysis (fc);
+                               if (s.IsUnreachable) {
+                                       statements[startIndex] = new EmptyStatement (s.loc);
+                                       continue;
+                               }
 
-                       if (unreachable)
-                               ec.UnreachableReported = false;
+                               //
+                               // Statement end reachability is needed mostly due to goto support. Consider
+                               //
+                               // if (cond) {
+                               //    goto X;
+                               // } else {
+                               //    goto Y;
+                               // }
+                               // X:
+                               //
+                               // X label is reachable only via goto not as another statement after if. We need
+                               // this for flow-analysis only to carry variable info correctly.
+                               //
+                               if (end_unreachable) {
+                                       for (++startIndex; startIndex < statements.Count; ++startIndex) {
+                                               s = statements[startIndex];
+                                               if (s is SwitchLabel) {
+                                                       s.FlowAnalysis (fc);
+                                                       break;
+                                               }
 
-                       return ok;
-               }
-               
-               protected override void DoEmit (EmitContext ec)
-               {
-                       for (int ix = 0; ix < statements.Count; ix++){
-                               statements [ix].Emit (ec);
+                                               if (s.IsUnreachable) {
+                                                       s.FlowAnalysis (fc);
+                                                       statements[startIndex] = new EmptyStatement (s.loc);
+                                               }
+                                       }
+                               }
                        }
+
+                       //
+                       // The condition should be true unless there is forward jumping goto
+                       // 
+                       // if (this is ExplicitBlock && end_unreachable != Explicit.HasReachableClosingBrace)
+                       //      Debug.Fail ();
+
+                       return !Explicit.HasReachableClosingBrace;
                }
 
-               public override void Emit (EmitContext ec)
+               public void ScanGotoJump (Statement label)
                {
-                       if (scope_initializers != null)
-                               EmitScopeInitializers (ec);
+                       int i;
+                       for (i = 0; i < statements.Count; ++i) {
+                               if (statements[i] == label)
+                                       break;
+                       }
 
-                       DoEmit (ec);
+                       var rc = new Reachability ();
+                       for (++i; i < statements.Count; ++i) {
+                               var s = statements[i];
+                               rc = s.MarkReachable (rc);
+                               if (rc.IsUnreachable)
+                                       return;
+                       }
+
+                       flags |= Flags.ReachableEnd;
                }
 
-               protected void EmitScopeInitializers (EmitContext ec)
+               public void ScanGotoJump (Statement label, FlowAnalysisContext fc)
                {
-                       foreach (Statement s in scope_initializers)
-                               s.Emit (ec);
+                       int i;
+                       for (i = 0; i < statements.Count; ++i) {
+                               if (statements[i] == label)
+                                       break;
+                       }
+
+                       DoFlowAnalysis (fc, ++i);
                }
 
 #if DEBUG
                public override string ToString ()
                {
-                       return String.Format ("{0} ({1}:{2})", GetType (), ID, StartLocation);
+                       return String.Format ("{0}: ID={1} Clone={2} Location={3}", GetType (), ID, clone_id != 0, StartLocation);
                }
 #endif
 
@@ -2422,7 +3000,7 @@ namespace Mono.CSharp {
                {
                        Block target = (Block) t;
 #if DEBUG
-                       target.clone_id = clone_id_counter++;
+                       target.clone_id = ++clone_id_counter;
 #endif
 
                        clonectx.AddBlockMap (this, target);
@@ -2497,6 +3075,15 @@ namespace Mono.CSharp {
                        }
                }
 
+               public bool HasReachableClosingBrace {
+                   get {
+                       return (flags & Flags.ReachableEnd) != 0;
+                   }
+                       set {
+                               flags = value ? flags | Flags.ReachableEnd : flags & ~Flags.ReachableEnd;
+                       }
+               }
+
                public bool HasYield {
                        get {
                                return (flags & Flags.YieldBlock) != 0;
@@ -2551,7 +3138,8 @@ namespace Mono.CSharp {
                        if (Parent != null)
                                ec.EndScope ();
 
-                       if (ec.EmitAccurateDebugInfo && !HasUnreachableClosingBrace && !IsCompilerGenerated && ec.Mark (EndLocation)) {
+                       if (ec.EmitAccurateDebugInfo && HasReachableClosingBrace && !(this is ParametersBlock) &&
+                               !IsCompilerGenerated && ec.Mark (EndLocation)) {
                                ec.Emit (OpCodes.Nop);
                        }
                }
@@ -2744,6 +3332,16 @@ namespace Mono.CSharp {
                        }
                }
 
+               public void SetCatchBlock ()
+               {
+                       flags |= Flags.CatchBlock;
+               }
+
+               public void SetFinallyBlock ()
+               {
+                       flags |= Flags.FinallyBlock;
+               }
+
                public void WrapIntoDestructor (TryFinally tf, ExplicitBlock tryBlock)
                {
                        tryBlock.statements = statements;
@@ -2879,12 +3477,12 @@ namespace Mono.CSharp {
 
                protected ParametersCompiled parameters;
                protected ParameterInfo[] parameter_info;
-               bool resolved;
-               protected bool unreachable;
+               protected bool resolved;
                protected ToplevelBlock top_block;
                protected StateMachine state_machine;
+               protected Dictionary<string, object> labels;
 
-               public ParametersBlock (Block parent, ParametersCompiled parameters, Location start)
+               public ParametersBlock (Block parent, ParametersCompiled parameters, Location start, Flags flags = 0)
                        : base (parent, 0, start, start)
                {
                        if (parameters == null)
@@ -2893,7 +3491,7 @@ namespace Mono.CSharp {
                        this.parameters = parameters;
                        ParametersBlock = this;
 
-                       flags |= (parent.ParametersBlock.flags & (Flags.YieldBlock | Flags.AwaitBlock));
+                       this.flags |= flags | (parent.ParametersBlock.flags & (Flags.YieldBlock | Flags.AwaitBlock));
 
                        this.top_block = parent.ParametersBlock.top_block;
                        ProcessParameters ();
@@ -2920,9 +3518,10 @@ namespace Mono.CSharp {
                        this.scope_initializers = source.scope_initializers;
 
                        this.resolved = true;
-                       this.unreachable = source.unreachable;
+                       this.reachable = source.reachable;
                        this.am_storey = source.am_storey;
                        this.state_machine = source.state_machine;
+                       this.flags = source.flags & Flags.ReachableEnd;
 
                        ParametersBlock = this;
 
@@ -2984,29 +3583,69 @@ namespace Mono.CSharp {
 
                #endregion
 
-               // <summary>
-               //   Check whether all `out' parameters have been assigned.
-               // </summary>
-               public void CheckOutParameters (FlowBranching.UsageVector vector)
+               //
+               // Checks whether all `out' parameters have been assigned.
+               //
+               public void CheckControlExit (FlowAnalysisContext fc)
                {
-                       if (vector.IsUnreachable)
-                               return;
-
-                       int n = parameter_info == null ? 0 : parameter_info.Length;
+                       CheckControlExit (fc, fc.DefiniteAssignment);
+               }
 
-                       for (int i = 0; i < n; i++) {
-                               VariableInfo var = parameter_info[i].VariableInfo;
+               public virtual void CheckControlExit (FlowAnalysisContext fc, DefiniteAssignmentBitSet dat)
+               {
+                       if (parameter_info == null)
+                               return;
 
-                               if (var == null)
+                       foreach (var p in parameter_info) {
+                               if (p.VariableInfo == null)
                                        continue;
 
-                               if (vector.IsAssigned (var, false))
+                               if (p.VariableInfo.IsAssigned (dat))
                                        continue;
 
-                               var p = parameter_info[i].Parameter;
-                               TopBlock.Report.Error (177, p.Location,
+                               fc.Report.Error (177, p.Location,
                                        "The out parameter `{0}' must be assigned to before control leaves the current method",
-                                       p.Name);
+                                       p.Parameter.Name);
+                       }                                       
+               }
+
+               protected override void CloneTo (CloneContext clonectx, Statement t)
+               {
+                       base.CloneTo (clonectx, t);
+
+                       var target = (ParametersBlock) t;
+
+                       //
+                       // Clone label statements as well as they contain block reference
+                       //
+                       var pb = this;
+                       while (true) {
+                               if (pb.labels != null) {
+                                       target.labels = new Dictionary<string, object> ();
+
+                                       foreach (var entry in pb.labels) {
+                                               var list = entry.Value as List<LabeledStatement>;
+
+                                               if (list != null) {
+                                                       var list_clone = new List<LabeledStatement> ();
+                                                       foreach (var lentry in list) {
+                                                               list_clone.Add (RemapLabeledStatement (lentry, lentry.Block, clonectx.RemapBlockCopy (lentry.Block)));
+                                                       }
+
+                                                       target.labels.Add (entry.Key, list_clone);
+                                               } else {
+                                                       var labeled = (LabeledStatement) entry.Value;
+                                                       target.labels.Add (entry.Key, RemapLabeledStatement (labeled, labeled.Block, clonectx.RemapBlockCopy (labeled.Block)));
+                                               }
+                                       }
+
+                                       break;
+                               }
+
+                               if (pb.Parent == null)
+                                       break;
+
+                               pb = pb.Parent.ParametersBlock;
                        }
                }
 
@@ -3043,6 +3682,53 @@ namespace Mono.CSharp {
                        base.Emit (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var res = base.DoFlowAnalysis (fc);
+
+                       if (HasReachableClosingBrace)
+                               CheckControlExit (fc);
+
+                       return res;
+               }
+
+               public LabeledStatement GetLabel (string name, Block block)
+               {
+                       //
+                       // Cloned parameters blocks can have their own cloned version of top-level labels
+                       //
+                       if (labels == null) {
+                               if (Parent != null)
+                                       return Parent.ParametersBlock.GetLabel (name, block);
+
+                               return null;
+                       }
+
+                       object value;
+                       if (!labels.TryGetValue (name, out value)) {
+                               return null;
+                       }
+
+                       var label = value as LabeledStatement;
+                       Block b = block;
+                       if (label != null) {
+                               do {
+                                       if (label.Block == b)
+                                               return label;
+                                       b = b.Parent;
+                               } while (b != null);
+                       } else {
+                               List<LabeledStatement> list = (List<LabeledStatement>) value;
+                               for (int i = 0; i < list.Count; ++i) {
+                                       label = list[i];
+                                       if (label.Block == b)
+                                               return label;
+                               }
+                       }
+
+                       return null;
+               }
+
                public ParameterInfo GetParameterInfo (Parameter p)
                {
                        for (int i = 0; i < parameters.Count; ++i) {
@@ -3082,67 +3768,59 @@ namespace Mono.CSharp {
                        }
                }
 
-               public bool Resolve (FlowBranching parent, BlockContext rc, IMethodData md)
+               static LabeledStatement RemapLabeledStatement (LabeledStatement stmt, Block src, Block dst)
+               {
+                       var src_stmts = src.Statements;
+                       for (int i = 0; i < src_stmts.Count; ++i) {
+                               if (src_stmts[i] == stmt)
+                                       return (LabeledStatement) dst.Statements[i];
+                       }
+
+                       throw new InternalErrorException ("Should never be reached");
+               }
+
+               public override bool Resolve (BlockContext bc)
                {
+                       // TODO: if ((flags & Flags.Resolved) != 0)
+
                        if (resolved)
                                return true;
 
                        resolved = true;
 
-                       if (rc.HasSet (ResolveContext.Options.ExpressionTreeConversion))
+                       if (bc.HasSet (ResolveContext.Options.ExpressionTreeConversion))
                                flags |= Flags.IsExpressionTree;
 
                        try {
-                               PrepareAssignmentAnalysis (rc);
-
-                               using (rc.With (ResolveContext.Options.DoFlowAnalysis, true)) {
-                                       FlowBranchingToplevel top_level = rc.StartFlowBranching (this, parent);
+                               PrepareAssignmentAnalysis (bc);
 
-                                       if (!Resolve (rc))
-                                               return false;
+                               if (!base.Resolve (bc))
+                                       return false;
 
-                                       unreachable = top_level.End ();
-                               }
                        } catch (Exception e) {
-                               if (e is CompletionResult || rc.Report.IsDisabled || e is FatalException || rc.Report.Printer is NullReportPrinter)
+                               if (e is CompletionResult || bc.Report.IsDisabled || e is FatalException || bc.Report.Printer is NullReportPrinter)
                                        throw;
 
-                               if (rc.CurrentBlock != null) {
-                                       rc.Report.Error (584, rc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message);
+                               if (bc.CurrentBlock != null) {
+                                       bc.Report.Error (584, bc.CurrentBlock.StartLocation, "Internal compiler error: {0}", e.Message);
                                } else {
-                                       rc.Report.Error (587, "Internal compiler error: {0}", e.Message);
+                                       bc.Report.Error (587, "Internal compiler error: {0}", e.Message);
                                }
 
-                               if (rc.Module.Compiler.Settings.DebugFlags > 0)
+                               if (bc.Module.Compiler.Settings.DebugFlags > 0)
                                        throw;
                        }
 
-                       if (rc.ReturnType.Kind != MemberKind.Void && !unreachable) {
-                               if (rc.CurrentAnonymousMethod == null) {
-                                       // FIXME: Missing FlowAnalysis for generated iterator MoveNext method
-                                       if (md is StateMachineMethod) {
-                                               unreachable = true;
-                                       } else {
-                                               rc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
-                                               return false;
-                                       }
-                               } else {
-                                       //
-                                       // If an asynchronous body of F is either an expression classified as nothing, or a 
-                                       // statement block where no return statements have expressions, the inferred return type is Task
-                                       //
-                                       if (IsAsync) {
-                                               var am = rc.CurrentAnonymousMethod as AnonymousMethodBody;
-                                               if (am != null && am.ReturnTypeInference != null && !am.ReturnTypeInference.HasBounds (0)) {
-                                                       am.ReturnTypeInference = null;
-                                                       am.ReturnType = rc.Module.PredefinedTypes.Task.TypeSpec;
-                                                       return true;
-                                               }
-                                       }
-
-                                       rc.Report.Error (1643, rc.CurrentAnonymousMethod.Location, "Not all code paths return a value in anonymous method of type `{0}'",
-                                                         rc.CurrentAnonymousMethod.GetSignatureForError ());
-                                       return false;
+                       //
+                       // If an asynchronous body of F is either an expression classified as nothing, or a 
+                       // statement block where no return statements have expressions, the inferred return type is Task
+                       //
+                       if (IsAsync) {
+                               var am = bc.CurrentAnonymousMethod as AnonymousMethodBody;
+                               if (am != null && am.ReturnTypeInference != null && !am.ReturnTypeInference.HasBounds (0)) {
+                                       am.ReturnTypeInference = null;
+                                       am.ReturnType = bc.Module.PredefinedTypes.Task.TypeSpec;
+                                       return true;
                                }
                        }
 
@@ -3169,9 +3847,8 @@ namespace Mono.CSharp {
                        state_machine = stateMachine;
                        iterator.SetStateMachine (stateMachine);
 
-                       var tlb = new ToplevelBlock (host.Compiler, Parameters, Location.Null);
+                       var tlb = new ToplevelBlock (host.Compiler, Parameters, Location.Null, Flags.CompilerGenerated);
                        tlb.Original = this;
-                       tlb.IsCompilerGenerated = true;
                        tlb.state_machine = stateMachine;
                        tlb.AddStatement (new Return (iterator, iterator.Location));
                        return tlb;
@@ -3216,16 +3893,15 @@ namespace Mono.CSharp {
                        state_machine = stateMachine;
                        initializer.SetStateMachine (stateMachine);
 
+                       const Flags flags = Flags.CompilerGenerated;
+
                        var b = this is ToplevelBlock ?
-                               new ToplevelBlock (host.Compiler, Parameters, Location.Null) :
-                               new ParametersBlock (Parent, parameters, Location.Null) {
-                                       IsAsync = true,
-                               };
+                               new ToplevelBlock (host.Compiler, Parameters, Location.Null, flags) :
+                               new ParametersBlock (Parent, parameters, Location.Null, flags | Flags.HasAsyncModifier);
 
                        b.Original = this;
-                       b.IsCompilerGenerated = true;
                        b.state_machine = stateMachine;
-                       b.AddStatement (new StatementExpression (initializer));
+                       b.AddStatement (new AsyncInitializerStatement (initializer));
                        return b;
                }
        }
@@ -3238,7 +3914,6 @@ namespace Mono.CSharp {
                LocalVariable this_variable;
                CompilerContext compiler;
                Dictionary<string, object> names;
-               Dictionary<string, object> labels;
 
                List<ExplicitBlock> this_references;
 
@@ -3247,12 +3922,12 @@ namespace Mono.CSharp {
                {
                }
 
-               public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start)
+               public ToplevelBlock (CompilerContext ctx, ParametersCompiled parameters, Location start, Flags flags = 0)
                        : base (parameters, start)
                {
                        this.compiler = ctx;
+                       this.flags = flags;
                        top_block = this;
-                       flags |= Flags.HasRet;
 
                        ProcessParameters ();
                }
@@ -3268,7 +3943,6 @@ namespace Mono.CSharp {
                {
                        this.compiler = source.TopBlock.compiler;
                        top_block = this;
-                       flags |= Flags.HasRet;
                }
 
                public bool IsIterator {
@@ -3530,33 +4204,6 @@ namespace Mono.CSharp {
                        return false;
                }
 
-               public LabeledStatement GetLabel (string name, Block block)
-               {
-                       if (labels == null)
-                               return null;
-
-                       object value;
-                       if (!labels.TryGetValue (name, out value)) {
-                               return null;
-                       }
-
-                       var label = value as LabeledStatement;
-                       Block b = block;
-                       if (label != null) {
-                               if (label.Block == b.Original)
-                                       return label;
-                       } else {
-                               List<LabeledStatement> list = (List<LabeledStatement>) value;
-                               for (int i = 0; i < list.Count; ++i) {
-                                       label = list[i];
-                                       if (label.Block == b.Original)
-                                               return label;
-                               }
-                       }
-                               
-                       return null;
-               }
-
                // <summary>
                //   This is used by non-static `struct' constructors which do not have an
                //   initializer - in this case, the constructor must initialize all of the
@@ -3574,9 +4221,16 @@ namespace Mono.CSharp {
                        this_variable.PrepareAssignmentAnalysis (bc);
                }
 
-               public bool IsThisAssigned (BlockContext ec)
+               public override void CheckControlExit (FlowAnalysisContext fc, DefiniteAssignmentBitSet dat)
                {
-                       return this_variable == null || this_variable.IsThisAssigned (ec, this);
+                       //
+                       // If we're a non-static struct constructor which doesn't have an
+                       // initializer, then we must initialize all of the struct's fields.
+                       //
+                       if (this_variable != null)
+                               this_variable.IsThisAssigned (fc, this);
+
+                       base.CheckControlExit (fc, dat);
                }
 
                public override void Emit (EmitContext ec)
@@ -3605,7 +4259,7 @@ namespace Mono.CSharp {
                        // As a workaround, we're always creating a return label in
                        // this case.
                        //
-                       if (ec.HasReturnLabel || !unreachable) {
+                       if (ec.HasReturnLabel || HasReachableClosingBrace) {
                                if (ec.HasReturnLabel)
                                        ec.MarkLabel (ec.ReturnLabel);
 
@@ -3622,12 +4276,44 @@ namespace Mono.CSharp {
                                throw new InternalErrorException (e, StartLocation);
                        }
                }
+
+               public bool Resolve (BlockContext bc, IMethodData md)
+               {
+                       if (resolved)
+                               return true;
+
+                       var errors = bc.Report.Errors;
+
+                       base.Resolve (bc);
+
+                       if (bc.Report.Errors > errors)
+                               return false;
+
+                       MarkReachable (new Reachability ());
+
+                       if (HasReachableClosingBrace && bc.ReturnType.Kind != MemberKind.Void) {
+                               // TODO: var md = bc.CurrentMemberDefinition;
+                               bc.Report.Error (161, md.Location, "`{0}': not all code paths return a value", md.GetSignatureForError ());
+                       }
+
+                       if ((flags & Flags.NoFlowAnalysis) != 0)
+                               return true;
+
+                       var fc = new FlowAnalysisContext (bc.Module.Compiler, this, bc.AssignmentInfoOffset);
+                       try {
+                               FlowAnalysis (fc);
+                       } catch (Exception e) {
+                               throw new InternalErrorException (e, StartLocation);
+                       }
+
+                       return true;
+               }
        }
        
        public class SwitchLabel : Statement
        {
-               Expression label;
                Constant converted;
+               Expression label;
 
                Label? il_label;
 
@@ -3663,7 +4349,7 @@ namespace Mono.CSharp {
                                return converted;
                        }
                        set {
-                               converted = value;
+                               converted = value; 
                        }
                }
 
@@ -3683,21 +4369,28 @@ namespace Mono.CSharp {
                        ec.MarkLabel (GetILLabel (ec));
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (!SectionStart)
+                               return false;
+
+                       fc.DefiniteAssignment = new DefiniteAssignmentBitSet (fc.SwitchInitialDefinitiveAssignment);
+                       return false;
+               }
+
                public override bool Resolve (BlockContext bc)
                {
                        if (ResolveAndReduce (bc))
                                bc.Switch.RegisterLabel (bc, this);
 
-                       bc.CurrentBranching.CurrentUsageVector.ResetBarrier ();
-
-                       return base.Resolve (bc);
+                       return true;
                }
 
                //
                // Resolves the expression, reduces it to a literal if possible
                // and then converts it to the requested type.
                //
-               bool ResolveAndReduce (ResolveContext rc)
+               bool ResolveAndReduce (BlockContext rc)
                {
                        if (IsDefault)
                                return true;
@@ -3717,14 +4410,8 @@ namespace Mono.CSharp {
 
                public void Error_AlreadyOccurs (ResolveContext ec, SwitchLabel collision_with)
                {
-                       string label;
-                       if (converted == null)
-                               label = "default";
-                       else
-                               label = converted.GetValueAsLiteral ();
-                       
                        ec.Report.SymbolRelatedToPreviousError (collision_with.loc, null);
-                       ec.Report.Error (152, loc, "The label `case {0}:' already occurs in this switch statement", label);
+                       ec.Report.Error (152, loc, "The label `{0}' already occurs in this switch statement", GetSignatureForError ());
                }
 
                protected override void CloneTo (CloneContext clonectx, Statement target)
@@ -3738,9 +4425,20 @@ namespace Mono.CSharp {
                {
                        return visitor.Visit (this);
                }
+
+               public string GetSignatureForError ()
+               {
+                       string label;
+                       if (converted == null)
+                               label = "default";
+                       else
+                               label = converted.GetValueAsLiteral ();
+
+                       return string.Format ("case {0}:", label);
+               }
        }
 
-       public class Switch : Statement
+       public class Switch : LoopStatement
        {
                // structure used to hold blocks of keys while calculating table switch
                sealed class LabelsRange : IComparable<LabelsRange>
@@ -3806,12 +4504,44 @@ namespace Mono.CSharp {
                                throw new NotImplementedException ();
                        }
 
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               return false;
+                       }
+
                        protected override void DoEmit (EmitContext ec)
                        {
                                body.EmitDispatch (ec);
                        }
                }
 
+               class MissingBreak : Statement
+               {
+                       SwitchLabel label;
+
+                       public MissingBreak (SwitchLabel sl)
+                       {
+                               this.label = sl;
+                               this.loc = sl.loc;
+                       }
+
+                       protected override void DoEmit (EmitContext ec)
+                       {
+                       }
+
+                       protected override void CloneTo (CloneContext clonectx, Statement target)
+                       {
+                       }
+
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               fc.Report.Error (163, loc, "Control cannot fall through from one case label `{0}' to another",
+                                       label.GetSignatureForError ());
+
+                               return true;
+                       }
+               }
+
                public Expression Expr;
 
                //
@@ -3822,6 +4552,7 @@ namespace Mono.CSharp {
                List<SwitchLabel> case_labels;
 
                List<Tuple<GotoCase, Constant>> goto_cases;
+               List<DefiniteAssignmentBitSet> end_reachable_das;
 
                /// <summary>
                ///   The governing switch type
@@ -3838,6 +4569,7 @@ namespace Mono.CSharp {
                ExpressionStatement string_dictionary;
                FieldExpr switch_cache_field;
                ExplicitBlock block;
+               bool end_reachable;
 
                //
                // Nullable Types support
@@ -3845,12 +4577,15 @@ namespace Mono.CSharp {
                Nullable.Unwrap unwrap;
 
                public Switch (Expression e, ExplicitBlock block, Location l)
+                       : base (block)
                {
                        Expr = e;
                        this.block = block;
                        loc = l;
                }
 
+               public SwitchLabel ActiveLabel { get; set; }
+
                public ExplicitBlock Block {
                        get {
                                return block;
@@ -3869,6 +4604,12 @@ namespace Mono.CSharp {
                        }
                }
 
+               public List<SwitchLabel> RegisteredLabels {
+                       get {
+                               return case_labels;
+                       }
+               }
+
                //
                // Determines the governing type for a switch.  The returned
                // expression might be the expression from the switch, or an
@@ -3942,7 +4683,7 @@ namespace Mono.CSharp {
                        };
                }
 
-               public void RegisterLabel (ResolveContext rc, SwitchLabel sl)
+               public void RegisterLabel (BlockContext rc, SwitchLabel sl)
                {
                        case_labels.Add (sl);
 
@@ -4106,7 +4847,7 @@ namespace Mono.CSharp {
                        }
                }
                
-               SwitchLabel FindLabel (Constant value)
+               public SwitchLabel FindLabel (Constant value)
                {
                        SwitchLabel sl = null;
 
@@ -4131,6 +4872,29 @@ namespace Mono.CSharp {
                        return sl;
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       Expr.FlowAnalysis (fc);
+
+                       var prev_switch = fc.SwitchInitialDefinitiveAssignment;
+                       var InitialDefinitiveAssignment = fc.DefiniteAssignment;
+                       fc.SwitchInitialDefinitiveAssignment = InitialDefinitiveAssignment;
+
+                       block.FlowAnalysis (fc);
+
+                       fc.SwitchInitialDefinitiveAssignment = prev_switch;
+
+                       if (end_reachable_das != null) {
+                               var sections_das = DefiniteAssignmentBitSet.And (end_reachable_das);
+                               InitialDefinitiveAssignment |= sections_das;
+                               end_reachable_das = null;
+                       }
+
+                       fc.DefiniteAssignment = InitialDefinitiveAssignment;
+
+                       return case_default != null && !end_reachable;
+               }
+
                public override bool Resolve (BlockContext ec)
                {
                        Expr = Expr.Resolve (ec);
@@ -4199,33 +4963,23 @@ namespace Mono.CSharp {
 
                        Switch old_switch = ec.Switch;
                        ec.Switch = this;
-                       ec.Switch.SwitchType = SwitchType;
+                       var parent_los = ec.EnclosingLoopOrSwitch;
+                       ec.EnclosingLoopOrSwitch = this;
 
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Switch, loc);
-
-                       ec.CurrentBranching.CurrentUsageVector.Goto ();
-
-                       var ok = block.Resolve (ec);
-
-                       if (case_default == null)
-                               ec.CurrentBranching.CreateSibling (null, FlowBranching.SiblingType.SwitchSection);
-
-                       if (ec.IsUnreachable)
-                               ec.KillFlowBranching ();
-                       else
-                               ec.EndFlowBranching ();
+                       var ok = Statement.Resolve (ec);
 
+                       ec.EnclosingLoopOrSwitch = parent_los;
                        ec.Switch = old_switch;
 
                        //
                        // Check if all goto cases are valid. Needs to be done after switch
-                       // is resolved becuase goto can jump forward in the scope.
+                       // is resolved because goto can jump forward in the scope.
                        //
                        if (goto_cases != null) {
                                foreach (var gc in goto_cases) {
                                        if (gc.Item1 == null) {
                                                if (DefaultLabel == null) {
-                                                       FlowBranchingBlock.Error_UnknownLabel (loc, "default", ec.Report);
+                                                       Goto.Error_UnknownLabel (ec, "default", loc);
                                                }
 
                                                continue;
@@ -4233,17 +4987,13 @@ namespace Mono.CSharp {
 
                                        var sl = FindLabel (gc.Item2);
                                        if (sl == null) {
-                                               FlowBranchingBlock.Error_UnknownLabel (loc, "case " + gc.Item2.GetValueAsLiteral (), ec.Report);
+                                               Goto.Error_UnknownLabel (ec, "case " + gc.Item2.GetValueAsLiteral (), loc);
                                        } else {
                                                gc.Item1.Label = sl;
                                        }
                                }
                        }
 
-                       if (constant != null) {
-                               ResolveUnreachableSections (ec, constant);
-                       }
-
                        if (!ok)
                                return false;
 
@@ -4274,6 +5024,87 @@ namespace Mono.CSharp {
                        return true;
                }
 
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (rc.IsUnreachable)
+                               return rc;
+
+                       base.MarkReachable (rc);
+
+                       if (block.Statements.Count == 0)
+                               return rc;
+
+                       SwitchLabel constant_label = null;
+                       var constant = new_expr as Constant;
+
+                       if (constant != null) {
+                               constant_label = FindLabel (constant) ?? case_default;
+                               if (constant_label == null) {
+                                       block.Statements.RemoveAt (0);
+                                       return rc;
+                               }
+                       }
+
+                       var section_rc = new Reachability ();
+                       SwitchLabel prev_label = null;
+
+                       for (int i = 0; i < block.Statements.Count; ++i) {
+                               var s = block.Statements[i];
+                               var sl = s as SwitchLabel;
+
+                               if (sl != null && sl.SectionStart) {
+                                       //
+                                       // Section is marked already via constant switch or goto case
+                                       //
+                                       if (!sl.IsUnreachable) {
+                                               section_rc = new Reachability ();
+                                               continue;
+                                       }
+
+                                       if (section_rc.IsUnreachable) {
+                                               section_rc = new Reachability ();
+                                       } else {
+                                               if (prev_label != null) {
+                                                       sl.SectionStart = false;
+                                                       s = new MissingBreak (prev_label);
+                                                       s.MarkReachable (rc);
+                                                       block.Statements.Insert (i - 1, s);
+                                                       ++i;
+                                               }
+                                       }
+
+                                       prev_label = sl;
+
+                                       if (constant_label != null && constant_label != sl)
+                                               section_rc = Reachability.CreateUnreachable ();
+                               }
+
+                               section_rc = s.MarkReachable (section_rc);
+                       }
+
+                       if (!section_rc.IsUnreachable && prev_label != null) {
+                               prev_label.SectionStart = false;
+                               var s = new MissingBreak (prev_label);
+                               s.MarkReachable (rc);
+                               block.Statements.Add (s);
+                       }
+
+                       //
+                       // Reachability can affect parent only when all possible paths are handled but
+                       // we still need to run reachability check on switch body to check for fall-through
+                       //
+                       if (case_default == null && constant_label == null)
+                               return rc;
+
+                       //
+                       // We have at least one local exit from the switch
+                       //
+                       if (end_reachable)
+                               return rc;
+
+                       return Reachability.CreateUnreachable ();
+               }
+
                public void RegisterGotoCase (GotoCase gotoCase, Constant value)
                {
                        if (goto_cases == null)
@@ -4340,40 +5171,6 @@ namespace Mono.CSharp {
                        string_dictionary = new SimpleAssign (switch_cache_field, initializer.Resolve (ec));
                }
 
-               void ResolveUnreachableSections (BlockContext bc, Constant value)
-               {
-                       var constant_label = FindLabel (value) ?? case_default;
-
-                       bool found = false;
-                       bool unreachable_reported = false;
-                       for (int i = 0; i < block.Statements.Count; ++i) {
-                               var s = block.Statements[i];
-
-                               if (s is SwitchLabel) {
-                                       if (unreachable_reported) {
-                                               found = unreachable_reported = false;
-                                       }
-
-                                       found |= s == constant_label;
-                                       continue;
-                               }
-
-                               if (found) {
-                                       unreachable_reported = true;
-                                       continue;
-                               }
-
-                               if (!unreachable_reported) {
-                                       unreachable_reported = true;
-                                       if (!bc.IsUnreachable) {
-                                               bc.Report.Warning (162, 2, s.loc, "Unreachable code detected");
-                                       }
-                               }
-
-                               block.Statements[i] = new EmptyStatement (s.loc);
-                       }
-               }
-
                void DoEmitStringSwitch (EmitContext ec)
                {
                        Label l_initialized = ec.DefineLabel ();
@@ -4479,8 +5276,23 @@ namespace Mono.CSharp {
                {
                        if (value == null) {
                                //
-                               // Constant switch, we already done the work
+                               // Constant switch, we've already done the work if there is only 1 label
+                               // referenced
                                //
+                               int reachable = 0;
+                               foreach (var sl in case_labels) {
+                                       if (sl.IsUnreachable)
+                                               continue;
+
+                                       if (reachable++ > 0) {
+                                               var constant = (Constant) new_expr;
+                                               var constant_label = FindLabel (constant) ?? case_default;
+
+                                               ec.Emit (OpCodes.Br, constant_label.GetILLabel (ec));
+                                               break;
+                                       }
+                               }
+
                                return;
                        }
 
@@ -4495,9 +5307,6 @@ namespace Mono.CSharp {
 
                protected override void DoEmit (EmitContext ec)
                {
-                       // Workaround broken flow-analysis
-                       block.HasUnreachableClosingBrace = true;
-
                        //
                        // Setup the codegen context
                        //
@@ -4546,16 +5355,32 @@ namespace Mono.CSharp {
                        Switch target = (Switch) t;
 
                        target.Expr = Expr.Clone (clonectx);
-                       target.block = (ExplicitBlock) block.Clone (clonectx);
+                       target.Statement = target.block = (ExplicitBlock) block.Clone (clonectx);
                }
                
                public override object Accept (StructuralVisitor visitor)
                {
                        return visitor.Visit (this);
                }
+
+               public override void AddEndDefiniteAssignment (FlowAnalysisContext fc)
+               {
+                       if (case_default == null)
+                               return;
+
+                       if (end_reachable_das == null)
+                               end_reachable_das = new List<DefiniteAssignmentBitSet> ();
+
+                       end_reachable_das.Add (fc.DefiniteAssignment);
+               }
+
+               public override void SetEndReachable ()
+               {
+                       end_reachable = true;
+               }
        }
 
-       // A place where execution can restart in an iterator
+       // A place where execution can restart in a state machine
        public abstract class ResumableStatement : Statement
        {
                bool prepared;
@@ -4715,8 +5540,32 @@ namespace Mono.CSharp {
                        ec.EndExceptionBlock ();
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var res = stmt.FlowAnalysis (fc);
+                       parent = null;
+                       return res;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Statement.MarkReachable (rc);
+               }
+
                public override bool Resolve (BlockContext bc)
                {
+                       bool ok;
+
+                       parent = bc.CurrentTryBlock;
+                       bc.CurrentTryBlock = this;
+
+                       using (bc.Set (ResolveContext.Options.TryScope)) {
+                               ok = stmt.Resolve (bc);
+                       }
+
+                       bc.CurrentTryBlock = parent;
+
                        //
                        // Finally block inside iterator is called from MoveNext and
                        // Dispose methods that means we need to lift the block into
@@ -4730,7 +5579,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       return base.Resolve (bc);
+                       return base.Resolve (bc) && ok;
                }
        }
 
@@ -4739,11 +5588,9 @@ namespace Mono.CSharp {
        //
        public abstract class ExceptionStatement : ResumableStatement
        {
-#if !STATIC
-               bool code_follows;
-#endif
                protected List<ResumableStatement> resume_points;
                protected int first_resume_pc;
+               protected ExceptionStatement parent;
 
                protected ExceptionStatement (Location loc)
                {
@@ -4778,26 +5625,18 @@ namespace Mono.CSharp {
                        }
                }
 
-               public void SomeCodeFollows ()
+               public virtual int AddResumePoint (ResumableStatement stmt, int pc, StateMachineInitializer stateMachine)
                {
-#if !STATIC
-                       code_follows = true;
-#endif
-               }
+                       if (parent != null) {
+                               // TODO: MOVE to virtual TryCatch
+                               var tc = this as TryCatch;
+                               var s = tc != null && tc.IsTryCatchFinally ? stmt : this;
 
-               public override bool Resolve (BlockContext ec)
-               {
-#if !STATIC
-                       // System.Reflection.Emit automatically emits a 'leave' at the end of a try clause
-                       // So, ensure there's some IL code after this statement.
-                       if (!code_follows && resume_points == null && ec.CurrentBranching.CurrentUsageVector.IsUnreachable)
-                               ec.NeedReturnLabel ();
-#endif
-                       return true;
-               }
+                               pc = parent.AddResumePoint (s, pc, stateMachine);
+                       } else {
+                               pc = stateMachine.AddResumePoint (this);
+                       }
 
-               public void AddResumePoint (ResumableStatement stmt, int pc)
-               {
                        if (resume_points == null) {
                                resume_points = new List<ResumableStatement> ();
                                first_resume_pc = pc;
@@ -4807,8 +5646,8 @@ namespace Mono.CSharp {
                                throw new InternalErrorException ("missed an intervening AddResumePoint?");
 
                        resume_points.Add (stmt);
+                       return pc;
                }
-
        }
 
        public class Lock : TryFinallyBlock
@@ -4871,17 +5710,13 @@ namespace Mono.CSharp {
                        }
 
                        using (ec.Set (ResolveContext.Options.LockScope)) {
-                               ec.StartFlowBranching (this);
-                               Statement.Resolve (ec);
-                               ec.EndFlowBranching ();
+                               base.Resolve (ec);
                        }
 
                        if (lv != null) {
                                lv.IsLockedByStatement = locked;
                        }
 
-                       base.Resolve (ec);
-
                        return true;
                }
                
@@ -4992,6 +5827,17 @@ namespace Mono.CSharp {
                                Block.Emit (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return Block.FlowAnalysis (fc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Block.MarkReachable (rc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Unchecked target = (Unchecked) t;
@@ -5027,6 +5873,17 @@ namespace Mono.CSharp {
                                Block.Emit (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return Block.FlowAnalysis (fc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Block.MarkReachable (rc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Checked target = (Checked) t;
@@ -5064,6 +5921,17 @@ namespace Mono.CSharp {
                        Block.Emit (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       return Block.FlowAnalysis (fc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+                       return Block.MarkReachable (rc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Unsafe target = (Unsafe) t;
@@ -5093,6 +5961,11 @@ namespace Mono.CSharp {
                        }
 
                        public abstract void EmitExit (EmitContext ec);
+
+                       public override void FlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               expr.FlowAnalysis (fc);
+                       }
                }
 
                class ExpressionEmitter : Emitter {
@@ -5306,19 +6179,20 @@ namespace Mono.CSharp {
 
                #endregion
 
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
-                       using (ec.Set (ResolveContext.Options.FixedInitializerScope)) {
-                               if (!decl.Resolve (ec))
+                       using (bc.Set (ResolveContext.Options.FixedInitializerScope)) {
+                               if (!decl.Resolve (bc))
                                        return false;
                        }
 
-                       ec.StartFlowBranching (FlowBranching.BranchingType.Conditional, loc);
-                       bool ok = statement.Resolve (ec);
-                       bool flow_unreachable = ec.EndFlowBranching ();
-                       has_ret = flow_unreachable;
+                       return statement.Resolve (bc);
+               }
 
-                       return ok;
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       decl.FlowAnalysis (fc);
+                       return statement.FlowAnalysis (fc);
                }
                
                protected override void DoEmit (EmitContext ec)
@@ -5348,6 +6222,19 @@ namespace Mono.CSharp {
                        }
                }
 
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       decl.MarkReachable (rc);
+
+                       rc = statement.MarkReachable (rc);
+
+                       // TODO: What if there is local exit?
+                       has_ret = rc.IsUnreachable;
+                       return rc;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Fixed target = (Fixed) t;
@@ -5364,13 +6251,13 @@ namespace Mono.CSharp {
 
        public class Catch : Statement
        {
-               Block block;
+               ExplicitBlock block;
                LocalVariable li;
                FullNamedExpression type_expr;
                CompilerAssign assign;
                TypeSpec type;
                
-               public Catch (Block block, Location loc)
+               public Catch (ExplicitBlock block, Location loc)
                {
                        this.block = block;
                        this.loc = loc;
@@ -5378,7 +6265,7 @@ namespace Mono.CSharp {
 
                #region Properties
 
-               public Block Block {
+               public ExplicitBlock Block {
                        get {
                                return block;
                        }
@@ -5447,7 +6334,7 @@ namespace Mono.CSharp {
 
                public override bool Resolve (BlockContext ec)
                {
-                       using (ec.With (ResolveContext.Options.CatchScope, true)) {
+                       using (ec.Set (ResolveContext.Options.CatchScope)) {
                                if (type_expr != null) {
                                        type = type_expr.ResolveAsType (ec);
                                        if (type == null)
@@ -5472,10 +6359,27 @@ namespace Mono.CSharp {
                                        }
                                }
 
+                               Block.SetCatchBlock ();
                                return Block.Resolve (ec);
                        }
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       if (li != null) {
+                               fc.SetVariableAssigned (li.VariableInfo, true);
+                       }
+
+                       return block.FlowAnalysis (fc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       return block.MarkReachable (rc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Catch target = (Catch) t;
@@ -5483,47 +6387,44 @@ namespace Mono.CSharp {
                        if (type_expr != null)
                                target.type_expr = (FullNamedExpression) type_expr.Clone (clonectx);
 
-                       target.block = clonectx.LookupBlock (block);
+                       target.block = (ExplicitBlock) clonectx.LookupBlock (block);
                }
        }
 
        public class TryFinally : TryFinallyBlock
        {
-               Block fini;
+               ExplicitBlock fini;
+               List<DefiniteAssignmentBitSet> try_exit_dat;
 
-               public TryFinally (Statement stmt, Block fini, Location loc)
+               public TryFinally (Statement stmt, ExplicitBlock fini, Location loc)
                         : base (stmt, loc)
                {
                        this.fini = fini;
                }
 
-               public Block Finallyblock {
+               public ExplicitBlock FinallyBlock {
                        get {
                                return fini;
                        }
                }
 
-               public override bool Resolve (BlockContext ec)
+               public void RegisterForControlExitCheck (DefiniteAssignmentBitSet vector)
                {
-                       bool ok = true;
+                       if (try_exit_dat == null)
+                               try_exit_dat = new List<DefiniteAssignmentBitSet> ();
 
-                       ec.StartFlowBranching (this);
-
-                       if (!stmt.Resolve (ec))
-                               ok = false;
+                       try_exit_dat.Add (vector);
+               }
 
-                       if (ok)
-                               ec.CurrentBranching.CreateSibling (fini, FlowBranching.SiblingType.Finally);
+               public override bool Resolve (BlockContext bc)
+               {
+                       bool ok = base.Resolve (bc);
 
-                       using (ec.With (ResolveContext.Options.FinallyScope, true)) {
-                               if (!fini.Resolve (ec))
-                                       ok = false;
+                       fini.SetFinallyBlock ();
+                       using (bc.Set (ResolveContext.Options.FinallyScope)) {
+                               ok &= fini.Resolve (bc);
                        }
 
-                       ec.EndFlowBranching ();
-
-                       ok &= base.Resolve (ec);
-
                        return ok;
                }
 
@@ -5537,13 +6438,54 @@ namespace Mono.CSharp {
                        fini.Emit (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var da = fc.BranchDefiniteAssignment ();
+
+                       var tf = fc.TryFinally;
+                       fc.TryFinally = this;
+
+                       var res_stmt = Statement.FlowAnalysis (fc);
+
+                       fc.TryFinally = tf;
+
+                       var try_da = fc.DefiniteAssignment;
+                       fc.DefiniteAssignment = da;
+
+                       var res_fin = fini.FlowAnalysis (fc);
+
+                       if (try_exit_dat != null) {
+                               //
+                               // try block has global exit but we need to run definite assignment check
+                               // for parameter block out parameter after finally block because it's always
+                               // executed before exit
+                               //
+                               foreach (var try_da_part in try_exit_dat)
+                                       fc.ParametersBlock.CheckControlExit (fc, fc.DefiniteAssignment | try_da_part);
+
+                               try_exit_dat = null;
+                       }
+
+                       fc.DefiniteAssignment |= try_da;
+                       return res_stmt | res_fin;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       //
+                       // Mark finally block first for any exit statement in try block
+                       // to know whether the code which follows finally is reachable
+                       //
+                       return fini.MarkReachable (rc) | base.MarkReachable (rc);
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        TryFinally target = (TryFinally) t;
 
                        target.stmt = stmt.Clone (clonectx);
                        if (fini != null)
-                               target.fini = clonectx.LookupBlock (fini);
+                               target.fini = (ExplicitBlock) clonectx.LookupBlock (fini);
                }
                
                public override object Accept (StructuralVisitor visitor)
@@ -5578,23 +6520,28 @@ namespace Mono.CSharp {
                        }
                }
 
-               public override bool Resolve (BlockContext ec)
+               public override bool Resolve (BlockContext bc)
                {
-                       bool ok = true;
+                       bool ok;
 
-                       ec.StartFlowBranching (this);
+                       using (bc.Set (ResolveContext.Options.TryScope)) {
+                               parent = bc.CurrentTryBlock;
 
-                       if (!Block.Resolve (ec))
-                               ok = false;
+                               if (IsTryCatchFinally) {
+                                       ok = Block.Resolve (bc);
+                               } else {
+                                       using (bc.Set (ResolveContext.Options.TryWithCatchScope)) {
+                                               bc.CurrentTryBlock = this;
+                                               ok = Block.Resolve (bc);
+                                               bc.CurrentTryBlock = parent;
+                                       }
+                               }
+                       }
 
                        for (int i = 0; i < clauses.Count; ++i) {
                                var c = clauses[i];
-                               ec.CurrentBranching.CreateSibling (c.Block, FlowBranching.SiblingType.Catch);
 
-                               if (!c.Resolve (ec)) {
-                                       ok = false;
-                                       continue;
-                               }
+                               ok &= c.Resolve (bc);
 
                                TypeSpec resolved_type = c.CatchType;
                                for (int ii = 0; ii < clauses.Count; ++ii) {
@@ -5605,13 +6552,13 @@ namespace Mono.CSharp {
                                                if (resolved_type.BuiltinType != BuiltinTypeSpec.Type.Exception)
                                                        continue;
 
-                                               if (!ec.Module.DeclaringAssembly.WrapNonExceptionThrows)
+                                               if (!bc.Module.DeclaringAssembly.WrapNonExceptionThrows)
                                                        continue;
 
-                                               if (!ec.Module.PredefinedAttributes.RuntimeCompatibility.IsDefined)
+                                               if (!bc.Module.PredefinedAttributes.RuntimeCompatibility.IsDefined)
                                                        continue;
 
-                                               ec.Report.Warning (1058, 1, c.loc,
+                                               bc.Report.Warning (1058, 1, c.loc,
                                                        "A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a `System.Runtime.CompilerServices.RuntimeWrappedException'");
 
                                                continue;
@@ -5625,7 +6572,7 @@ namespace Mono.CSharp {
                                                continue;
 
                                        if (resolved_type == ct || TypeSpec.IsBaseClass (resolved_type, ct, true)) {
-                                               ec.Report.Error (160, c.loc,
+                                               bc.Report.Error (160, c.loc,
                                                        "A previous catch clause already catches all exceptions of this or a super type `{0}'",
                                                        ct.GetSignatureForError ());
                                                ok = false;
@@ -5633,9 +6580,7 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       ec.EndFlowBranching ();
-
-                       return base.Resolve (ec) && ok;
+                       return base.Resolve (bc) && ok;
                }
 
                protected sealed override void DoEmit (EmitContext ec)
@@ -5652,6 +6597,45 @@ namespace Mono.CSharp {
                                ec.EndExceptionBlock ();
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       var start_fc = fc.BranchDefiniteAssignment ();
+                       var res = Block.FlowAnalysis (fc);
+
+                       DefiniteAssignmentBitSet try_fc = res ? null : fc.DefiniteAssignment;
+
+                       foreach (var c in clauses) {
+                               fc.DefiniteAssignment = new DefiniteAssignmentBitSet (start_fc);
+                               if (!c.FlowAnalysis (fc)) {
+                                       if (try_fc == null)
+                                               try_fc = fc.DefiniteAssignment;
+                                       else
+                                               try_fc &= fc.DefiniteAssignment;
+
+                                       res = false;
+                               }
+                       }
+
+                       fc.DefiniteAssignment = try_fc ?? start_fc;
+                       parent = null;
+                       return res;
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       if (rc.IsUnreachable)
+                               return rc;
+
+                       base.MarkReachable (rc);
+
+                       var tc_rc = Block.MarkReachable (rc);
+
+                       foreach (var c in clauses)
+                               tc_rc &= c.MarkReachable (rc);
+
+                       return tc_rc;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        TryCatch target = (TryCatch) t;
@@ -5881,6 +6865,18 @@ namespace Mono.CSharp {
                        decl.EmitDispose (ec);
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       decl.FlowAnalysis (fc);
+                       return stmt.FlowAnalysis (fc);
+               }
+
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       decl.MarkReachable (rc);
+                       return base.MarkReachable (rc);
+               }
+
                public override bool Resolve (BlockContext ec)
                {
                        VariableReference vr;
@@ -5909,17 +6905,11 @@ namespace Mono.CSharp {
                                }
                        }
 
-                       ec.StartFlowBranching (this);
-
-                       stmt.Resolve (ec);
-
-                       ec.EndFlowBranching ();
+                       base.Resolve (ec);
 
                        if (vr != null)
                                vr.IsLockedByStatement = vr_locked;
 
-                       base.Resolve (ec);
-
                        return true;
                }
 
@@ -5940,7 +6930,7 @@ namespace Mono.CSharp {
        /// <summary>
        ///   Implementation of the foreach C# statement
        /// </summary>
-       public class Foreach : Statement
+       public class Foreach : LoopStatement
        {
                abstract class IteratorStatement : Statement
                {
@@ -5965,6 +6955,11 @@ namespace Mono.CSharp {
 
                                base.Emit (ec);
                        }
+
+                       protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+                       {
+                               throw new NotImplementedException ();
+                       }
                }
 
                sealed class ArrayForeach : IteratorStatement
@@ -6046,22 +7041,7 @@ namespace Mono.CSharp {
 
                                for_each.body.AddScopeStatement (new StatementExpression (new CompilerAssign (variable_ref, access, Location.Null), for_each.type.Location));
 
-                               bool ok = true;
-
-                               ec.StartFlowBranching (FlowBranching.BranchingType.Loop, loc);
-                               ec.CurrentBranching.CreateSibling ();
-
-                               ec.StartFlowBranching (FlowBranching.BranchingType.Embedded, loc);
-                               if (!for_each.body.Resolve (ec))
-                                       ok = false;
-                               ec.EndFlowBranching ();
-
-                               // There's no direct control flow from the end of the embedded statement to the end of the loop
-                               ec.CurrentBranching.CurrentUsageVector.Goto ();
-
-                               ec.EndFlowBranching ();
-
-                               return ok;
+                               return for_each.body.Resolve (ec);
                        }
 
                        protected override void DoEmit (EmitContext ec)
@@ -6431,15 +7411,14 @@ namespace Mono.CSharp {
                Expression type;
                LocalVariable variable;
                Expression expr;
-               Statement statement;
                Block body;
 
                public Foreach (Expression type, LocalVariable var, Expression expr, Statement stmt, Block body, Location l)
+                       : base (stmt)
                {
                        this.type = type;
                        this.variable = var;
                        this.expr = expr;
-                       this.statement = stmt;
                        this.body = body;
                        loc = l;
                }
@@ -6448,10 +7427,6 @@ namespace Mono.CSharp {
                        get { return expr; }
                }
 
-               public Statement Statement {
-                       get { return statement; }
-               }
-
                public Expression TypeExpression {
                        get { return type; }
                }
@@ -6460,6 +7435,15 @@ namespace Mono.CSharp {
                        get { return variable; }
                }
 
+               public override Reachability MarkReachable (Reachability rc)
+               {
+                       base.MarkReachable (rc);
+
+                       body.MarkReachable (rc);
+
+                       return rc;
+               }
+
                public override bool Resolve (BlockContext ec)
                {
                        expr = expr.Resolve (ec);
@@ -6471,12 +7455,12 @@ namespace Mono.CSharp {
                                return false;
                        }
 
-                       body.AddStatement (statement);
+                       body.AddStatement (Statement);
 
                        if (expr.Type.BuiltinType == BuiltinTypeSpec.Type.String) {
-                               statement = new ArrayForeach (this, 1);
+                               Statement = new ArrayForeach (this, 1);
                        } else if (expr.Type is ArrayContainer) {
-                               statement = new ArrayForeach (this, ((ArrayContainer) expr.Type).Rank);
+                               Statement = new ArrayForeach (this, ((ArrayContainer) expr.Type).Rank);
                        } else {
                                if (expr.eclass == ExprClass.MethodGroup || expr is AnonymousMethodExpression) {
                                        ec.Report.Error (446, expr.Location, "Foreach statement cannot operate on a `{0}'",
@@ -6484,10 +7468,11 @@ namespace Mono.CSharp {
                                        return false;
                                }
 
-                               statement = new CollectionForeach (this, variable, expr);
+                               Statement = new CollectionForeach (this, variable, expr);
                        }
 
-                       return statement.Resolve (ec);
+                       base.Resolve (ec);
+                       return true;
                }
 
                protected override void DoEmit (EmitContext ec)
@@ -6496,20 +7481,30 @@ namespace Mono.CSharp {
                        ec.LoopBegin = ec.DefineLabel ();
                        ec.LoopEnd = ec.DefineLabel ();
 
-                       if (!(statement is Block))
+                       if (!(Statement is Block))
                                ec.BeginCompilerScope ();
 
                        variable.CreateBuilder (ec);
 
-                       statement.Emit (ec);
+                       Statement.Emit (ec);
 
-                       if (!(statement is Block))
+                       if (!(Statement is Block))
                                ec.EndScope ();
 
                        ec.LoopBegin = old_begin;
                        ec.LoopEnd = old_end;
                }
 
+               protected override bool DoFlowAnalysis (FlowAnalysisContext fc)
+               {
+                       expr.FlowAnalysis (fc);
+
+                       var da = fc.BranchDefiniteAssignment ();
+                       body.FlowAnalysis (fc);
+                       fc.DefiniteAssignment = da;
+                       return false;
+               }
+
                protected override void CloneTo (CloneContext clonectx, Statement t)
                {
                        Foreach target = (Foreach) t;
@@ -6517,7 +7512,7 @@ namespace Mono.CSharp {
                        target.type = type.Clone (clonectx);
                        target.expr = expr.Clone (clonectx);
                        target.body = (Block) body.Clone (clonectx);
-                       target.statement = statement.Clone (clonectx);
+                       target.Statement = Statement.Clone (clonectx);
                }
                
                public override object Accept (StructuralVisitor visitor)
index 10874fecc65e0333a0b325b7c7e2aa425ab4b086..edaa4dde69233c9613f88d26b2ff13088b824e95 100644 (file)
@@ -1416,6 +1416,7 @@ namespace Mono.CSharp
                bool IsPartial { get; }
                bool IsComImport { get; }
                bool IsTypeForwarder { get; }
+               bool IsCyclicTypeForwarder { get; }
                int TypeParametersCount { get; }
                TypeParameterSpec[] TypeParameters { get; }
 
@@ -1487,6 +1488,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                public override string Name {
                        get {
                                return name;
@@ -1617,6 +1624,12 @@ namespace Mono.CSharp
                        }
                }
 
+               bool ITypeDefinition.IsCyclicTypeForwarder {
+                       get {
+                               return false;
+                       }
+               }
+
                public override string Name {
                        get {
                                throw new NotSupportedException ();
diff --git a/mcs/tests/dtest-059.cs b/mcs/tests/dtest-059.cs
new file mode 100644 (file)
index 0000000..b57b8d2
--- /dev/null
@@ -0,0 +1,22 @@
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               new C<int> ().Test ();
+       }
+}
+
+class C<T>
+{
+       public void Test ()
+       {
+               dynamic d = null;
+
+               int v;
+               int.TryParse (d, out v);
+
+               int.TryParse (d, out v);
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/gtest-600.cs b/mcs/tests/gtest-600.cs
new file mode 100644 (file)
index 0000000..54b6c29
--- /dev/null
@@ -0,0 +1,34 @@
+class A { }
+class B { }
+
+interface ICharlie<T> { }
+
+class Delta : ICharlie<A>, ICharlie<B>
+{
+       static void Test<U> (ICharlie<U> icu, U u)
+       {
+       }
+
+       public void World<U> (U u, IFoo<U> foo)
+       {
+       }
+
+       public void Test (Foo foo)
+       {
+               World ("Canada", foo);
+       }
+
+       static void Main ()
+       {
+               Test (new Delta (), new A ());
+               Test (new Delta (), new B ());
+       }
+}
+
+public interface IFoo<T>
+{
+}
+
+public class Foo : IFoo<int>, IFoo<string>
+{
+}
index 8098cfd5bcabaa322a1a92d3491e5722859ee6c7..163e78d135caac1dba6b75fb7836b8a5b3886bde 100644 (file)
@@ -594,4 +594,48 @@ public class X
 
                return service;
        }
+
+       public void test41 ()
+       {
+               int y, x = 3;
+               int z;
+               while (true) {
+                       if (x > 3) {
+                               y = 3;
+                               goto end;
+                       } else {
+                               z = 3;
+                       }
+
+                       break;
+               end:
+                       z = y;
+               }
+
+               Console.WriteLine (z);
+       }
+       
+       public void test42 (int arg)
+       {
+               bool x;
+               for (; ; ) {
+                       x = false;
+                       if (arg > 0) {
+                               x = true;
+                               switch (arg) {
+                               case 1:
+                               case 2:
+                                       continue;
+                               default:
+                                       break;
+                               }
+                               break;
+                       } else {
+                               x = false;
+                               break;
+                       }
+               }
+
+               Console.WriteLine (x);
+       }
 }
index 35ca796e054812cb65e8e784fbb6ac37c38c3486..8b8bd6bf2e8a7290d2d665e6a7dd7722437b2f8b 100644 (file)
@@ -1,3 +1,5 @@
+using System;
+
 class Foo {
        public static int Main ()
        {
@@ -5,9 +7,17 @@ class Foo {
                        f ();
                        return 1;
                } catch {
-                       return 0;
                }
+
+               try {
+                       f2 ();
+                       return 2;
+               } catch (ApplicationException) {
+               }
+
+               return 0;
        }
+
        static void f ()
        {
                try {
@@ -20,4 +30,15 @@ class Foo {
        skip:
                ;
        }
+
+       static void f2 ()
+       {
+               try {
+                       goto FinallyExit;
+               } finally {
+                       throw new ApplicationException ();
+               }
+       FinallyExit:
+               Console.WriteLine ("Too late");
+       }
 }
index 9df2a493acda4d8ed41f70d56e5428c542011269..1f49f63c7650ecb05e0d0e870d1ac32d6b1ffd08 100644 (file)
@@ -3,6 +3,17 @@
 public class TestCase
 {
        public static int Main ()
+       {
+               if (Test1 () != 0)
+                       return 1;
+
+               if (Test2 () != 0)
+                       return 2;
+
+               return 0;
+       }
+
+       static int Test1 ()
        {
                int i = 0;
                {
@@ -21,4 +32,46 @@ public class TestCase
                        
                return 0;
        }
+
+       static int Test2 ()
+       {
+               int i = 0;
+
+               while (true) {
+                       {
+                               goto A;
+                               A:
+                                       i += 3;
+                               break;
+                       }
+               }
+
+               if (i != 3)
+                       return 1;
+
+               return 0;
+       }
+
+       static int Test3 ()
+       {
+               int i = 0;
+
+               do {
+                       {
+                               goto A;
+                               A:
+                                       i += 3;
+                               goto X;
+                               X:
+                               break;
+                       }
+#pragma warning disable 162, 429
+               } while (i > 0);
+#pragma warning restore 162, 429
+               
+               if (i != 3)
+                       return 1;
+
+               return 0;
+       }
 }
diff --git a/mcs/tests/test-872.cs b/mcs/tests/test-872.cs
new file mode 100644 (file)
index 0000000..e501d33
--- /dev/null
@@ -0,0 +1,25 @@
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               int x = 1;
+               switch (x) {
+               case 1:
+                       try {
+                               goto case 6;
+                       } catch {
+                       }
+                       break;
+               case 6:
+                       try {
+                               goto default;
+                       } catch {
+                       }
+                       break;
+               default:
+                       break;
+               }
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-874.cs b/mcs/tests/test-874.cs
new file mode 100644 (file)
index 0000000..b8f52f0
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+
+class X
+{
+       public static void Main ()
+       {
+               int a;
+               goto X;
+       A:
+               Console.WriteLine (a);
+               goto Y;
+       X:
+               a = 1;
+               goto A;
+       Y:
+               return;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-875-2-lib.il b/mcs/tests/test-875-2-lib.il
new file mode 100644 (file)
index 0000000..7c45836
--- /dev/null
@@ -0,0 +1,21 @@
+.assembly extern mscorlib
+{
+}
+
+.assembly extern 'test-875-lib-missing'
+{
+}
+
+.assembly 'test-875-2-lib'
+{
+  .hash algorithm 0x00008004
+  .ver 0:0:0:0
+}
+
+.module 'test-875-2-lib'
+
+.class extern forwarder N.Lib
+{
+  .assembly extern 'test-875-lib-missing'
+}
+
diff --git a/mcs/tests/test-875-lib.cs b/mcs/tests/test-875-lib.cs
new file mode 100644 (file)
index 0000000..2121951
--- /dev/null
@@ -0,0 +1,8 @@
+// Compiler options: -t:library
+
+namespace N
+{
+       public class Lib
+       {
+       }
+}
diff --git a/mcs/tests/test-875.cs b/mcs/tests/test-875.cs
new file mode 100644 (file)
index 0000000..b4ebd43
--- /dev/null
@@ -0,0 +1,11 @@
+// Compiler options: -r:test-875-lib.dll -r:test-875-2-lib.dll
+
+using N;
+
+public class Test: Lib
+{
+       public static void Main ()
+       {
+               new Test ();
+       }
+}
diff --git a/mcs/tests/test-876.cs b/mcs/tests/test-876.cs
new file mode 100644 (file)
index 0000000..f7e373e
--- /dev/null
@@ -0,0 +1,112 @@
+using System;
+
+class T
+{
+       public static int Main ()
+       {
+               Test1 ();
+               Test2 ();
+               Test3 (0, 1);
+               Test4 ();
+               Test5 ();
+               
+               switch (1) {
+               case 1:
+                       return 0;
+               default:
+                       break;
+               }
+       }
+
+       static void Test1 ()
+       {
+               int g = 9;
+       A:
+               switch (g) {
+               case 4:
+                       return;
+               case 5:
+                       goto A;
+               }
+
+               switch (g) {
+               case 9:
+                       break;
+               }
+
+               return;
+       }
+       
+       static void Test2 ()
+       {
+               int a,b;
+               int g = 9;
+               if (g > 0) {
+                       a = 1;
+                       goto X;
+               } else {
+                       b = 2;
+                       goto Y;
+               }
+
+       X:
+               Console.WriteLine (a);
+               return;
+       Y:
+               Console.WriteLine (b);
+               return;
+       }
+       
+       static uint Test3 (int self, uint data)
+       {
+               uint rid;
+               switch (self) {
+               case 0:
+                       rid = 2;
+                       switch (data & 3) {
+                       case 0:
+                               goto ret;
+                       default:
+                               goto exit;
+                       }
+               default:
+                       goto exit;
+               }
+       ret:
+               return rid;
+       exit:
+               return 0;
+       }
+
+       static void Test4 ()
+       {
+               bool v;
+               try {
+                       throw new NotImplementedException ();
+               } catch (System.Exception) {
+                       v = false;
+               }
+               
+               Console.WriteLine (v);
+       }
+
+       static void Test5 ()
+       {
+               int i = 8;
+               switch (10) {
+               case 5:
+                       if (i != 10)
+                               throw new ApplicationException ();
+                       
+                       Console.WriteLine (5);
+                       break;
+               case 10:
+                       i = 10;
+                       Console.WriteLine (10);
+                       goto default;
+               default:
+                       Console.WriteLine ("default");
+                       goto case 5;
+               }
+       }
+}
diff --git a/mcs/tests/test-877.cs b/mcs/tests/test-877.cs
new file mode 100644 (file)
index 0000000..b372dfc
--- /dev/null
@@ -0,0 +1,18 @@
+using System;
+
+struct S
+{
+       string value;
+
+       public S (int arg)
+       {
+               throw new ApplicationException ();
+       }
+}
+
+public class A
+{
+       public static void Main ()
+       {
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-878.cs b/mcs/tests/test-878.cs
new file mode 100644 (file)
index 0000000..659b77a
--- /dev/null
@@ -0,0 +1,34 @@
+using System;
+
+public class Tests
+{
+       public static int Main ()
+       {
+               return 0;
+       }
+
+       void Test1 ()
+       {
+               int a;
+               if (true) {
+                       a = 0;
+               } else {
+                       a = 1;
+               }
+
+               Console.WriteLine (a);
+       }
+
+       void Test2 ()
+       {
+               int a;
+               if (false) {
+                       a = 0;
+               } else {
+                       a = 1;
+               }
+
+               Console.WriteLine (a);
+       }
+}
+
diff --git a/mcs/tests/test-879.cs b/mcs/tests/test-879.cs
new file mode 100644 (file)
index 0000000..4d6aa33
--- /dev/null
@@ -0,0 +1,28 @@
+struct AStruct
+{
+       public object foo;
+
+       public AStruct (int i)
+               : this ()
+       {
+       }
+}
+
+public class Tests
+{
+       public static int Main ()
+       {
+               for (int i = 0; i < 100; ++i) {
+                       AStruct a;
+
+                       a = new AStruct (5);
+                       if (a.foo != null)
+                               return 1;
+
+                       a.foo = i + 1;
+               }
+
+               System.Console.WriteLine ("ok");
+               return 0;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-880.cs b/mcs/tests/test-880.cs
new file mode 100644 (file)
index 0000000..6449d56
--- /dev/null
@@ -0,0 +1,78 @@
+using System;
+
+public class A
+{
+       public static void Main ()
+       {
+       }
+
+       static void Test1 ()
+       {
+               int a;
+               bool r = false;
+
+               if (r && (a = 1) > 0 && r) {
+                       System.Console.WriteLine (a);
+               }
+       }
+
+       static void Test2 ()
+       {
+               int a;
+               var res = (a = 1) > 0 || Call (a);
+       }
+
+       static void Test3 ()
+       {
+               int a;
+               if ((a = 1) > 0 || Call (a))
+                       return;
+       }
+
+       static void Test4 ()
+       {
+               int version1;
+               bool r = false;
+               if (r || !OutCall (out version1) || version1 == 0 || version1 == -1)
+               {
+                       throw new ArgumentException();
+               }
+       }
+
+       static void Test5 ()
+       {
+               bool r = false;
+               int t1;
+               if (Foo (r ? Call (1) : Call (4), OutCall (out t1)))
+                       Console.WriteLine (t1);
+       }
+
+       static void Test6 ()
+       {
+               int b = 0;
+               var res = b != 0 && b.ToString () != null;
+       }
+
+       static bool Test7 ()
+       {
+               int f = 1;
+               int g;
+        return f > 1 && OutCall (out g) && g > 1;
+       }
+
+       static bool OutCall (out int arg)
+       {
+               arg = 1;
+               return false;
+       }
+       
+       static bool Call (int arg)
+       {
+               return false;
+       }
+
+       static bool Foo (params object[] arg)
+       {
+               return false;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-881.cs b/mcs/tests/test-881.cs
new file mode 100644 (file)
index 0000000..08f4946
--- /dev/null
@@ -0,0 +1,26 @@
+using System;
+
+namespace A
+{
+       class XAttribute : Attribute { }
+}
+
+namespace B
+{
+       class XAttribute : Attribute { }
+}
+
+namespace C
+{
+       using A;
+       using B;
+       using X = A.XAttribute;
+
+       [X]
+       class Test 
+       {
+               public static void Main ()
+               {
+               }
+       }
+}
diff --git a/mcs/tests/test-882.cs b/mcs/tests/test-882.cs
new file mode 100644 (file)
index 0000000..67200e0
--- /dev/null
@@ -0,0 +1,72 @@
+using System;
+
+public class MyUInt32
+{
+       public uint x;
+
+       public MyUInt32 (uint x)
+       {
+               this.x = x;
+       }
+
+       public static implicit operator uint (MyUInt32 v)
+       {
+               return v.x;
+       }
+
+       public static implicit operator long (MyUInt32 v)
+       {
+               throw new ApplicationException ();
+       }
+
+       public static implicit operator MyUInt32 (uint v)
+       {
+               return new MyUInt32 (v);
+       }
+
+       public static implicit operator MyUInt32 (long v)
+       {
+               throw new ApplicationException ();
+       }
+}
+
+class Test
+{
+       static MyUInt32 test1 (MyUInt32 x)
+       {
+               x = x + 1;
+               return x;
+       }
+
+       static MyUInt32 test2 (MyUInt32 x)
+       {
+               x++;
+               return x;
+       }
+
+       static MyUInt32 test3 (MyUInt32 x)
+       {
+               ++x;
+               return x;
+       }
+
+       public static int Main ()
+       {
+               var m = new MyUInt32 (2);
+               m = test1 (m);
+               if (m.x != 3)
+                       return 1;
+
+               m = new MyUInt32 (2);
+               m = test2 (m);
+               if (m.x != 3)
+                       return 2;
+
+               m = new MyUInt32 (3);
+               m = test3 (m);
+               if (m.x != 4)
+                       return 3;
+
+               return 0;
+       }
+}
\ No newline at end of file
index 734db7e0909036d42e9c18b50abf824afa395200..5d8767dd617c02a3bc6f6e6025aa0f09a7d2dc45 100644 (file)
@@ -7,7 +7,6 @@ class Program
        {
                public void M ()
                {
-                       Console.WriteLine ("called");
                }
        }
 
diff --git a/mcs/tests/test-async-53.cs b/mcs/tests/test-async-53.cs
new file mode 100644 (file)
index 0000000..3ffee8c
--- /dev/null
@@ -0,0 +1,27 @@
+using System;
+
+class Y
+{
+}
+
+class X
+{
+       public event Action<int, string> E;
+
+       void Foo ()
+       {
+               var nc = new Y ();
+
+               E += async (arg1, arg2) => {
+                       nc = null;
+               };
+
+               E (1, "h");
+       }
+
+       public static void Main ()
+       {
+               var x = new X ();
+               x.Foo ();
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-async-54.cs b/mcs/tests/test-async-54.cs
new file mode 100644 (file)
index 0000000..ab10233
--- /dev/null
@@ -0,0 +1,41 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+
+class Test
+{
+       public static int Main ()
+       {
+               int res;
+               res = TestMethod (new TaskCanceledException ()).Result;
+               if (res != 0)
+                       return 10 * res;
+
+               res = TestMethod (new OperationCanceledException ("my message")).Result;
+               if (res != 0)
+                       return 20 * res;
+
+               return 0;
+       }
+
+       async static Task<int> TestMethod (Exception ex)
+       {
+               try {
+                       await Foo (ex);
+               } catch (OperationCanceledException e) {
+                       if (e == ex)
+                               return 0;
+
+                       return 1;
+               }
+
+               return 2;
+       }
+
+
+       async static Task Foo (Exception e)
+       {
+               await Task.Delay (1);
+               throw e;
+       }
+}
\ No newline at end of file
diff --git a/mcs/tests/test-xml-068-ref.xml b/mcs/tests/test-xml-068-ref.xml
new file mode 100644 (file)
index 0000000..480a34d
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<doc>
+    <assembly>
+        <name>test-xml-068</name>
+    </assembly>
+    <members>
+        <member name="M:X.Test">
+            <summary>
+            Test summary
+            </summary>
+            <see cref="!:#sometext" />
+        </member>
+    </members>
+</doc>
diff --git a/mcs/tests/test-xml-068.cs b/mcs/tests/test-xml-068.cs
new file mode 100644 (file)
index 0000000..0ca6157
--- /dev/null
@@ -0,0 +1,16 @@
+// Compiler options: -doc:xml-068.xml
+
+class X
+{
+       /// <summary>
+       /// Test summary
+       /// </summary>
+       /// <see cref="#sometext"/>
+       static void Test ()
+       {
+       }
+
+       public static void Main ()
+       {
+       }
+}
\ No newline at end of file
index 44afaf1727b51498aeb65172dc8ae60b732aba28..d33697cfe09353956ae448b037cdc0eb66a35e5c 100644 (file)
         <size>26</size>\r
       </method>\r
       <method name="Void .ctor(Int32)" attrs="6278">\r
-        <size>9</size>\r
+        <size>16</size>\r
       </method>\r
     </type>\r
     <type name="MyTypeExplicit">\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="dtest-059.cs">\r
+    <type name="X">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>12</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="C`1[T]">\r
+      <method name="Void Test()" attrs="134">\r
+        <size>238</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="C`1+&lt;Test&gt;c__DynamicSite0+Container0[T]">\r
+      <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Type, System.Object, Int32 ByRef)" attrs="454">\r
+        <size>0</size>\r
+      </method>\r
+      <method name="Void .ctor(Object, IntPtr)" attrs="6278">\r
+        <size>0</size>\r
+      </method>\r
+    </type>\r
+    <type name="C`1+&lt;Test&gt;c__DynamicSite0+Container1[T]">\r
+      <method name="Void Invoke(System.Runtime.CompilerServices.CallSite, System.Type, System.Object, Int32 ByRef)" attrs="454">\r
+        <size>0</size>\r
+      </method>\r
+      <method name="Void .ctor(Object, IntPtr)" attrs="6278">\r
+        <size>0</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="dtest-anontype-01.cs">\r
     <type name="C">\r
       <method name="Void Main()" attrs="150">\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="gtest-600.cs">\r
+    <type name="A">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="B">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="Delta">\r
+      <method name="Void Test[U](ICharlie`1[U], U)" attrs="145">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void World[U](U, IFoo`1[U])" attrs="134">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void Test(Foo)" attrs="134">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Void Main()" attrs="145">\r
+        <size>32</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="Foo">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="gtest-anontype-01.cs">\r
     <type name="Test">\r
       <method name="Int32 Main()" attrs="150">\r
         <size>8</size>\r
       </method>\r
       <method name="Void .ctor(Object)" attrs="6278">\r
-        <size>9</size>\r
+        <size>16</size>\r
       </method>\r
     </type>\r
     <type name="C">\r
         <size>26</size>\r
       </method>\r
       <method name="Void .ctor(Int32)" attrs="6278">\r
-        <size>9</size>\r
+        <size>16</size>\r
       </method>\r
     </type>\r
     <type name="MyTypeExplicit">\r
         <size>10</size>\r
       </method>\r
       <method name="Int32 test40(Int32)" attrs="145">\r
-        <size>27</size>\r
+        <size>20</size>\r
       </method>\r
       <method name="Void .ctor()" attrs="6278">\r
         <size>7</size>\r
       </method>\r
+      <method name="Void test41()" attrs="134">\r
+        <size>44</size>\r
+      </method>\r
+      <method name="Void test42(Int32)" attrs="134">\r
+        <size>73</size>\r
+      </method>\r
     </type>\r
   </test>\r
   <test name="test-155.cs">\r
   <test name="test-519.cs">\r
     <type name="Foo">\r
       <method name="Int32 Main()" attrs="150">\r
-        <size>25</size>\r
+        <size>52</size>\r
       </method>\r
       <method name="Void f()" attrs="145">\r
-        <size>21</size>\r
+        <size>23</size>\r
       </method>\r
       <method name="Void .ctor()" attrs="6278">\r
         <size>7</size>\r
       </method>\r
+      <method name="Void f2()" attrs="145">\r
+        <size>16</size>\r
+      </method>\r
     </type>\r
   </test>\r
   <test name="test-52.cs">\r
   <test name="test-545.cs">\r
     <type name="Dingus">\r
       <method name="Void .ctor(Int32)" attrs="6278">\r
-        <size>2</size>\r
+        <size>9</size>\r
       </method>\r
     </type>\r
     <type name="X">\r
   <test name="test-579.cs">\r
     <type name="TestCase">\r
       <method name="Int32 Main()" attrs="150">\r
-        <size>49</size>\r
+        <size>44</size>\r
       </method>\r
       <method name="Void .ctor()" attrs="6278">\r
         <size>7</size>\r
       </method>\r
+      <method name="Int32 Test1()" attrs="145">\r
+        <size>49</size>\r
+      </method>\r
+      <method name="Int32 Test2()" attrs="145">\r
+        <size>48</size>\r
+      </method>\r
+      <method name="Int32 Test3()" attrs="145">\r
+        <size>47</size>\r
+      </method>\r
     </type>\r
   </test>\r
   <test name="test-58.cs">\r
   <test name="test-634.cs">\r
     <type name="Test">\r
       <method name="Void TestFunc()" attrs="150">\r
-        <size>7</size>\r
+        <size>13</size>\r
       </method>\r
       <method name="Void Main(System.String[])" attrs="150">\r
         <size>7</size>\r
         <size>0</size>\r
       </method>\r
     </type>\r
+    <type name="Test+&lt;TestFunc&gt;c__AnonStorey0">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
   </test>\r
   <test name="test-635.cs">\r
     <type name="ShortCircuitFold">\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-872.cs">\r
+    <type name="X">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>66</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-873.cs">\r
     <type name="Program">\r
       <method name="Int32 Main()" attrs="145">\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-874.cs">\r
+    <type name="X">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>30</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-875.cs">\r
+    <type name="Test">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>8</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-876.cs">\r
+    <type name="T">\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>39</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+      <method name="Void Test1()" attrs="145">\r
+        <size>57</size>\r
+      </method>\r
+      <method name="Void Test2()" attrs="145">\r
+        <size>50</size>\r
+      </method>\r
+      <method name="UInt32 Test3(Int32, UInt32)" attrs="145">\r
+        <size>60</size>\r
+      </method>\r
+      <method name="Void Test4()" attrs="145">\r
+        <size>25</size>\r
+      </method>\r
+      <method name="Void Test5()" attrs="145">\r
+        <size>65</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-877.cs">\r
+    <type name="S">\r
+      <method name="Void .ctor(Int32)" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="A">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-878.cs">\r
+    <type name="Tests">\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>10</size>\r
+      </method>\r
+      <method name="Void Test1()" attrs="129">\r
+        <size>12</size>\r
+      </method>\r
+      <method name="Void Test2()" attrs="129">\r
+        <size>12</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-879.cs">\r
+    <type name="AStruct">\r
+      <method name="Void .ctor(Int32)" attrs="6278">\r
+        <size>9</size>\r
+      </method>\r
+    </type>\r
+    <type name="Tests">\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>83</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-88.cs">\r
     <type name="X">\r
       <method name="Void f(System.String)" attrs="145">\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-880.cs">\r
+    <type name="A">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void Test1()" attrs="145">\r
+        <size>33</size>\r
+      </method>\r
+      <method name="Void Test2()" attrs="145">\r
+        <size>21</size>\r
+      </method>\r
+      <method name="Void Test3()" attrs="145">\r
+        <size>27</size>\r
+      </method>\r
+      <method name="Void Test4()" attrs="145">\r
+        <size>42</size>\r
+      </method>\r
+      <method name="Void Test5()" attrs="145">\r
+        <size>72</size>\r
+      </method>\r
+      <method name="Void Test6()" attrs="145">\r
+        <size>33</size>\r
+      </method>\r
+      <method name="Boolean Test7()" attrs="145">\r
+        <size>37</size>\r
+      </method>\r
+      <method name="Boolean OutCall(Int32 ByRef)" attrs="145">\r
+        <size>13</size>\r
+      </method>\r
+      <method name="Boolean Call(Int32)" attrs="145">\r
+        <size>10</size>\r
+      </method>\r
+      <method name="Boolean Foo(System.Object[])" attrs="145">\r
+        <size>10</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-881.cs">\r
+    <type name="A.XAttribute">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="B.XAttribute">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="C.Test">\r
+      <method name="Void Main()" attrs="150">\r
+        <size>2</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-882.cs">\r
+    <type name="MyUInt32">\r
+      <method name="UInt32 op_Implicit(MyUInt32)" attrs="2198">\r
+        <size>15</size>\r
+      </method>\r
+      <method name="Int64 op_Implicit(MyUInt32)" attrs="2198">\r
+        <size>7</size>\r
+      </method>\r
+      <method name="MyUInt32 op_Implicit(UInt32)" attrs="2198">\r
+        <size>15</size>\r
+      </method>\r
+      <method name="MyUInt32 op_Implicit(Int64)" attrs="2198">\r
+        <size>7</size>\r
+      </method>\r
+      <method name="Void .ctor(UInt32)" attrs="6278">\r
+        <size>15</size>\r
+      </method>\r
+    </type>\r
+    <type name="Test">\r
+      <method name="MyUInt32 test1(MyUInt32)" attrs="145">\r
+        <size>25</size>\r
+      </method>\r
+      <method name="MyUInt32 test2(MyUInt32)" attrs="145">\r
+        <size>25</size>\r
+      </method>\r
+      <method name="MyUInt32 test3(MyUInt32)" attrs="145">\r
+        <size>25</size>\r
+      </method>\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>109</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-89.cs">\r
     <type name="X">\r
       <method name="X F(Int32)" attrs="145">\r
     </type>\r
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async0">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>226</size>\r
+        <size>225</size>\r
       </method>\r
     </type>\r
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async2">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>226</size>\r
+        <size>225</size>\r
       </method>\r
     </type>\r
     <type name="Program+&lt;Main&gt;c__AnonStorey1+&lt;Main&gt;c__async3">\r
     </type>\r
     <type name="AsyncTypeInference+&lt;Main&gt;c__async8">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>157</size>\r
+        <size>156</size>\r
       </method>\r
     </type>\r
     <type name="AsyncTypeInference+&lt;Main&gt;c__asyncB">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>38</size>\r
+        <size>37</size>\r
       </method>\r
     </type>\r
     <type name="AsyncTypeInference+&lt;Main&gt;c__async2">\r
         <size>9</size>\r
       </method>\r
       <method name="Void .ctor(Int32, String)" attrs="6278">\r
-        <size>9</size>\r
+        <size>16</size>\r
       </method>\r
     </type>\r
     <type name="Tester">\r
     </type>\r
     <type name="Program+C">\r
       <method name="Void M()" attrs="134">\r
-        <size>12</size>\r
+        <size>2</size>\r
       </method>\r
       <method name="Void .ctor()" attrs="6278">\r
         <size>7</size>\r
     </type>\r
     <type name="Program+&lt;Main&gt;c__async1">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>197</size>\r
+        <size>196</size>\r
       </method>\r
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
         <size>13</size>\r
     </type>\r
     <type name="C+&lt;Foo&gt;c__async3">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>169</size>\r
+        <size>168</size>\r
       </method>\r
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
         <size>13</size>\r
     </type>\r
     <type name="C+&lt;Foo&gt;c__async0+&lt;Foo&gt;c__AnonStorey4+&lt;Foo&gt;c__async3">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>185</size>\r
+        <size>184</size>\r
       </method>\r
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
         <size>13</size>\r
     </type>\r
     <type name="C+&lt;Foo&gt;c__async0+&lt;Foo&gt;c__AnonStorey4+&lt;Foo&gt;c__async3">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>214</size>\r
+        <size>213</size>\r
       </method>\r
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
         <size>13</size>\r
     </type>\r
     <type name="C+&lt;Test&gt;c__async0">\r
       <method name="Void MoveNext()" attrs="486">\r
-        <size>61</size>\r
+        <size>60</size>\r
       </method>\r
       <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
         <size>13</size>\r
       </method>\r
     </type>\r
   </test>\r
+  <test name="test-async-53.cs">\r
+    <type name="Y">\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="X">\r
+      <method name="Void add_E(System.Action`2[System.Int32,System.String])" attrs="2182">\r
+        <size>42</size>\r
+      </method>\r
+      <method name="Void remove_E(System.Action`2[System.Int32,System.String])" attrs="2182">\r
+        <size>42</size>\r
+      </method>\r
+      <method name="Void Foo()" attrs="129">\r
+        <size>54</size>\r
+      </method>\r
+      <method name="Void Main()" attrs="150">\r
+        <size>14</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="X+&lt;Foo&gt;c__AnonStorey1">\r
+      <method name="Void &lt;&gt;m__0(Int32, System.String)" attrs="131">\r
+        <size>35</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="X+&lt;Foo&gt;c__AnonStorey1+&lt;Foo&gt;c__async0">\r
+      <method name="Void MoveNext()" attrs="486">\r
+        <size>43</size>\r
+      </method>\r
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
+        <size>13</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
+  <test name="test-async-54.cs">\r
+    <type name="Test">\r
+      <method name="Int32 Main()" attrs="150">\r
+        <size>79</size>\r
+      </method>\r
+      <method name="System.Threading.Tasks.Task`1[System.Int32] TestMethod(System.Exception)" attrs="145">\r
+        <size>41</size>\r
+      </method>\r
+      <method name="System.Threading.Tasks.Task Foo(System.Exception)" attrs="145">\r
+        <size>41</size>\r
+      </method>\r
+      <method name="Void .ctor()" attrs="6278">\r
+        <size>7</size>\r
+      </method>\r
+    </type>\r
+    <type name="Test+&lt;TestMethod&gt;c__async0">\r
+      <method name="Void MoveNext()" attrs="486">\r
+        <size>226</size>\r
+      </method>\r
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
+        <size>13</size>\r
+      </method>\r
+    </type>\r
+    <type name="Test+&lt;Foo&gt;c__async1">\r
+      <method name="Void MoveNext()" attrs="486">\r
+        <size>159</size>\r
+      </method>\r
+      <method name="Void SetStateMachine(IAsyncStateMachine)" attrs="486">\r
+        <size>13</size>\r
+      </method>\r
+    </type>\r
+  </test>\r
   <test name="test-cls-00.cs">\r
     <type name="CLSCLass_6">\r
       <method name="Void add_Disposed(Delegate)" attrs="2182">\r
index 9fe965f5569a962ebdb8f631b43c4f36e5ce9bcd..4e7ca90fa6ecc9d56c39c9fa43c35ef0006d4a38 100644 (file)
@@ -98,7 +98,11 @@ namespace Mono.Cecil.Cil {
 
                public static VariableDefinition GetVariable (MethodBody body, int index)
                {
-                       return body.Variables [index];
+                       // bug 15727 - newer cecil does the same (in MethodDefinition.GetVariable)
+                       var variables = body.Variables;
+                       if (index < 0 || index >= variables.Count)
+                               return null;
+                       return variables [index];
                }
 
                void ReadCilBody (MethodBody body, BinaryReader br)
diff --git a/mcs/tools/cil-strip/cil-strip.csproj b/mcs/tools/cil-strip/cil-strip.csproj
new file mode 100644 (file)
index 0000000..8f4e068
--- /dev/null
@@ -0,0 +1,991 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>10.0.0</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{7B3D8F99-304A-4C2E-BAC5-7D1A29747B01}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <RootNamespace>cilstrip</RootNamespace>
+    <AssemblyName>cil-strip</AssemblyName>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug</OutputPath>
+    <DefineConstants>DEBUG;</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <ConsolePause>false</ConsolePause>
+    <Commandlineparameters>/Users/sebastienpouliot/Dropbox/iCatalogXniOS.exe /Users/sebastienpouliot/Dropbox/iCatalogXniOS-out.exe</Commandlineparameters>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>full</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release</OutputPath>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Externalconsole>true</Externalconsole>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+  </ItemGroup>
+  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
+  <ItemGroup>
+    <Folder Include="cil-strip\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="AssemblyStripper.cs">
+      <Link>cil-strip\AssemblyStripper.cs</Link>
+    </Compile>
+    <Compile Include="cilstrip.cs">
+      <Link>cil-strip\cilstrip.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AggressiveReflectionReader.cs">
+      <Link>cil-strip\Mono.Cecil\AggressiveReflectionReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ArrayDimension.cs">
+      <Link>cil-strip\Mono.Cecil\ArrayDimension.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ArrayDimensionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ArrayDimensionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ArrayType.cs">
+      <Link>cil-strip\Mono.Cecil\ArrayType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyFactory.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyFactory.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyFlags.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyFlags.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyHashAlgorithm.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyHashAlgorithm.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyInfo.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyInfo.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyKind.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyKind.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyLinkedResource.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyLinkedResource.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyNameDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyNameDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyNameReference.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyNameReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\AssemblyNameReferenceCollection.cs">
+      <Link>cil-strip\Mono.Cecil\AssemblyNameReferenceCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\BaseAssemblyResolver.cs">
+      <Link>cil-strip\Mono.Cecil\BaseAssemblyResolver.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\BaseReflectionReader.cs">
+      <Link>cil-strip\Mono.Cecil\BaseReflectionReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\BaseReflectionVisitor.cs">
+      <Link>cil-strip\Mono.Cecil\BaseReflectionVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\BaseStructureVisitor.cs">
+      <Link>cil-strip\Mono.Cecil\BaseStructureVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\CallSite.cs">
+      <Link>cil-strip\Mono.Cecil\CallSite.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\CompactFrameworkCompatibility.cs">
+      <Link>cil-strip\Mono.Cecil\CompactFrameworkCompatibility.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\Constants.cs">
+      <Link>cil-strip\Mono.Cecil\Constants.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ConstraintCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ConstraintCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ConstructorCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ConstructorCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\CustomAttribute.cs">
+      <Link>cil-strip\Mono.Cecil\CustomAttribute.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\CustomAttributeCollection.cs">
+      <Link>cil-strip\Mono.Cecil\CustomAttributeCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\DefaultAssemblyResolver.cs">
+      <Link>cil-strip\Mono.Cecil\DefaultAssemblyResolver.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\DefaultImporter.cs">
+      <Link>cil-strip\Mono.Cecil\DefaultImporter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\EmbeddedResource.cs">
+      <Link>cil-strip\Mono.Cecil\EmbeddedResource.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\EventAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\EventAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\EventDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\EventDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\EventDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\EventDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\EventReference.cs">
+      <Link>cil-strip\Mono.Cecil\EventReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ExternTypeCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ExternTypeCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\FieldAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\FieldAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\FieldDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\FieldDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\FieldDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\FieldDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\FieldReference.cs">
+      <Link>cil-strip\Mono.Cecil\FieldReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\FileAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\FileAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\FunctionPointerType.cs">
+      <Link>cil-strip\Mono.Cecil\FunctionPointerType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericArgumentCollection.cs">
+      <Link>cil-strip\Mono.Cecil\GenericArgumentCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericContext.cs">
+      <Link>cil-strip\Mono.Cecil\GenericContext.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericInstanceMethod.cs">
+      <Link>cil-strip\Mono.Cecil\GenericInstanceMethod.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericInstanceType.cs">
+      <Link>cil-strip\Mono.Cecil\GenericInstanceType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericParameter.cs">
+      <Link>cil-strip\Mono.Cecil\GenericParameter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericParameterAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\GenericParameterAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\GenericParameterCollection.cs">
+      <Link>cil-strip\Mono.Cecil\GenericParameterCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\HashCodeProvider.cs">
+      <Link>cil-strip\Mono.Cecil\HashCodeProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IAnnotationProvider.cs">
+      <Link>cil-strip\Mono.Cecil\IAnnotationProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IAssemblyResolver.cs">
+      <Link>cil-strip\Mono.Cecil\IAssemblyResolver.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ICustomAttributeProvider.cs">
+      <Link>cil-strip\Mono.Cecil\ICustomAttributeProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IDetailReader.cs">
+      <Link>cil-strip\Mono.Cecil\IDetailReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IGenericInstance.cs">
+      <Link>cil-strip\Mono.Cecil\IGenericInstance.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IGenericParameterProvider.cs">
+      <Link>cil-strip\Mono.Cecil\IGenericParameterProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IHasConstant.cs">
+      <Link>cil-strip\Mono.Cecil\IHasConstant.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IHasMarshalSpec.cs">
+      <Link>cil-strip\Mono.Cecil\IHasMarshalSpec.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IHasSecurity.cs">
+      <Link>cil-strip\Mono.Cecil\IHasSecurity.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IImporter.cs">
+      <Link>cil-strip\Mono.Cecil\IImporter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IMemberDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\IMemberDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IMemberReference.cs">
+      <Link>cil-strip\Mono.Cecil\IMemberReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IMetadataScope.cs">
+      <Link>cil-strip\Mono.Cecil\IMetadataScope.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IMetadataTokenProvider.cs">
+      <Link>cil-strip\Mono.Cecil\IMetadataTokenProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IMethodSignature.cs">
+      <Link>cil-strip\Mono.Cecil\IMethodSignature.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IReflectionStructureVisitable.cs">
+      <Link>cil-strip\Mono.Cecil\IReflectionStructureVisitable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IReflectionStructureVisitor.cs">
+      <Link>cil-strip\Mono.Cecil\IReflectionStructureVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IReflectionVisitable.cs">
+      <Link>cil-strip\Mono.Cecil\IReflectionVisitable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IReflectionVisitor.cs">
+      <Link>cil-strip\Mono.Cecil\IReflectionVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\IRequireResolving.cs">
+      <Link>cil-strip\Mono.Cecil\IRequireResolving.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ImportContext.cs">
+      <Link>cil-strip\Mono.Cecil\ImportContext.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\InterfaceCollection.cs">
+      <Link>cil-strip\Mono.Cecil\InterfaceCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\LinkedResource.cs">
+      <Link>cil-strip\Mono.Cecil\LinkedResource.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ManifestResourceAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\ManifestResourceAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MarshalSpec.cs">
+      <Link>cil-strip\Mono.Cecil\MarshalSpec.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MemberReference.cs">
+      <Link>cil-strip\Mono.Cecil\MemberReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MemberReferenceCollection.cs">
+      <Link>cil-strip\Mono.Cecil\MemberReferenceCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MetadataResolver.cs">
+      <Link>cil-strip\Mono.Cecil\MetadataResolver.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\MethodAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodCallingConvention.cs">
+      <Link>cil-strip\Mono.Cecil\MethodCallingConvention.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\MethodDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\MethodDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodImplAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\MethodImplAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodReference.cs">
+      <Link>cil-strip\Mono.Cecil\MethodReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodReturnType.cs">
+      <Link>cil-strip\Mono.Cecil\MethodReturnType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodSemanticsAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\MethodSemanticsAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\MethodSpecification.cs">
+      <Link>cil-strip\Mono.Cecil\MethodSpecification.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\Modifiers.cs">
+      <Link>cil-strip\Mono.Cecil\Modifiers.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ModuleDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\ModuleDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ModuleDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ModuleDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ModuleReference.cs">
+      <Link>cil-strip\Mono.Cecil\ModuleReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ModuleReferenceCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ModuleReferenceCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\NameObjectCollectionBase.cs">
+      <Link>cil-strip\Mono.Cecil\NameObjectCollectionBase.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\NativeType.cs">
+      <Link>cil-strip\Mono.Cecil\NativeType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\NestedTypeCollection.cs">
+      <Link>cil-strip\Mono.Cecil\NestedTypeCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\NullReferenceImporter.cs">
+      <Link>cil-strip\Mono.Cecil\NullReferenceImporter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\OverrideCollection.cs">
+      <Link>cil-strip\Mono.Cecil\OverrideCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PInvokeAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\PInvokeAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PInvokeInfo.cs">
+      <Link>cil-strip\Mono.Cecil\PInvokeInfo.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ParameterAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\ParameterAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ParameterDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\ParameterDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ParameterDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ParameterDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ParameterReference.cs">
+      <Link>cil-strip\Mono.Cecil\ParameterReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PinnedType.cs">
+      <Link>cil-strip\Mono.Cecil\PinnedType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PointerType.cs">
+      <Link>cil-strip\Mono.Cecil\PointerType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PropertyAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\PropertyAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PropertyDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\PropertyDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PropertyDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\PropertyDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\PropertyReference.cs">
+      <Link>cil-strip\Mono.Cecil\PropertyReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ReferenceType.cs">
+      <Link>cil-strip\Mono.Cecil\ReferenceType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ReflectionController.cs">
+      <Link>cil-strip\Mono.Cecil\ReflectionController.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ReflectionException.cs">
+      <Link>cil-strip\Mono.Cecil\ReflectionException.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ReflectionHelper.cs">
+      <Link>cil-strip\Mono.Cecil\ReflectionHelper.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ReflectionReader.cs">
+      <Link>cil-strip\Mono.Cecil\ReflectionReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ReflectionWriter.cs">
+      <Link>cil-strip\Mono.Cecil\ReflectionWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\Resource.cs">
+      <Link>cil-strip\Mono.Cecil\Resource.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\ResourceCollection.cs">
+      <Link>cil-strip\Mono.Cecil\ResourceCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\SecurityAction.cs">
+      <Link>cil-strip\Mono.Cecil\SecurityAction.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\SecurityDeclaration.cs">
+      <Link>cil-strip\Mono.Cecil\SecurityDeclaration.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\SecurityDeclarationCollection.cs">
+      <Link>cil-strip\Mono.Cecil\SecurityDeclarationCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\SecurityDeclarationReader.cs">
+      <Link>cil-strip\Mono.Cecil\SecurityDeclarationReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\SentinelType.cs">
+      <Link>cil-strip\Mono.Cecil\SentinelType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\StructureReader.cs">
+      <Link>cil-strip\Mono.Cecil\StructureReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\StructureWriter.cs">
+      <Link>cil-strip\Mono.Cecil\StructureWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TableComparers.cs">
+      <Link>cil-strip\Mono.Cecil\TableComparers.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TargetRuntime.cs">
+      <Link>cil-strip\Mono.Cecil\TargetRuntime.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TypeAttributes.cs">
+      <Link>cil-strip\Mono.Cecil\TypeAttributes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TypeDefinition.cs">
+      <Link>cil-strip\Mono.Cecil\TypeDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TypeDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil\TypeDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TypeReference.cs">
+      <Link>cil-strip\Mono.Cecil\TypeReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TypeReferenceCollection.cs">
+      <Link>cil-strip\Mono.Cecil\TypeReferenceCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\TypeSpecification.cs">
+      <Link>cil-strip\Mono.Cecil\TypeSpecification.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil\VariantType.cs">
+      <Link>cil-strip\Mono.Cecil\VariantType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\BaseImageVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\BaseImageVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\CLIHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\CLIHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\CopyImageVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\CopyImageVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\DOSHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\DOSHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\DataDirectory.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\DataDirectory.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\DebugHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\DebugHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\DebugStoreType.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\DebugStoreType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ExportTable.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ExportTable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\IBinaryVisitable.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\IBinaryVisitable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\IBinaryVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\IBinaryVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\IHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\IHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\Image.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\Image.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ImageCharacteristics.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ImageCharacteristics.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ImageFormatException.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ImageFormatException.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ImageInitializer.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ImageInitializer.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ImageReader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ImageReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ImageWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ImageWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\Imports.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\Imports.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\MemoryBinaryWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\MemoryBinaryWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\PEFileHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\PEFileHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\PEOptionalHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\PEOptionalHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\RVA.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\RVA.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceDataEntry.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceDataEntry.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceDirectoryEntry.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceDirectoryEntry.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceDirectoryString.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceDirectoryString.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceDirectoryTable.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceDirectoryTable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceNode.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceNode.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceReader.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\ResourceWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\ResourceWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\RuntimeImage.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\RuntimeImage.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\Section.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\Section.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\SectionCharacteristics.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\SectionCharacteristics.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\SectionCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\SectionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Binary\SubSystem.cs">
+      <Link>cil-strip\Mono.Cecil.Binary\SubSystem.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\BaseCodeVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\BaseCodeVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\CilWorker.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\CilWorker.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\Code.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\Code.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\CodeReader.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\CodeReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\CodeWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\CodeWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\Document.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\Document.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\DocumentHashAlgorithm.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\DocumentHashAlgorithm.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\DocumentLanguage.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\DocumentLanguage.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\DocumentLanguageVendor.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\DocumentLanguageVendor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\DocumentType.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\DocumentType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ExceptionHandler.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ExceptionHandler.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ExceptionHandlerCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ExceptionHandlerCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ExceptionHandlerType.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ExceptionHandlerType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\FlowControl.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\FlowControl.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\GuidAttribute.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\GuidAttribute.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ICodeVisitable.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ICodeVisitable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ICodeVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ICodeVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\IScopeProvider.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\IScopeProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ISymbolReader.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ISymbolReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ISymbolStoreFactory.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ISymbolStoreFactory.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ISymbolWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ISymbolWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\IVariableDefinitionProvider.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\IVariableDefinitionProvider.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\Instruction.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\Instruction.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\InstructionCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\InstructionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\MethodBody.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\MethodBody.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\MethodDataSection.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\MethodDataSection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\MethodHeader.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\MethodHeader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\OpCode.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\OpCode.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\OpCodeNames.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\OpCodeNames.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\OpCodeType.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\OpCodeType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\OpCodes.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\OpCodes.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\OperandType.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\OperandType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\Scope.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\Scope.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\ScopeCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\ScopeCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\SequencePoint.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\SequencePoint.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\StackBehaviour.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\StackBehaviour.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\SymbolStoreHelper.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\SymbolStoreHelper.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\VariableDefinition.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\VariableDefinition.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\VariableDefinitionCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\VariableDefinitionCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Cil\VariableReference.cs">
+      <Link>cil-strip\Mono.Cecil.Cil\VariableReference.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Assembly.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Assembly.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\AssemblyOS.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\AssemblyOS.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\AssemblyProcessor.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\AssemblyProcessor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\AssemblyRef.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\AssemblyRef.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\AssemblyRefOS.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\AssemblyRefOS.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\AssemblyRefProcessor.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\AssemblyRefProcessor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\BaseMetadataVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\BaseMetadataVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\BlobHeap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\BlobHeap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ClassLayout.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ClassLayout.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\CodedIndex.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\CodedIndex.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Constant.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Constant.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\CultureUtils.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\CultureUtils.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\CustomAttribute.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\CustomAttribute.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\DeclSecurity.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\DeclSecurity.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ElementType.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ElementType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Event.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Event.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\EventMap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\EventMap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\EventPtr.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\EventPtr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ExportedType.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ExportedType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Field.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Field.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\FieldLayout.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\FieldLayout.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\FieldMarshal.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\FieldMarshal.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\FieldPtr.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\FieldPtr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\FieldRVA.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\FieldRVA.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\File.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\File.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\GenericParam.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\GenericParam.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\GenericParamConstraint.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\GenericParamConstraint.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\GuidHeap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\GuidHeap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\IMetadataRow.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\IMetadataRow.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\IMetadataTable.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\IMetadataTable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\IMetadataVisitable.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\IMetadataVisitable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\IMetadataVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\IMetadataVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ImplMap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ImplMap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\InterfaceImpl.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\InterfaceImpl.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ManifestResource.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ManifestResource.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MemberRef.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MemberRef.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataFormatException.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataFormatException.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataHeap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataHeap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataInitializer.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataInitializer.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataReader.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataRoot.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataRoot.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataRowReader.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataRowReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataRowWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataRowWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataStream.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataStream.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataStreamCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataStreamCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataTableReader.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataTableReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataTableWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataTableWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataToken.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataToken.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MetadataWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MetadataWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Method.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Method.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MethodImpl.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MethodImpl.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MethodPtr.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MethodPtr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MethodSemantics.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MethodSemantics.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\MethodSpec.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\MethodSpec.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Module.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Module.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ModuleRef.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ModuleRef.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\NestedClass.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\NestedClass.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Param.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Param.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\ParamPtr.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\ParamPtr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Property.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Property.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\PropertyMap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\PropertyMap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\PropertyPtr.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\PropertyPtr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\RowCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\RowCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\StandAloneSig.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\StandAloneSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\StringsHeap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\StringsHeap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\TableCollection.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\TableCollection.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\TablesHeap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\TablesHeap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\TokenType.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\TokenType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\TypeDef.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\TypeDef.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\TypeRef.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\TypeRef.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\TypeSpec.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\TypeSpec.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\UserStringsHeap.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\UserStringsHeap.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Metadata\Utilities.cs">
+      <Link>cil-strip\Mono.Cecil.Metadata\Utilities.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Array.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Array.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\ArrayShape.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\ArrayShape.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\BaseSignatureVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\BaseSignatureVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Class.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Class.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Constraint.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Constraint.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\CustomAttrib.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\CustomAttrib.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\CustomMod.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\CustomMod.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\FieldSig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\FieldSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\FnPtr.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\FnPtr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\GenericArg.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\GenericArg.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\GenericInst.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\GenericInst.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\GenericInstSignature.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\GenericInstSignature.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\ISignatureVisitable.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\ISignatureVisitable.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\ISignatureVisitor.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\ISignatureVisitor.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\InputOutputItem.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\InputOutputItem.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\LocalVarSig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\LocalVarSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\MVar.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\MVar.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\MarshalSig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\MarshalSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\MethodDefSig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\MethodDefSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\MethodRefSig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\MethodRefSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\MethodSig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\MethodSig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\MethodSpec.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\MethodSpec.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Param.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Param.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\PropertySig.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\PropertySig.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Ptr.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Ptr.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\RetType.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\RetType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\SigType.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\SigType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Signature.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Signature.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\SignatureReader.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\SignatureReader.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\SignatureWriter.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\SignatureWriter.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\SzArray.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\SzArray.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\TypeSpec.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\TypeSpec.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\ValueType.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\ValueType.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Cecil.Signatures\Var.cs">
+      <Link>cil-strip\Mono.Cecil.Signatures\Var.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Xml\SecurityParser.cs">
+      <Link>cil-strip\Mono.Xml\SecurityParser.cs</Link>
+    </Compile>
+    <Compile Include="Mono.Xml\SmallXmlParser.cs">
+      <Link>cil-strip\Mono.Xml\SmallXmlParser.cs</Link>
+    </Compile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="Mono.Xml\ChangeLog">
+      <Link>cil-strip\Mono.Xml\ChangeLog</Link>
+    </None>
+  </ItemGroup>
+</Project>
\ No newline at end of file
index 4f814f4bde44957401aa90a6af44d771a3006e7a..0fae1a02c00e199a0a7ce7fc313fa3cd73f34963 100644 (file)
@@ -33,6 +33,8 @@
                        <method name="InternalArray__IndexOf" />
                        <method name="InternalArray__get_Item" />
                        <method name="InternalArray__set_Item" />
+                       <method name="InternalArray__IReadOnlyList_get_Item" />
+                       <method name="InternalArray__IReadOnlyCollection_get_Count" />
                </type>
                <type fullname="System.ArrayTypeMismatchException" />
                <type fullname="System.Attribute" />
index bb944b1b551597c72952f044dc01cd1a217b81f8..30b7779f586d2534a89a3f9e72b4cb7c64cd0bc1 100644 (file)
@@ -189,7 +189,7 @@ namespace Mono.Linker.Steps {
                                MarkCustomAttribute (ca);
                }
 
-               void MarkCustomAttribute (CustomAttribute ca)
+               protected virtual void MarkCustomAttribute (CustomAttribute ca)
                {
                        MarkMethod (ca.Constructor);
 
@@ -296,7 +296,7 @@ namespace Mono.Linker.Steps {
                                MarkCustomAttributes (module);
                }
 
-               void MarkField (FieldReference reference)
+               protected void MarkField (FieldReference reference)
                {
 //                     if (IgnoreScope (reference.DeclaringType.Scope))
 //                             return;
@@ -346,10 +346,7 @@ namespace Mono.Linker.Steps {
 
                protected virtual void MarkSerializable (TypeDefinition type)
                {
-                       if (!type.HasMethods)
-                               return;
-
-                       MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
+                       MarkDefaultConstructor (type);
                        MarkMethodsIf (type.Methods, IsSpecialSerializationConstructorPredicate);
                }
 
@@ -582,6 +579,14 @@ namespace Mono.Linker.Steps {
                        return method.IsConstructor && !method.IsStatic;
                }
 
+               protected void MarkDefaultConstructor (TypeDefinition type)
+               {
+                       if ((type == null) || !type.HasMethods)
+                               return;
+
+                       MarkMethodsIf (type.Methods, IsDefaultConstructorPredicate);
+               }
+
                static MethodPredicate IsStaticConstructorPredicate = new MethodPredicate (IsStaticConstructor);
 
                static bool IsStaticConstructor (MethodDefinition method)
@@ -901,12 +906,12 @@ namespace Mono.Linker.Steps {
                        return null;
                }
 
-               void MarkProperty (PropertyDefinition prop)
+               protected void MarkProperty (PropertyDefinition prop)
                {
                        MarkCustomAttributes (prop);
                }
 
-               void MarkEvent (EventDefinition evt)
+               protected void MarkEvent (EventDefinition evt)
                {
                        MarkCustomAttributes (evt);
                        MarkMethodIfNotNull (evt.AddMethod);
index 20f06f3bb5888cfef5906d64cddb1096351289ad..9bd2bad93444e1d258faa01310f7b4b7b0600571 100644 (file)
@@ -94,6 +94,9 @@ namespace Mono.Linker.Steps {
 
                void SweepReferences (AssemblyDefinition assembly, AssemblyDefinition target)
                {
+                       if (assembly == target)
+                               return;
+
                        var references = assembly.MainModule.AssemblyReferences;
                        for (int i = 0; i < references.Count; i++) {
                                var reference = references [i];
@@ -128,10 +131,26 @@ namespace Mono.Linker.Steps {
                                return;
                        resolvedTypeReferences.Add (assembly);
 
+                       var hash = new Dictionary<TypeReference,IMetadataScope> ();
+
                        foreach (TypeReference tr in assembly.MainModule.GetTypeReferences ()) {
+                               if (hash.ContainsKey (tr))
+                                       continue;
                                var td = tr.Resolve ();
+                               IMetadataScope scope = tr.Scope;
                                // at this stage reference might include things that can't be resolved
-                               tr.Scope = td == null ? null : assembly.MainModule.Import (td).Scope;
+                               // 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;
+                               hash.Add (tr, scope);
+                       }
+
+                       // Resolve everything first before updating scopes.
+                       // If we set the scope to null, then calling Resolve() on any of its
+                       // nested types would crash.
+
+                       foreach (var e in hash) {
+                               e.Key.Scope = e.Value;
                        }
                }
 
index 9700fe0543d474e38aa23d90e2e6a1bc6b2721f8..91c9851251625babd67cb0a902a04c947c06bc05 100644 (file)
@@ -91,6 +91,7 @@
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index 8918f4d86884af136610c06c40c275d5feac1576..804141f78e7237b2983a0816f234dc7ea857c15a 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index a4f8b4baf8d7d0df4d03d850460930f441952983..183416b919878eff94921af3a83f6a470e3e3b82 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index c873e3aa4159940dd3007691310ae8bb31b11358..890e316c4b259af7726b637782fafb50758118e1 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index 393a51ae7b3e11d5c4b008a23755981f982e377b..b850e47bef2476f51b49bfe93f07c213086aa07d 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index af7e8564c1a11c410e6740b79b42f5d352059f20..9e79eef40282dc100f8a2d2db2fb484c093d6731 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index 42c2af1365f43bb63f0dcdb1c58186ef85bd7e70..7941eab44aae392b2090da2418ac2d250ed4aaa0 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index d7fb2ea21da64f4774cf911adf6ddcf7788977bb..8e20daa9d18c9f1b51a1911384aca87236f3791f 100644 (file)
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
         <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index eb7fb859d7108ca9f31e808a113e126bc422dc0e..11bac1bf516bc97af9a790441ac1fd674f7dc3a5 100644 (file)
@@ -266,6 +266,7 @@ class Example {
             <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -277,6 +278,7 @@ class Example {
             <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -288,6 +290,7 @@ class Example {
             <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -299,6 +302,7 @@ class Example {
             <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -402,6 +406,7 @@ class Example {
             <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -413,6 +418,7 @@ class Example {
             <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -424,6 +430,7 @@ class Example {
             <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -435,6 +442,7 @@ class Example {
             <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -854,6 +862,7 @@ class Example {
             <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -865,6 +874,7 @@ class Example {
             <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -876,6 +886,7 @@ class Example {
             <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -887,6 +898,7 @@ class Example {
             <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -925,6 +937,7 @@ class Example {
             <exception cref="T:System.ArgumentNullException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -936,6 +949,7 @@ class Example {
             <exception cref="T:System.ArgumentOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -947,6 +961,7 @@ class Example {
             <exception cref="T:System.FormatException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
@@ -958,6 +973,7 @@ class Example {
             <exception cref="T:System.IndexOutOfRangeException">To be added; from:
           <see cref="M:System.Delegate.Combine(System.Delegate,System.Delegate)" />,
           <see cref="M:System.Delegate.CombineImpl(System.Delegate)" />,
+          <see cref="M:System.Delegate.Remove(System.Delegate,System.Delegate)" />,
           <see cref="M:System.String.FormatHelper(System.Text.StringBuilder,System.IFormatProvider,System.String,System.Object[])" />,
           <see cref="M:System.String.get_Chars(System.Int32)" />,
           <see cref="M:System.String.InternalSetChar(System.Int32,System.Char)" />,
index 31b095ea55a4809552230dee4f5732fa5f5f530b..8f7e736ff6331b4c133145b5ff49e894967b4ad6 100755 (executable)
@@ -626,6 +626,8 @@ void          mono_register_config_for_assembly (const char* assembly_name, cons
                        Error ("Cannot find assembly `" + assembly + "'" );
                        Console.WriteLine ("Log: \n" + total_log);
                } catch (IKVM.Reflection.BadImageFormatException f) {
+                       if (skip_scan)
+                               throw;
                        Error ("Cannot load assembly (bad file format) " + f.Message);
                } catch (FileLoadException f){
                        Error ("Cannot load assembly " + f.Message);
index 504d899f831e6a22c2b059c6a02317ed1f6a5db9..af9012a90444aefcb2c438dfa97ec38f2a5ecb15 100644 (file)
@@ -315,7 +315,7 @@ class MonoP {
                        assembly = options.AssemblyReference;
 
                        if (options.ShowAll){
-                               ShowAll (assembly, options.FilterObsolete, options.ShowPrivate);
+                               ShowAll (assembly, options.ShowPrivate, options.FilterObsolete);
                                return;
                        } else {
                                if (options.Type == null) {
index 0aea81dac014639c37ba5ec6688e3d0b6ad2defb..439afd50e35f2afc5f9fe50dd3d8865494954fd1 100644 (file)
@@ -46,7 +46,7 @@ namespace Mono.Tuner {
 
                public abstract SubStepTargets Targets { get; }
 
-               void ISubStep.Initialize (LinkContext context)
+               public virtual void Initialize (LinkContext context)
                {
                        this.context = context;
                }
index 3922f9168b32dd61d23efc069ba4821b69e3adf5..7edc44f031646933f34e3e538f942bb05fc92e23 100644 (file)
@@ -1,6 +1,4 @@
 using System;
-using System.Collections.Generic;
-using System.Linq;
 
 using Mono.Linker;
 using Mono.Linker.Steps;
@@ -11,19 +9,23 @@ namespace Mono.Tuner {
 
        public class RemoveResources : IStep {
 
-               I18nAssemblies assemblies;
+               readonly I18nAssemblies assemblies;
 
                public RemoveResources (I18nAssemblies assemblies)
                {
                        this.assemblies = assemblies;
                }
 
-               public void Process (LinkContext context)
+               public virtual void Process (LinkContext context)
                {
                        AssemblyDefinition assembly;
                        if (!context.TryGetLinkedAssembly ("mscorlib", out assembly))
                                return;
 
+                       // skip this if we're not linking mscorlib, e.g. --linkskip=mscorlib
+                       if (context.Annotations.GetAction (assembly) != AssemblyAction.Link)
+                               return;
+
                        var resources = assembly.MainModule.Resources;
 
                        for (int i = 0; i < resources.Count; i++) {
index 53c27b05869794a0d48f31c4cf698ef84455679f..9ba7f3a92ec4ff1b83d00561c2329c74d8123539 100644 (file)
@@ -3,6 +3,7 @@
        <Import Project="$(MSBuildProjectFullPath).user" Condition="Exists('$(MSBuildProjectFullPath).user')"/>
        
        <PropertyGroup>
+               <OutputType Condition="'$(OutputType)' == ''">Exe</OutputType>
                <TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
                <TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
                <TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
@@ -14,7 +15,7 @@
        </PropertyGroup>
 
        <PropertyGroup>
-               <AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
+               <AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
                <OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
                <OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
                <WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
index bf686b06af2b0c4dadd49cc765fb0687f8475451..6d91c7767391a9247e248cdaf98feed82b266b05 100644 (file)
@@ -3,6 +3,7 @@
        <Import Project="$(MSBuildProjectFullPath).user" Condition="Exists('$(MSBuildProjectFullPath).user')"/>
        
        <PropertyGroup>
+               <OutputType Condition="'$(OutputType)' == ''">Exe</OutputType>
                <TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
                <TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
                <TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
@@ -14,7 +15,7 @@
        </PropertyGroup>
 
        <PropertyGroup>
-               <AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
+               <AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
                <OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
                <OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
                <WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
index 7bd9900af727cb470f0722f1f1a994fffc066ee3..6e4b73e89db215e2a63ccae6f21037183e1e8e32 100644 (file)
@@ -10,6 +10,7 @@
        <Import Project="$(MSBuildProjectFullPath).user" Condition="Exists('$(MSBuildProjectFullPath).user')"/> 
        
        <PropertyGroup>
+               <OutputType Condition="'$(OutputType)' == ''">Exe</OutputType>
                <TargetExt Condition="'$(OutputType)' == 'Winexe'">.exe</TargetExt>
                <TargetExt Condition="'$(OutputType)' == 'Exe'">.exe</TargetExt>
                <TargetExt Condition="'$(OutputType)' == 'Library'">.dll</TargetExt>
@@ -21,7 +22,7 @@
        </PropertyGroup>
 
        <PropertyGroup>
-               <AssemblyName Condition="'$(AssemblyName)' == ''">$(RootNamespace)</AssemblyName>
+               <AssemblyName Condition="'$(AssemblyName)' == ''">$(MSBuildProjectName)</AssemblyName>
                <OutputPath Condition="'$(OutputPath)' != '' and !HasTrailingSlash('$(OutputPath)')">$(OutputPath)\</OutputPath> 
                <OutputPath Condition=" '$(Platform)'=='' and '$(Configuration)'=='' and '$(OutputPath)'=='' ">bin\Debug\</OutputPath>
                <WarningLevel Condition="'$(WarningLevel)' == ''" >2</WarningLevel>
index 217bcaa0226ba6711723bb1ef38534d70fdd76d0..192a67fdc59490ecdd746caf9bfe2ca0807f9634 100644 (file)
@@ -139,7 +139,7 @@ rm -rf %buildroot
 
 %files -f mcs.lang
 %defattr(-, root, root)
-%doc AUTHORS COPYING.LIB ChangeLog NEWS README
+%doc AUTHORS COPYING.LIB ChangeLog NEWS README.md
 %config %_sysconfdir/mono/2.0/machine.config
 %config %_sysconfdir/mono/2.0/settings.map
 %config %_sysconfdir/mono/4.0/machine.config
index 9dd3269774b3e0cfd146cf15b315f46560605b7f..3c40d9de522f7bfd8c14e185debfc2e54ecb23f3 100644 (file)
@@ -1054,6 +1054,10 @@ typedef union {
 
 #define amd64_sse_cvtsi2sd_reg_reg(inst,dreg,reg) amd64_sse_cvtsi2sd_reg_reg_size ((inst), (dreg), (reg), 8)
 
+#define amd64_sse_cvtsi2ss_reg_reg_size(inst,dreg,reg,size) emit_sse_reg_reg_size ((inst), (dreg), (reg), 0xf3, 0x0f, 0x2a, (size))
+
+#define amd64_sse_cvtsi2ss_reg_reg(inst,dreg,reg) amd64_sse_cvtsi2ss_reg_reg_size ((inst), (dreg), (reg), 8)
+
 #define amd64_sse_cvtsd2ss_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf2, 0x0f, 0x5a)
 
 #define amd64_sse_cvtss2sd_reg_reg(inst,dreg,reg) emit_sse_reg_reg ((inst), (dreg), (reg), 0xf3, 0x0f, 0x5a)
index dc4df7d8a6a048ffe35419d5975e09a63528e98c..1dbd1c6e279d40613c8d7ccf9eb3ea0664528993 100644 (file)
@@ -334,7 +334,7 @@ enum {
 /* misc and coprocessor ops */
 #define mips_move(c,dest,src) mips_addu(c,dest,src,mips_zero)
 #define mips_dmove(c,dest,src) mips_daddu(c,dest,src,mips_zero)
-#define mips_nop(c) mips_sll(c,0,0,0)
+#define mips_nop(c) mips_or(c,mips_at,mips_at,0)
 #define mips_break(c,code) mips_emit32(c, ((code)<<6)|13)
 #define mips_mfhi(c,dest) mips_format_r(c,0,0,0,dest,0,16)
 #define mips_mflo(c,dest) mips_format_r(c,0,0,0,dest,0,18)
index ced466eaf1407c509f05e76eca52389a7a38d575..ad6282f64090332eb6f3b23a97f9589f4f9e594e 100644 (file)
@@ -1039,7 +1039,7 @@ typedef union {
                } else {        \
                        x86_codegen_pre(&(inst), 6); \
                        *(inst)++ = (unsigned char)0x69;        \
-                       x86_reg_emit ((inst), (reg), (mem));    \
+                       x86_mem_emit ((inst), (reg), (mem));    \
                        x86_imm_emit32 ((inst), (imm)); \
                }       \
        } while (0)
index c316fef320ac3a74e5d69d148fd9ed36ff666efb..4d548329ddb4ebe5b988754435b19e69e2a401ff 100644 (file)
@@ -1715,10 +1715,11 @@ static GSList *load_modules (void)
 
                slide = _dyld_get_image_vmaddr_slide (i);
                name = _dyld_get_image_name (i);
-               hdr = _dyld_get_image_header (i);
 #if SIZEOF_VOID_P == 8
+               hdr = (const struct mach_header_64*)_dyld_get_image_header (i);
                sec = getsectbynamefromheader_64 (hdr, SEG_DATA, SECT_DATA);
 #else
+               hdr = _dyld_get_image_header (i);
                sec = getsectbynamefromheader (hdr, SEG_DATA, SECT_DATA);
 #endif
 
@@ -2119,9 +2120,11 @@ static gchar *get_process_name_from_proc (pid_t pid)
        size_t size;
        struct kinfo_proc2 *pi;
 #elif defined(PLATFORM_MACOSX)
+#if !(!defined (__mono_ppc__) && defined (TARGET_OSX))
        size_t size;
        struct kinfo_proc *pi;
        int mib[] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid };
+#endif
 #else
        FILE *fp;
        gchar *filename = NULL;
index a659d3763e80bdf39e8a7758d740738c36e937c1..27ee96d4e3cbeba0b137e8d18d12033a1a3a7f53 100644 (file)
@@ -778,6 +778,7 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
        gpointer handle = GUINT_TO_POINTER (fd);
        int ret;
        const void *tmp_val;
+       int bufsize = 0;
        struct timeval tv;
        
        if (startup_count == 0) {
@@ -805,7 +806,7 @@ int _wapi_setsockopt(guint32 fd, int level, int optname,
                 * buffer sizes "to allow space for bookkeeping
                 * overhead."
                 */
-               int bufsize = *((int *) optval);
+               bufsize = *((int *) optval);
 
                bufsize /= 2;
                tmp_val = &bufsize;
index c4d7c9c562ae1edc59676aa1d4f0e89dd9a34c97..91073a5e704e528a7542cc4b6ba96077948b141d 100644 (file)
@@ -117,6 +117,7 @@ common_sources = \
        filewatcher.c           \
        filewatcher.h           \
        gc-internal.h           \
+       gc-memfuncs.c           \
        icall.c                 \
        icall-def.h             \
        image.c                 \
@@ -253,7 +254,8 @@ sgen_sources = \
        sgen-stw.c                              \
        sgen-fin-weak-hash.c    \
        sgen-layout-stats.c     \
-       sgen-layout-stats.h
+       sgen-layout-stats.h     \
+       sgen-qsort.c
 
 libmonoruntime_la_SOURCES = $(common_sources) $(gc_dependent_sources) $(boehm_sources)
 libmonoruntime_la_CFLAGS = $(BOEHM_DEFINES)
@@ -331,3 +333,27 @@ else
 Makefile.am: Makefile.am.in
        cp $< $@
 endif
+
+if !HOST_WIN32
+
+test_sgen_qsort_SOURCES = test-sgen-qsort.c
+test_sgen_qsort_CFLAGS = $(SGEN_DEFINES)
+test_sgen_qsort_LDADD = libmonoruntimesgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
+       $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV)
+if PLATFORM_DARWIN
+test_sgen_qsort_LDFLAGS=-framework CoreFoundation
+endif
+
+test_gc_memfuncs_SOURCES = test-gc-memfuncs.c
+test_gc_memfuncs_CFLAGS = $(SGEN_DEFINES)
+test_gc_memfuncs_LDADD = libmonoruntimesgen.la ../io-layer/libwapi.la ../utils/libmonoutils.la \
+       $(LIBGC_LIBS) $(GLIB_LIBS) -lm $(LIBICONV)
+if PLATFORM_DARWIN
+test_gc_memfuncs_LDFLAGS=-framework CoreFoundation
+endif
+
+noinst_PROGRAMS = test-sgen-qsort test-gc-memfuncs
+
+TESTS = test-sgen-qsort test-gc-memfuncs
+
+endif !HOST_WIN32
index 20ccd0c489885fa478f8f2204b174f68f11e47db..f5090c04508675cbe7b7d91966ed9ea823d1446a 100644 (file)
@@ -77,7 +77,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 110
+#define MONO_CORLIB_VERSION 111
 
 typedef struct
 {
@@ -476,7 +476,6 @@ mono_domain_create_appdomain_internal (char *friendly_name, MonoAppDomainSetup *
        shadow_location = get_shadow_assembly_location_base (data, &error);
        if (!mono_error_ok (&error))
                mono_error_raise_exception (&error);
-       mono_debugger_event_create_appdomain (data, shadow_location);
        g_free (shadow_location);
 #endif
 
@@ -1945,7 +1944,9 @@ ves_icall_System_AppDomain_LoadAssembly (MonoAppDomain *ad,  MonoString *assRef,
 
        if (!parsed) {
                /* This is a parse error... */
-               return NULL;
+               if (!refOnly)
+                       refass = mono_try_assembly_resolve (domain, assRef, refOnly);
+               return refass;
        }
 
        ass = mono_assembly_load_full_nosearch (&aname, NULL, &status, refOnly);
@@ -2200,23 +2201,6 @@ unload_data_unref (unload_data *data)
        } while (InterlockedCompareExchange (&data->refcount, count, count - 1) != count);
 }
 
-static void
-deregister_reflection_info_roots_nspace_table (gpointer key, gpointer value, gpointer image)
-{
-       guint32 index = GPOINTER_TO_UINT (value);
-       MonoClass *class = mono_class_get (image, MONO_TOKEN_TYPE_DEF | index);
-
-       g_assert (class);
-
-       mono_class_free_ref_info (class);
-}
-
-static void
-deregister_reflection_info_roots_name_space (gpointer key, gpointer value, gpointer user_data)
-{
-       g_hash_table_foreach (value, deregister_reflection_info_roots_nspace_table, user_data);
-}
-
 static void
 deregister_reflection_info_roots_from_list (MonoImage *image)
 {
@@ -2230,7 +2214,6 @@ deregister_reflection_info_roots_from_list (MonoImage *image)
                list = list->next;
        }
 
-       g_slist_free (image->reflection_info_unregister_classes);
        image->reflection_info_unregister_classes = NULL;
 }
 
@@ -2239,29 +2222,28 @@ deregister_reflection_info_roots (MonoDomain *domain)
 {
        GSList *list;
 
-       mono_loader_lock ();
        mono_domain_assemblies_lock (domain);
        for (list = domain->domain_assemblies; list; list = list->next) {
                MonoAssembly *assembly = list->data;
                MonoImage *image = assembly->image;
                int i;
-               /*No need to take the image lock here since dynamic images are appdomain bound and at this point the mutator is gone.*/
-               if (image->dynamic && image->name_cache)
-                       g_hash_table_foreach (image->name_cache, deregister_reflection_info_roots_name_space, image);
-               deregister_reflection_info_roots_from_list (image);
+
+               /*
+                * No need to take the image lock here since dynamic images are appdomain bound and
+                * at this point the mutator is gone.  Taking the image lock here would mean
+                * promoting it from a simple lock to a complex lock, which we better avoid if
+                * possible.
+                */
+               if (image->dynamic)
+                       deregister_reflection_info_roots_from_list (image);
+
                for (i = 0; i < image->module_count; ++i) {
                        MonoImage *module = image->modules [i];
-                       if (module) {
-                               if (module->dynamic && module->name_cache) {
-                                       g_hash_table_foreach (module->name_cache,
-                                                       deregister_reflection_info_roots_name_space, module);
-                               }
+                       if (module && module->dynamic)
                                deregister_reflection_info_roots_from_list (module);
-                       }
                }
        }
        mono_domain_assemblies_unlock (domain);
-       mono_loader_unlock ();
 }
 
 static guint32 WINAPI
@@ -2417,8 +2399,6 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
                }
        }
 
-       mono_debugger_event_unload_appdomain (domain);
-
        mono_domain_set (domain, FALSE);
        /* Notify OnDomainUnload listeners */
        method = mono_class_get_method_from_name (domain->domain->mbr.obj.vtable->klass, "DoDomainUnload", -1); 
index 8ad1eda644d9188d137a3196d815c7d34f85219e..6e0abbce80c647bb73da89c91de3e3bd48073aa1 100644 (file)
@@ -36,6 +36,7 @@
 #include <mono/metadata/cil-coff.h>
 #include <mono/utils/mono-io-portability.h>
 #include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
 
 #ifndef HOST_WIN32
 #include <sys/types.h>
@@ -176,6 +177,8 @@ static CRITICAL_SECTION assemblies_mutex;
 /* If defined, points to the bundled assembly information */
 const MonoBundledAssembly **bundles;
 
+static mono_mutex_t assembly_binding_mutex;
+
 /* Loaded assembly binding info */
 static GSList *loaded_assembly_bindings = NULL;
 
@@ -735,6 +738,19 @@ mono_assemblies_init (void)
        check_extra_gac_path_env ();
 
        InitializeCriticalSection (&assemblies_mutex);
+       mono_mutex_init (&assembly_binding_mutex);
+}
+
+static void
+mono_assembly_binding_lock (void)
+{
+       mono_locks_mutex_acquire (&assembly_binding_mutex, AssemblyBindingLock);
+}
+
+static void
+mono_assembly_binding_unlock (void)
+{
+       mono_locks_mutex_release (&assembly_binding_mutex, AssemblyBindingLock);
 }
 
 gboolean
@@ -2469,7 +2485,7 @@ mono_assembly_bind_version (MonoAssemblyBindingInfo *info, MonoAssemblyName *ana
        return dest_name;
 }
 
-/* LOCKING: Assumes that we are already locked */
+/* LOCKING: assembly_binding lock must be held */
 static MonoAssemblyBindingInfo*
 search_binding_loaded (MonoAssemblyName *aname)
 {
@@ -2605,15 +2621,17 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
                return aname;
 
        domain = mono_domain_get ();
-       mono_loader_lock ();
+
+       mono_assembly_binding_lock ();
        info = search_binding_loaded (aname);
+       mono_assembly_binding_unlock ();
+
        if (!info) {
                mono_domain_lock (domain);
                info = get_per_domain_assembly_binding_info (domain, aname);
                mono_domain_unlock (domain);
        }
 
-       mono_loader_unlock ();
        if (info) {
                if (!check_policy_versions (info, aname))
                        return aname;
@@ -2637,10 +2655,7 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
                                g_free (domain_config_file_name);
                        g_free (domain_config_file_path);
                }
-               mono_domain_unlock (domain);
 
-               mono_loader_lock ();
-               mono_domain_lock (domain);
                info2 = get_per_domain_assembly_binding_info (domain, aname);
 
                if (info2) {
@@ -2651,7 +2666,6 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
                }
 
                mono_domain_unlock (domain);
-               mono_loader_unlock ();
        }
 
        if (!info) {
@@ -2675,7 +2689,7 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
                g_strlcpy ((char *)info->public_key_token, (const char *)aname->public_key_token, MONO_PUBLIC_KEY_TOKEN_LENGTH);
        }
        
-       mono_loader_lock ();
+       mono_assembly_binding_lock ();
        info2 = search_binding_loaded (aname);
        if (info2) {
                /* This binding was added by another thread 
@@ -2687,7 +2701,7 @@ mono_assembly_apply_binding (MonoAssemblyName *aname, MonoAssemblyName *dest_nam
        } else
                loaded_assembly_bindings = g_slist_prepend (loaded_assembly_bindings, info);
                
-       mono_loader_unlock ();
+       mono_assembly_binding_unlock ();
        
        if (!info->is_valid || !check_policy_versions (info, aname))
                return aname;
@@ -3099,6 +3113,7 @@ mono_assemblies_cleanup (void)
        GSList *l;
 
        DeleteCriticalSection (&assemblies_mutex);
+       mono_mutex_destroy (&assembly_binding_mutex);
 
        for (l = loaded_assembly_bindings; l; l = l->next) {
                MonoAssemblyBindingInfo *info = l->data;
@@ -3113,12 +3128,14 @@ mono_assemblies_cleanup (void)
        free_assembly_preload_hooks ();
 }
 
-/*LOCKING assumes loader lock is held*/
+/*LOCKING takes the assembly_binding lock*/
 void
 mono_assembly_cleanup_domain_bindings (guint32 domain_id)
 {
-       GSList **iter = &loaded_assembly_bindings;
+       GSList **iter;
 
+       mono_assembly_binding_lock ();
+       iter = &loaded_assembly_bindings;
        while (*iter) {
                GSList *l = *iter;
                MonoAssemblyBindingInfo *info = l->data;
@@ -3132,6 +3149,7 @@ mono_assembly_cleanup_domain_bindings (guint32 domain_id)
                        iter = &l->next;
                }
        }
+       mono_assembly_binding_unlock ();
 }
 
 /*
index b858650c874c5b213684f311f8802926f9a93ca6..d81608d1825fdde4df88c4276c5e2efb118ff7c8 100644 (file)
@@ -28,6 +28,7 @@
 #include <mono/utils/mono-threads.h>
 #include <mono/utils/dtrace.h>
 #include <mono/utils/gc_wrapper.h>
+#include <mono/utils/mono-mutex.h>
 
 #if HAVE_BOEHM_GC
 
@@ -48,6 +49,7 @@ void *pthread_get_stackaddr_np(pthread_t);
 #define MIN_BOEHM_MAX_HEAP_SIZE (MIN_BOEHM_MAX_HEAP_SIZE_IN_MB << 20)
 
 static gboolean gc_initialized = FALSE;
+static mono_mutex_t mono_gc_lock;
 
 static void*
 boehm_thread_register (MonoThreadInfo* info, void *baseptr);
@@ -187,6 +189,7 @@ mono_gc_base_init (void)
 #endif
        
        mono_threads_init (&cb, sizeof (MonoThreadInfo));
+       mono_mutex_init (&mono_gc_lock);
 
        mono_gc_enable_events ();
        gc_initialized = TRUE;
@@ -976,11 +979,20 @@ mono_gc_get_managed_allocator_by_type (int atype)
 
        mono_tls_key_set_offset (TLS_KEY_BOEHM_GC_THREAD, offset);
 
-       mono_loader_lock ();
        res = alloc_method_cache [atype];
-       if (!res)
-               res = alloc_method_cache [atype] = create_allocator (atype, TLS_KEY_BOEHM_GC_THREAD);
-       mono_loader_unlock ();
+       if (res)
+               return res;
+
+       res = create_allocator (atype, TLS_KEY_BOEHM_GC_THREAD);
+       mono_mutex_lock (&mono_gc_lock);
+       if (alloc_method_cache [atype]) {
+               mono_free_method (res);
+               res = alloc_method_cache [atype];
+       } else {
+               mono_memory_barrier ();
+               alloc_method_cache [atype] = res;
+       }
+       mono_mutex_unlock (&mono_gc_lock);
        return res;
 }
 
index d9db61bfd4ed7d577569fb8a359bddfbee2b0228..911dbadf4730a33fad9848b35f5a29b2e8811876 100644 (file)
@@ -71,7 +71,6 @@ static void mono_generic_class_setup_parent (MonoClass *klass, MonoClass *gklass
 
 
 void (*mono_debugger_class_init_func) (MonoClass *klass) = NULL;
-void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass) = NULL;
 
 
 /*
@@ -2169,9 +2168,6 @@ mono_class_setup_methods (MonoClass *class)
 
        class->methods = methods;
 
-       if (mono_debugger_class_loaded_methods_func)
-               mono_debugger_class_loaded_methods_func (class);
-
        mono_loader_unlock ();
 }
 
@@ -2923,9 +2919,12 @@ get_implicit_generic_array_interfaces (MonoClass *class, int *num, int *is_enume
         * We collect the types needed to build the
         * instantiations in interfaces at intervals of 3/5, because 3/5 are
         * the generic interfaces needed to implement.
+        *
+        * On 4.5, as an optimization, we don't expand ref classes for the variant generic interfaces
+        * (IEnumerator, IReadOnlyList and IReadOnlyColleciton). The regular dispatch code can handle those cases.
         */
-       nifaces = generic_ireadonlylist_class ? 5 : 3;
        if (eclass->valuetype) {
+               nifaces = generic_ireadonlylist_class ? 5 : 3;
                fill_valuetype_array_derived_types (valuetype_types, eclass, original_rank);
 
                /* IList, ICollection, IEnumerable, IReadOnlyList`1 */
@@ -2947,6 +2946,7 @@ get_implicit_generic_array_interfaces (MonoClass *class, int *num, int *is_enume
                int idepth = eclass->idepth;
                if (!internal_enumerator)
                        idepth--;
+               nifaces = generic_ireadonlylist_class ? 2 : 3;
 
                // FIXME: This doesn't seem to work/required for generic params
                if (!(eclass->this_arg.type == MONO_TYPE_VAR || eclass->this_arg.type == MONO_TYPE_MVAR || (eclass->image->dynamic && !eclass->wastypebuilder)))
@@ -3010,10 +3010,16 @@ get_implicit_generic_array_interfaces (MonoClass *class, int *num, int *is_enume
 
                interfaces [i + 0] = inflate_class_one_arg (mono_defaults.generic_ilist_class, iface);
                interfaces [i + 1] = inflate_class_one_arg (generic_icollection_class, iface);
-               interfaces [i + 2] = inflate_class_one_arg (generic_ienumerable_class, iface);
-               if (generic_ireadonlylist_class) {
-                       interfaces [i + 3] = inflate_class_one_arg (generic_ireadonlylist_class, iface);
-                       interfaces [i + 4] = inflate_class_one_arg (generic_ireadonlycollection_class, iface);
+
+               if (eclass->valuetype) {
+                       interfaces [i + 2] = inflate_class_one_arg (generic_ienumerable_class, iface);
+                       if (generic_ireadonlylist_class) {
+                               interfaces [i + 3] = inflate_class_one_arg (generic_ireadonlylist_class, iface);
+                               interfaces [i + 4] = inflate_class_one_arg (generic_ireadonlycollection_class, iface);
+                       }
+               } else {
+                       if (!generic_ireadonlylist_class)
+                               interfaces [i + 2] = inflate_class_one_arg (generic_ienumerable_class, iface);
                }
        }
        if (internal_enumerator) {
@@ -3607,10 +3613,6 @@ mono_class_setup_vtable_full (MonoClass *class, GList *in_setup)
        if (class->vtable)
                return;
 
-       if (mono_debug_using_mono_debugger ())
-               /* The debugger currently depends on this */
-               mono_class_setup_methods (class);
-
        if (MONO_CLASS_IS_INTERFACE (class)) {
                /* This sets method->slot for all methods if this is an interface */
                mono_class_setup_methods (class);
@@ -5484,7 +5486,7 @@ mono_class_setup_parent (MonoClass *class, MonoClass *parent)
  *  - supertypes: array of classes: each element has a class in the hierarchy
  *    starting from @class up to System.Object
  * 
- * LOCKING: this assumes the loader lock is held
+ * LOCKING: This function is atomic, in case of contention we waste memory.
  */
 void
 mono_class_setup_supertypes (MonoClass *class)
@@ -5492,7 +5494,8 @@ mono_class_setup_supertypes (MonoClass *class)
        int ms;
        MonoClass **supertypes;
 
-       if (class->supertypes)
+       mono_atomic_load_acquire (supertypes, void*, &class->supertypes);
+       if (supertypes)
                return;
 
        if (class->parent && !class->parent->supertypes)
@@ -8654,7 +8657,7 @@ mono_class_get_virtual_methods (MonoClass* klass, gpointer *iter)
        MonoMethod** method;
        if (!iter)
                return NULL;
-       if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass) || mono_debug_using_mono_debugger ()) {
+       if (klass->methods || !MONO_CLASS_HAS_STATIC_METADATA (klass)) {
                if (!*iter) {
                        mono_class_setup_methods (klass);
                        /*
index 42601954129da0eba7f350451ca9ba0c4a11a13f..8503fbf3f4e3b7e980b2e955b62390a725c31251 100644 (file)
@@ -2000,11 +2000,9 @@ cominterop_get_ccw (MonoObject* object, MonoClass* itf)
                        cominterop_setup_marshal_context (&m, adjust_method);
                        m.mb = mb;
                        mono_marshal_emit_managed_wrapper (mb, sig_adjusted, mspecs, &m, adjust_method, 0);
-                       mono_loader_lock ();
                        mono_cominterop_lock ();
                        wrapper_method = mono_mb_create_method (mb, m.csig, m.csig->param_count + 16);
                        mono_cominterop_unlock ();
-                       mono_loader_unlock ();
 
                        vtable [vtable_index--] = mono_compile_method (wrapper_method);
 
@@ -2208,11 +2206,9 @@ cominterop_get_managed_wrapper_adjusted (MonoMethod *method)
 
        mono_mb_emit_byte (mb, CEE_RET);
 
-       mono_loader_lock ();
        mono_cominterop_lock ();
        res = mono_mb_create_method (mb, sig_native, sig_native->param_count + 16);     
        mono_cominterop_unlock ();
-       mono_loader_unlock ();
 
        mono_mb_free (mb);
 
index c331662aec7b5b91e4997bea0240df554d5dcae6..5205078c18e0961eb05052ec851cc04ce6184e7c 100644 (file)
@@ -296,1111 +296,1111 @@ static const DateTimeFormatEntry datetime_format_entries [] = {
 
 
 static const NumberFormatEntry number_format_entries [] = {
-       {35403, 35406, 35403, 35406, 35403, 35406, 35409, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35465, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35485, 35494, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35502, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35502, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35506, 35471, 35473, 35477, 35510, 35522, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35559, 35573, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35607, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35632, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35636, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35639, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 0, 35477, 35588, 35644, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35502, 35471, 35654, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35670, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35674, 35684, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35693, 35471, 35473, 35477, 35697, 35716, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35735, 35471, 35473, 35477, 35588, 35644, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 35473, 35477, 35742, 35751, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35760, 35471, 35768, 35477, 35784, 35812, 2601, 35458, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35839, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 2, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 0, 35477, 35510, 35522, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35842, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35534, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35853, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35857, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35860, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 3, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35865, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35868, 35471, 35872, 35477, 35439, 35449, 2601, 35458, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35888, 35902, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35915, 35471, 35918, 35477, 35932, 35944, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35955, 35471, 35846, 35477, 35958, 35969, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 35979, 35419, 0, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35983, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35987, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35993, 36003, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36016, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36019, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36026, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36030, 35471, 36037, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36063, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 36095, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36121, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 1, 1, 1, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36152, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36162, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36167, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36170, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 1, 1, 2, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36174, 35471, 0, 35477, 35439, 35449, 2601, 35458, 4, 1, 0, 0, 0, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36178, 35471, 0, 35477, 35439, 35449, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36186, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 1, 1, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35616, 35624, 2601, 35458, 8, 3, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36193, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36206, 35419, 0, 35477, 35439, 35449, 2601, 35458, 3, 0, 4, 2, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36209, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36213, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36213, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36162, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36217, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36167, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 35409, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35465, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35485, 35494, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36220, 35471, 36224, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35506, 35471, 35473, 35477, 35510, 35522, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35559, 35573, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35607, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35632, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35636, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35639, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 0, 35477, 35588, 35644, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35502, 35471, 35654, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35670, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35674, 35684, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35534, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35693, 35471, 35473, 35477, 35697, 35716, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35735, 35471, 35473, 35477, 35588, 35644, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 35473, 35477, 35742, 35751, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35760, 35471, 35768, 35477, 35784, 35812, 2601, 35458, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35839, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 2, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 0, 35477, 35510, 35522, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35842, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35534, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35853, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35857, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35860, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 3, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35865, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35868, 35471, 35872, 35477, 35439, 35449, 2601, 35458, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35888, 35902, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35915, 35471, 35918, 35477, 35932, 35944, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35955, 35471, 35846, 35477, 35958, 35969, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36019, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 35979, 35419, 0, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35983, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35987, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36234, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35993, 36003, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36016, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36019, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36026, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36239, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36037, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36063, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 36095, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36121, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 1, 1, 1, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 36152, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {763, 35460, 763, 35460, 763, 35460, 36162, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36167, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36170, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 1, 1, 2, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36174, 35471, 0, 35477, 35439, 35449, 2601, 35458, 4, 1, 0, 0, 0, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36012, 35471, 0, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36178, 35471, 0, 35477, 35439, 35449, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36186, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 1, 1, {3, 0}, {3, 0}, {3, 0}},
-       {763, 35460, 763, 35460, 763, 35460, 36193, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36206, 35419, 0, 35477, 35439, 35449, 2601, 35458, 3, 0, 4, 2, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36209, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36213, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36213, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35534, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36213, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36162, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36217, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36167, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36245, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35502, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 36255, 763, 36255, 763, 36255, 0, 35471, 35473, 35477, 35537, 35548, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36167, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 36255, 763, 36255, 763, 36255, 0, 35471, 0, 35477, 35588, 35644, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35674, 35684, 2601, 35458, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35534, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35473, 35477, 35588, 35644, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36257, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35481, 35471, 0, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35586, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36265, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36272, 35471, 36037, 35477, 35439, 35449, 2601, 35458, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36162, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36276, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 36224, 35477, 35439, 35449, 2601, 35458, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35458, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35586, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 15, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35846, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36286, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 0, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 7774, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 36255, 763, 36255, 763, 36255, 0, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36296, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 0, 35471, 36224, 35477, 35439, 35449, 2601, 35458, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 36255, 763, 36255, 763, 36255, 0, 35471, 35473, 35477, 35537, 35548, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36306, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36310, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35481, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36320, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36324, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36327, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 10511, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36337, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36343, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36353, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36359, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36369, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36374, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36384, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36388, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36396, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36406, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35481, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36416, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36209, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 9, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36426, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36436, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36446, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35403, 35406, 35403, 35406, 35403, 35406, 36450, 35419, 35422, 35436, 35439, 35449, 2601, 35458, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36012, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
-       {35460, 763, 35460, 763, 35460, 763, 36460, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36463, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 2471, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36467, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35458, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
-       {35460, 763, 35460, 763, 35460, 763, 36470, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36478, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36257, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36483, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35534, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36234, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36265, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35439, 35449, 2601, 35458, 5, 1, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36486, 35471, 36224, 35477, 35439, 35449, 2601, 35458, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36486, 35471, 36224, 35477, 35439, 35449, 2601, 35458, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 35534, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 763, 35460, 763, 35460, 763, 36478, 35471, 35473, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35460, 35460, 35460, 35460, 35460, 36019, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36239, 35471, 0, 35477, 35439, 35449, 2601, 35458, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 36162, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
-       {35460, 35462, 35460, 35462, 35460, 35462, 0, 35471, 0, 35477, 35616, 35624, 2601, 35458, 8, 3, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
-       {763, 35460, 763, 35460, 763, 35460, 36213, 35471, 0, 35477, 35439, 35449, 2601, 35458, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}}
+       {763, 35403, 35405, 35408, 35405, 35408, 35411, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35465, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35485, 35494, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35502, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35502, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35506, 35471, 35473, 35477, 35510, 35522, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35559, 35573, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35607, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35632, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35636, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35639, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 0, 35477, 35588, 35644, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35502, 35471, 35654, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35670, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35674, 35684, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35693, 35471, 35473, 35477, 35697, 35716, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35735, 35471, 35473, 35477, 35588, 35644, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35738, 763, 35740, 763, 35740, 0, 35471, 35473, 35477, 35744, 35753, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35762, 35471, 35770, 35477, 35786, 35814, 2601, 35460, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35841, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 2, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 0, 35477, 35510, 35522, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35844, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 35462, 35403, 35462, 35534, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35855, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35859, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35862, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 3, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35867, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35870, 35471, 35874, 35477, 35441, 35451, 2601, 35460, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35890, 35904, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35917, 35471, 35920, 35477, 35934, 35946, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 763, 35403, 763, 35403, 35957, 35471, 35848, 35477, 35960, 35971, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35981, 35462, 35403, 35403, 35403, 35403, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {239, 35403, 35405, 35408, 35405, 35408, 35983, 35421, 0, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35987, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 763, 35403, 763, 35991, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35997, 36007, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36020, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {2601, 35462, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {2601, 35462, 35403, 35462, 35403, 35462, 36023, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36030, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36034, 35471, 36041, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36067, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 36099, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36125, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 1, 1, 1, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36156, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36166, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36171, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 763, 35403, 763, 36174, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 1, 1, 2, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36178, 35471, 0, 35477, 35441, 35451, 2601, 35460, 4, 1, 0, 0, 0, 0, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36182, 35471, 0, 35477, 35441, 35451, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36190, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 2, 1, 1, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35616, 35624, 2601, 35460, 8, 3, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36197, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
+       {35405, 35408, 35405, 35408, 35405, 35408, 36210, 35421, 0, 35477, 35441, 35451, 2601, 35460, 3, 0, 4, 2, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36213, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36217, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36217, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36166, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35403, 35403, 35403, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 763, 35740, 763, 35740, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35403, 35403, 35403, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 36221, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36171, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 35411, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35465, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35485, 35494, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36224, 35471, 36228, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35506, 35471, 35473, 35477, 35510, 35522, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35559, 35573, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35607, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35632, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35636, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35639, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 0, 35477, 35588, 35644, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35502, 35471, 35654, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35670, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35674, 35684, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35534, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35693, 35471, 35473, 35477, 35697, 35716, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35735, 35471, 35473, 35477, 35588, 35644, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35738, 763, 35740, 763, 35740, 0, 35471, 35473, 35477, 35744, 35753, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35762, 35471, 35770, 35477, 35786, 35814, 2601, 35460, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35841, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 2, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 0, 35477, 35510, 35522, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35844, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 35462, 35403, 35462, 35534, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35855, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35859, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35862, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 3, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35867, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35870, 35471, 35874, 35477, 35441, 35451, 2601, 35460, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35890, 35904, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35917, 35471, 35920, 35477, 35934, 35946, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 763, 35403, 763, 35403, 35957, 35471, 35848, 35477, 35960, 35971, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35981, 35462, 35403, 35403, 35403, 35403, 36023, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {239, 35403, 35405, 35408, 35405, 35408, 35983, 35421, 0, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35987, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 763, 35403, 763, 35991, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 36238, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35997, 36007, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 0, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36020, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {2601, 35462, 35403, 35462, 35403, 35462, 36023, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36030, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 36243, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36041, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36067, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 36099, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36125, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 1, 1, 1, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 36156, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 763, 35403, 763, 35403, 36166, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36171, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 763, 35403, 763, 36174, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 1, 1, 2, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36178, 35471, 0, 35477, 35441, 35451, 2601, 35460, 4, 1, 0, 0, 0, 0, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36016, 35471, 0, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36182, 35471, 0, 35477, 35441, 35451, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36190, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 2, 1, 1, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 763, 35403, 763, 35403, 36197, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 2}, {3, 2}},
+       {35405, 35408, 35405, 35408, 35405, 35408, 36210, 35421, 0, 35477, 35441, 35451, 2601, 35460, 3, 0, 4, 2, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36213, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36217, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36217, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 10511, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 2, 2, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35534, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36217, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36166, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35403, 35403, 35403, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35403, 35403, 35403, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 36221, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36171, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36249, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35502, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 35473, 35477, 35537, 35548, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36171, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 0, 35477, 35588, 35644, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35674, 35684, 2601, 35460, 12, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35534, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 35462, 35403, 35462, 35481, 35471, 35473, 35477, 35588, 35644, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 36259, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35481, 35471, 0, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35586, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 36267, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35403, 35403, 35403, 36274, 35471, 36041, 35477, 35441, 35451, 2601, 35460, 12, 2, 2, 2, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {763, 35403, 35403, 35462, 35403, 35462, 36166, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36278, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 36228, 35477, 35441, 35451, 2601, 35460, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35460, 9, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35586, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 15, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35848, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36288, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 0, 0, 0, 3, 3, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35537, 35548, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 7774, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36298, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 0, 35471, 36228, 35477, 35441, 35451, 2601, 35460, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35738, 763, 35738, 763, 35738, 0, 35471, 35473, 35477, 35537, 35548, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36308, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 0, 0, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36312, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35481, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36322, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35481, 35471, 35473, 35477, 35616, 35624, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36326, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36329, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 3, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 10511, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 2, 2, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36339, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36345, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 3, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 1, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36355, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36361, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36371, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36376, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36386, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36390, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36398, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 3, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36408, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35481, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36418, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 3, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36213, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 9, 2, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36428, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36438, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 3, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36448, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35405, 35408, 35405, 35408, 36452, 35421, 35424, 35438, 35441, 35451, 2601, 35460, 3, 2, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36016, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, 2}, {3, 2}, {3, 2}},
+       {35403, 763, 35403, 763, 35403, 763, 36462, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36465, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 2471, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36469, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 14, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 35586, 35471, 35473, 35477, 35588, 35598, 2601, 35460, 0, 0, 0, 0, 1, 2, 2, 2, {3, -1}, {3, 0}, {3, 0}},
+       {35403, 763, 35403, 763, 35403, 763, 36472, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36480, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 36259, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36485, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35534, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 763, 35403, 763, 36238, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 36267, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35441, 35451, 2601, 35460, 5, 1, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36488, 35471, 36228, 35477, 35441, 35451, 2601, 35460, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36488, 35471, 36228, 35477, 35441, 35451, 2601, 35460, 0, 0, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 35534, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 12, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35403, 763, 35403, 763, 35403, 763, 36480, 35471, 35473, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {35981, 35462, 35403, 35403, 35403, 35403, 36023, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {35403, 35462, 35403, 35462, 35403, 35462, 36243, 35471, 0, 35477, 35441, 35451, 2601, 35460, 8, 3, 1, 1, 1, 0, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 35403, 35462, 35403, 35462, 36166, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 0, 1, 1, 1, 2, 2, 2, {3, 0}, {3, 0}, {3, 0}},
+       {763, 35403, 35403, 35462, 35403, 35462, 0, 35471, 0, 35477, 35616, 35624, 2601, 35460, 8, 3, 0, 0, 3, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}},
+       {763, 35403, 763, 35403, 763, 35403, 36217, 35471, 0, 35477, 35441, 35451, 2601, 35460, 2, 2, 0, 0, 1, 2, 2, 2, {3, -1}, {3, -1}, {3, -1}}
 };
 
 
 static const CultureInfoEntry culture_entries [] = {
-       {0x0001, 0x007F, 768, -1, 36490, 36493, 36500, 36515, 36519, 36490, 0, {0, 0, 36523, 0}, 0, 0, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x0002, 0x007F, 257, -1, 36551, 36554, 36564, 36583, 36587, 36551, 0, {36591, 0, 0, 0}, 1, 1, { 1251, 21025, 10007, 866, 0, ';' }},
-       {0x0003, 0x007F, 257, -1, 36633, 36636, 36644, 36652, 36656, 36633, 0, {36660, 0, 0, 0}, 2, 2, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0004, 0x0004, 257, -1, 36680, 36687, 36715, 36722, 36726, 36730, 0, {36733, 0, 0, 0}, 3, 3, { 936, 500, 10008, 936, 0, ',' }},
-       {0x0004, 0x7804, 257, -1, 36740, 36748, 36715, 36722, 36726, 36730, 0, {36733, 0, 0, 0}, 4, 4, { 936, 500, 10008, 936, 0, ',' }},
-       {0x0005, 0x007F, 257, -1, 36769, 36772, 36778, 36788, 36792, 36769, 0, {36796, 0, 0, 0}, 5, 5, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x0006, 0x007F, 257, -1, 36822, 36825, 36832, 36838, 36842, 36822, 0, {36846, 0, 0, 0}, 6, 6, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0007, 0x007F, 257, -1, 36867, 36870, 36877, 36885, 36889, 36867, 0, {36893, 0, 0, 0}, 7, 7, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x0008, 0x007F, 257, -1, 36918, 36921, 36927, 36944, 36948, 36918, 0, {36952, 0, 0, 0}, 8, 8, { 1253, 20273, 10006, 737, 0, ';' }},
-       {0x0009, 0x007F, 257, -1, 36994, 36997, 36997, 37005, 37009, 36994, 0, {37013, 0, 0, 0}, 9, 9, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x000A, 0x007F, 257, -1, 37032, 37035, 37043, 37052, 37056, 37032, 0, {37060, 0, 0, 0}, 10, 10, { 1252, 20284, 10000, 850, 0, ';' }},
-       {0x000B, 0x007F, 257, -1, 37082, 37085, 37093, 37099, 37103, 37082, 0, {37107, 0, 0, 0}, 11, 11, { 1252, 20278, 10000, 850, 0, ';' }},
-       {0x000C, 0x007F, 257, -1, 37132, 37135, 37142, 37152, 37156, 37132, 0, {37160, 0, 0, 0}, 12, 12, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x000D, 0x007F, 257, -1, 37182, 37185, 37192, 37203, 37207, 37182, 0, {37211, 0, 0, 0}, 13, 13, { 1255, 500, 10005, 862, 1, ',' }},
-       {0x000E, 0x007F, 257, -1, 37244, 37247, 37257, 37264, 37268, 37244, 0, {37272, 0, 0, 0}, 14, 14, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x000F, 0x007F, 257, -1, 37288, 37291, 37301, 37311, 37315, 37288, 0, {37319, 0, 0, 0}, 15, 15, { 1252, 20871, 10079, 850, 0, ';' }},
-       {0x0010, 0x007F, 257, -1, 37339, 37342, 37350, 37359, 37363, 37339, 0, {37060, 0, 0, 0}, 16, 16, { 1252, 20280, 10000, 850, 0, ';' }},
-       {0x0011, 0x007F, 257, -1, 37367, 37370, 37379, 37389, 37393, 37367, 0, {37397, 0, 0, 0}, 17, 17, { 932, 20290, 10001, 932, 0, ',' }},
-       {0x0012, 0x007F, 257, -1, 37424, 37427, 37434, 37444, 37448, 37424, 0, {37452, 0, 0, 0}, 18, 18, { 949, 20833, 10003, 949, 0, ',' }},
-       {0x0013, 0x007F, 257, -1, 37462, 37465, 37471, 37482, 37486, 37462, 0, {37490, 0, 0, 0}, 19, 19, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0014, 0x007F, 257, -1, 37512, 37515, 37525, 37531, 37535, 37539, 0, {36846, 0, 0, 0}, 20, 20, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0015, 0x007F, 257, -1, 37542, 37545, 37552, 37559, 37563, 37542, 0, {37567, 0, 0, 0}, 21, 21, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x0016, 0x007F, 257, -1, 37591, 37594, 37605, 37616, 37620, 37591, 0, {37624, 0, 0, 0}, 22, 22, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0017, 0x007F, 257, -1, 37647, 37650, 37658, 37668, 37672, 37647, 0, {37676, 0, 0, 0}, 23, 23, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x0018, 0x007F, 257, -1, 37696, 37699, 37708, 37717, 37721, 37696, 0, {37725, 0, 0, 0}, 24, 24, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x0019, 0x007F, 257, -1, 37744, 37747, 37755, 37770, 37774, 37744, 0, {37778, 0, 0, 0}, 25, 25, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x001A, 0x007F, 257, -1, 37824, 37827, 37836, 37845, 37849, 37824, 0, {37853, 0, 0, 0}, 26, 26, { 1250, 500, 10082, 852, 0, ';' }},
-       {0x001B, 0x007F, 257, -1, 37876, 37879, 37886, 37898, 37902, 37876, 0, {37906, 0, 0, 0}, 27, 27, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x001C, 0x007F, 257, -1, 37930, 37933, 37942, 37948, 37952, 37930, 0, {0, 0, 0, 0}, 28, 28, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x001D, 0x007F, 257, -1, 37956, 37959, 37967, 37975, 37979, 37956, 0, {36846, 0, 0, 0}, 29, 29, { 1252, 20278, 10000, 850, 0, ';' }},
-       {0x001E, 0x007F, 512, -1, 37983, 37986, 37991, 38001, 38005, 37983, 0, {0, 38009, 0, 0}, 30, 30, { 874, 20838, 10021, 874, 0, ',' }},
-       {0x001F, 0x007F, 257, -1, 38040, 38043, 38051, 38060, 38064, 38040, 0, {38068, 0, 0, 0}, 31, 31, { 1254, 20905, 10081, 857, 0, ';' }},
-       {0x0020, 0x007F, 257, -1, 38082, 38085, 38090, 38099, 38103, 38082, 0, {38107, 0, 0, 0}, 32, 32, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x0021, 0x007F, 257, -1, 38137, 38140, 38151, 38168, 38172, 38137, 0, {38176, 0, 0, 0}, 33, 33, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0022, 0x007F, 257, -1, 38195, 38198, 38208, 38229, 38233, 38195, 0, {38237, 0, 0, 0}, 34, 34, { 1251, 500, 10017, 866, 0, ';' }},
-       {0x0023, 0x007F, 257, -1, 38283, 38286, 38297, 38318, 38322, 38283, 0, {38326, 0, 0, 0}, 35, 35, { 1251, 500, 10007, 866, 0, ';' }},
-       {0x0024, 0x007F, 257, -1, 38368, 38371, 38381, 38395, 38399, 38368, 0, {38403, 0, 0, 0}, 36, 36, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x0025, 0x007F, 257, -1, 38425, 38428, 38437, 38443, 38447, 38425, 0, {38451, 0, 0, 0}, 37, 37, { 1257, 500, 10029, 775, 0, ';' }},
-       {0x0026, 0x007F, 257, -1, 38471, 38474, 38482, 38492, 38496, 38471, 0, {38500, 0, 0, 0}, 38, 38, { 1257, 500, 10029, 775, 0, ';' }},
-       {0x0027, 0x007F, 257, -1, 38519, 38522, 38533, 38543, 38547, 38519, 0, {38551, 0, 0, 0}, 39, 39, { 1257, 500, 10029, 775, 0, ';' }},
-       {0x0028, 0x007F, 257, -1, 38574, 38577, 0, 38583, 38587, 38574, 0, {0, 0, 0, 0}, 40, 40, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0029, 0x007F, 257, -1, 38591, 38594, 38602, 38613, 38617, 38591, 0, {38621, 0, 0, 0}, 41, 41, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x002A, 0x007F, 257, -1, 38645, 38648, 38659, 38674, 4121, 38645, 0, {38678, 0, 0, 0}, 42, 42, { 1258, 500, 10000, 1258, 0, ',' }},
-       {0x002B, 0x007F, 257, -1, 38693, 38696, 38705, 38720, 38724, 38693, 0, {0, 0, 0, 0}, 43, 43, { 0, 500, 2, 1, 0, ',' }},
-       {0x002C, 0x007F, 257, -1, 14519, 38728, 38740, 38754, 38758, 14519, 0, {38762, 0, 0, 0}, 44, 44, { 1254, 20905, 10081, 857, 0, ';' }},
-       {0x002D, 0x007F, 257, -1, 38780, 38783, 38790, 38798, 38802, 38780, 0, {38806, 0, 0, 0}, 45, 45, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x002F, 0x007F, 257, -1, 38826, 38829, 38840, 38861, 38865, 38826, 0, {38869, 0, 0, 0}, 46, 46, { 1251, 500, 10007, 866, 0, ';' }},
-       {0x0032, 0x007F, 257, -1, 38913, 38916, 38923, 38932, 38936, 38913, 0, {0, 0, 0, 0}, 47, 47, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0034, 0x007F, 257, -1, 38940, 38943, 38949, 38958, 38962, 38940, 0, {0, 0, 0, 0}, 48, 48, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0035, 0x007F, 257, -1, 38966, 38969, 38974, 38982, 38986, 38966, 0, {38990, 0, 0, 0}, 49, 49, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0036, 0x007F, 257, -1, 39011, 39014, 39014, 39024, 39028, 39011, 0, {39032, 0, 0, 0}, 50, 50, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0037, 0x007F, 257, -1, 39052, 39055, 39064, 39086, 39090, 39052, 0, {39094, 0, 0, 0}, 51, 51, { 0, 500, 2, 1, 0, ';' }},
-       {0x0038, 0x007F, 257, -1, 39159, 39162, 39170, 39180, 39184, 39159, 0, {0, 0, 0, 0}, 52, 52, { 1252, 20277, 10079, 850, 0, ';' }},
-       {0x0039, 0x007F, 257, -1, 39188, 39191, 39197, 39216, 39220, 39188, 0, {39224, 0, 0, 0}, 53, 53, { 0, 500, 2, 1, 0, ',' }},
-       {0x003A, 0x007F, 257, -1, 39265, 39268, 39276, 39282, 39286, 39265, 0, {39290, 0, 0, 0}, 54, 54, { 0, 500, 2, 1, 0, ',' }},
-       {0x003B, 0x007F, 257, -1, 39311, 39314, 39328, 39345, 39349, 39311, 0, {0, 0, 0, 0}, 55, 55, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x003C, 0x007F, 257, -1, 39353, 39356, 39362, 39370, 39374, 39353, 0, {39378, 0, 0, 0}, 56, 56, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x003E, 0x007F, 257, -1, 39399, 39402, 39408, 39422, 39426, 39399, 0, {39430, 0, 0, 0}, 57, 57, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x003F, 0x007F, 257, -1, 39447, 39450, 39457, 39477, 39481, 39447, 0, {39485, 0, 0, 0}, 58, 58, { 0, 500, 2, 1, 0, ';' }},
-       {0x0040, 0x007F, 257, -1, 39527, 39530, 39538, 39551, 39555, 39527, 0, {0, 0, 0, 0}, 59, 59, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0041, 0x007F, 257, -1, 39559, 39562, 39570, 39580, 39584, 39559, 0, {39588, 0, 0, 0}, 60, 60, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x0043, 0x007F, 257, -1, 39609, 39612, 39618, 39629, 39633, 39609, 0, {0, 0, 0, 0}, 61, 61, { 1254, 500, 10029, 857, 0, ';' }},
-       {0x0045, 0x007F, 257, -1, 39637, 39640, 39648, 39664, 39668, 39637, 0, {39672, 0, 0, 0}, 62, 62, { 0, 500, 2, 1, 0, ',' }},
-       {0x0046, 0x007F, 257, -1, 39737, 39740, 39748, 39767, 39771, 39737, 0, {0, 0, 0, 0}, 63, 63, { 0, 500, 2, 1, 0, ',' }},
-       {0x0047, 0x007F, 257, -1, 39775, 39778, 39787, 39809, 39813, 39775, 0, {39817, 0, 0, 0}, 64, 64, { 0, 500, 2, 1, 0, ',' }},
-       {0x0048, 0x007F, 257, -1, 14525, 39873, 39879, 39895, 39899, 14525, 0, {0, 0, 0, 0}, 65, 65, { 0, 500, 2, 1, 0, ',' }},
-       {0x0049, 0x007F, 257, -1, 39903, 39906, 39912, 39928, 39932, 39903, 0, {39936, 0, 0, 0}, 66, 66, { 0, 500, 2, 1, 0, ',' }},
-       {0x004A, 0x007F, 257, -1, 40001, 40004, 40011, 40030, 40034, 40001, 0, {40038, 0, 0, 0}, 67, 67, { 0, 500, 2, 1, 0, ',' }},
-       {0x004B, 0x007F, 257, -1, 35839, 40103, 40111, 40127, 40131, 35839, 0, {40135, 0, 0, 0}, 68, 68, { 0, 500, 2, 1, 0, ',' }},
-       {0x004C, 0x007F, 257, -1, 40206, 40209, 40219, 40238, 40242, 40206, 0, {40246, 0, 0, 0}, 69, 69, { 0, 500, 2, 1, 0, ',' }},
-       {0x004D, 0x007F, 257, -1, 14516, 40296, 40305, 40327, 40331, 14516, 0, {40335, 0, 0, 0}, 70, 70, { 0, 500, 2, 1, 0, ',' }},
-       {0x004E, 0x007F, 257, -1, 40388, 40391, 40399, 40415, 2565, 40388, 0, {40419, 0, 0, 0}, 71, 71, { 0, 500, 2, 1, 0, ',' }},
-       {0x0050, 0x007F, 257, -1, 40481, 40484, 40494, 40507, 40511, 40481, 0, {0, 0, 0, 0}, 72, 72, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0051, 0x007F, 257, -1, 40515, 40518, 40526, 40551, 40555, 40515, 0, {0, 0, 0, 0}, 73, 73, { 0, 500, 2, 1, 0, ',' }},
-       {0x0052, 0x007F, 257, -1, 40559, 40562, 40568, 40576, 40580, 40559, 0, {0, 0, 0, 0}, 74, 74, { 1252, 20285, 10000, 850, 0, ',' }},
-       {0x0053, 0x007F, 257, -1, 40584, 40587, 40593, 40621, 40625, 40584, 0, {0, 0, 0, 0}, 75, 75, { 0, 500, 2, 1, 0, ',' }},
-       {0x0054, 0x007F, 257, -1, 40629, 40632, 40636, 40646, 40650, 40629, 0, {0, 0, 0, 0}, 76, 76, { 0, 500, 2, 1, 0, ',' }},
-       {0x0056, 0x007F, 257, -1, 40654, 40657, 40666, 40673, 40677, 40654, 0, {37060, 0, 0, 0}, 77, 77, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0057, 0x007F, 257, -1, 40681, 40685, 40693, 40712, 40681, 40681, 0, {0, 0, 0, 0}, 78, 78, { 0, 500, 2, 1, 0, ',' }},
-       {0x005B, 0x007F, 257, -1, 40716, 40719, 40727, 40743, 40747, 40716, 0, {40751, 0, 0, 0}, 79, 79, { 0, 500, 2, 1, 0, ',' }},
-       {0x005E, 0x007F, 257, -1, 7865, 40773, 40781, 40794, 40798, 7865, 0, {40802, 0, 0, 0}, 80, 80, { 0, 500, 2, 1, 0, ';' }},
-       {0x005F, 0x007F, 257, -1, 40847, 40851, 40877, 40887, 40847, 40847, 0, {0, 0, 0, 0}, 81, 81, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0061, 0x007F, 257, -1, 2059, 40891, 40898, 40917, 40921, 2059, 0, {40925, 0, 0, 0}, 82, 82, { 0, 500, 2, 1, 0, ',' }},
-       {0x0063, 0x007F, 1024, -1, 40975, 40978, 40985, 40994, 40998, 40975, 0, {0, 0, 0, 0}, 83, 83, { 0, 500, 2, 1, 1, ';' }},
-       {0x0064, 0x007F, 257, -1, 41002, 41006, 41006, 41015, 41002, 41002, 0, {41019, 0, 0, 0}, 84, 84, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x0068, 0x007F, 257, -1, 41042, 41045, 41045, 41051, 41055, 41042, 0, {0, 0, 0, 0}, 85, 85, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x006A, 0x007F, 257, -1, 41059, 41062, 41069, 41084, 41088, 41059, 0, {0, 0, 0, 0}, 86, 86, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x006C, 0x007F, 257, -1, 41092, 41096, 41111, 41128, 41092, 41092, 0, {0, 0, 0, 0}, 87, 87, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x006F, 0x007F, 257, -1, 41132, 41135, 41147, 41159, 41163, 41132, 0, {0, 0, 0, 0}, 88, 88, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0070, 0x007F, 257, -1, 14510, 41167, 41167, 41172, 41176, 14510, 0, {0, 0, 0, 0}, 89, 89, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x0078, 0x007F, 257, -1, 41180, 41183, 41194, 41204, 41208, 41180, 0, {41212, 0, 0, 0}, 90, 90, { 0, 500, 2, 1, 0, ',' }},
-       {0x007E, 0x007F, 257, -1, 41225, 41228, 41235, 41245, 41249, 41225, 0, {41253, 0, 0, 0}, 91, 91, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0082, 0x007F, 257, -1, 41273, 41276, 41284, 41292, 41296, 41273, 0, {0, 0, 0, 0}, 92, 92, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0084, 0x007F, 257, -1, 41300, 41304, 41317, 41336, 41300, 41300, 0, {41340, 0, 0, 0}, 93, 93, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0085, 0x007F, 257, -1, 41365, 41369, 41375, 41393, 41365, 41365, 0, {0, 0, 0, 0}, 94, 94, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0087, 0x007F, 257, -1, 41397, 41400, 41400, 41412, 41416, 41397, 0, {0, 0, 0, 0}, 95, 95, { 1252, 37, 10000, 437, 0, ';' }},
-       {0x0091, 0x007F, 257, -1, 41420, 41423, 41439, 41449, 41453, 41420, 0, {41457, 0, 0, 0}, 96, 96, { 1252, 20285, 10000, 850, 0, ',' }},
-       {0x0401, 0x0001, 768, 98, 41482, 41488, 41510, 36515, 36519, 36490, 13258, {0, 0, 36523, 0}, 97, 97, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x0402, 0x0002, 257, 11, 41574, 41580, 41601, 36583, 36587, 36551, 41639, {36591, 0, 0, 0}, 98, 98, { 1251, 21025, 10007, 866, 0, ';' }},
-       {0x0403, 0x0003, 257, 32, 41642, 41648, 41664, 36652, 36656, 36633, 41682, {36660, 0, 0, 0}, 99, 99, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0404, 0x7C04, 257, 110, 41685, 41691, 41713, 41729, 36726, 36730, 41733, {41736, 0, 0, 0}, 100, 100, { 950, 500, 10002, 950, 0, ',' }},
-       {0x0405, 0x0005, 257, 24, 41743, 41749, 41772, 36788, 36792, 36769, 41802, {36796, 0, 0, 0}, 101, 101, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x0406, 0x0006, 257, 26, 41805, 41811, 41828, 36838, 36842, 36822, 41844, {36846, 0, 0, 0}, 102, 102, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0407, 0x0007, 257, 25, 41847, 41853, 41870, 36885, 36889, 36867, 41892, {36893, 0, 0, 0}, 103, 103, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x0408, 0x0008, 257, 40, 41895, 41901, 41916, 36944, 36948, 36918, 41948, {36952, 0, 0, 0}, 104, 104, { 1253, 20273, 10006, 737, 0, ';' }},
-       {0x0409, 0x0009, 257, 112, 41951, 41957, 41957, 37005, 37009, 36994, 41981, {37013, 0, 0, 0}, 105, 105, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x040B, 0x000B, 257, 34, 41984, 41990, 42008, 37099, 37103, 37082, 42022, {37107, 0, 0, 0}, 106, 106, { 1252, 20278, 10000, 850, 0, ';' }},
-       {0x040C, 0x000C, 257, 36, 42025, 42031, 42047, 37152, 37156, 37132, 42066, {37160, 0, 0, 0}, 107, 107, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x040D, 0x000D, 257, 48, 42069, 42075, 42091, 37203, 37207, 37182, 42115, {37211, 0, 0, 0}, 108, 108, { 1255, 500, 10005, 862, 1, ',' }},
-       {0x040E, 0x000E, 257, 45, 42118, 42124, 42144, 37264, 37268, 37244, 42167, {37272, 0, 0, 0}, 109, 109, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x040F, 0x000F, 257, 52, 42170, 42176, 42196, 37311, 37315, 37288, 42216, {37319, 0, 0, 0}, 110, 110, { 1252, 20871, 10079, 850, 0, ';' }},
-       {0x0410, 0x0010, 257, 53, 42219, 42225, 42241, 37359, 37363, 37339, 42259, {37060, 0, 0, 0}, 111, 111, { 1252, 20280, 10000, 850, 0, ';' }},
-       {0x0411, 0x0011, 257, 56, 42262, 42268, 42285, 37389, 37393, 37367, 42304, {37397, 0, 0, 0}, 112, 112, { 932, 20290, 10001, 932, 0, ',' }},
-       {0x0412, 0x0012, 257, 60, 42307, 42313, 42334, 37444, 37448, 37424, 42359, {37452, 0, 0, 0}, 113, 113, { 949, 20833, 10003, 949, 0, ',' }},
-       {0x0413, 0x0013, 257, 80, 42362, 42368, 42388, 37482, 37486, 37462, 42411, {37490, 0, 0, 0}, 114, 114, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0414, 0x7C14, 257, 81, 42414, 42420, 42447, 37531, 37535, 37539, 42469, {36846, 0, 0, 0}, 115, 115, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0415, 0x0015, 257, 89, 42472, 42478, 42494, 37559, 37563, 37542, 42510, {37567, 0, 0, 0}, 116, 116, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x0416, 0x0016, 257, 15, 42513, 42519, 42539, 37616, 37620, 37591, 42559, {37624, 0, 0, 0}, 117, 117, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0417, 0x0017, 257, 19, 42562, 42568, 42590, 37668, 37672, 37647, 13261, {37676, 0, 0, 0}, 118, 118, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x0418, 0x0018, 257, 94, 42609, 42615, 42634, 37717, 37721, 37696, 42654, {37725, 0, 0, 0}, 119, 119, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x0419, 0x0019, 257, 96, 42657, 42663, 42680, 37770, 37774, 37744, 42710, {37778, 0, 0, 0}, 120, 120, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x041A, 0x001A, 257, 44, 42713, 42719, 42738, 37845, 37849, 37824, 42758, {37853, 0, 0, 0}, 121, 121, { 1250, 500, 10082, 852, 0, ';' }},
-       {0x041B, 0x001B, 257, 102, 42761, 42767, 42785, 37898, 37902, 37876, 42820, {37906, 0, 0, 0}, 122, 122, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x041C, 0x001C, 257, 2, 42823, 42829, 42848, 37948, 37952, 37930, 42867, {0, 0, 0, 0}, 123, 123, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x041D, 0x001D, 257, 99, 42870, 42876, 42893, 37975, 37979, 37956, 42911, {36846, 0, 0, 0}, 124, 124, { 1252, 20278, 10000, 850, 0, ';' }},
-       {0x041E, 0x001E, 512, 105, 42914, 42920, 42936, 38001, 38005, 37983, 42958, {0, 38009, 0, 0}, 125, 125, { 874, 20838, 10021, 874, 0, ',' }},
-       {0x041F, 0x001F, 257, 108, 42961, 42967, 42984, 38060, 38064, 38040, 43004, {38068, 0, 0, 0}, 126, 126, { 1254, 20905, 10081, 857, 0, ';' }},
-       {0x0420, 0x0020, 257, 88, 43007, 43013, 43029, 38099, 38103, 38082, 43055, {38107, 0, 0, 0}, 127, 127, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x0421, 0x0021, 257, 46, 43058, 43064, 43087, 38168, 38172, 38137, 43116, {38176, 0, 0, 0}, 128, 128, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0422, 0x0022, 257, 111, 43119, 43125, 43145, 38229, 38233, 38195, 43183, {38237, 0, 0, 0}, 129, 129, { 1251, 500, 10017, 866, 0, ';' }},
-       {0x0423, 0x0023, 257, 16, 43186, 43192, 43213, 38318, 38322, 38283, 43253, {38326, 0, 0, 0}, 130, 130, { 1251, 500, 10007, 866, 0, ';' }},
-       {0x0424, 0x0024, 257, 101, 43256, 43262, 43283, 38395, 38399, 38368, 43309, {38403, 0, 0, 0}, 131, 131, { 1250, 20880, 10029, 852, 0, ';' }},
-       {0x0425, 0x0025, 257, 30, 43312, 43318, 43337, 38443, 38447, 38425, 43351, {38451, 0, 0, 0}, 132, 132, { 1257, 500, 10029, 775, 0, ';' }},
-       {0x0426, 0x0026, 257, 68, 43354, 43360, 43377, 38492, 38496, 38471, 43397, {38500, 0, 0, 0}, 133, 133, { 1257, 500, 10029, 775, 0, ';' }},
-       {0x0427, 0x0027, 257, 66, 43400, 43406, 43429, 38543, 38547, 38519, 43449, {38551, 0, 0, 0}, 134, 134, { 1257, 500, 10029, 775, 0, ';' }},
-       {0x0428, 0x7C28, 257, 106, 43452, 43463, 0, 38583, 38587, 38574, 43492, {0, 0, 0, 0}, 135, 135, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0429, 0x0029, 257, 51, 43495, 43501, 43516, 38613, 38617, 38591, 43540, {38621, 0, 0, 0}, 136, 136, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x042A, 0x002A, 257, 116, 43543, 43549, 43570, 38674, 4121, 38645, 43598, {38678, 0, 0, 0}, 137, 137, { 1258, 500, 10000, 1258, 0, ',' }},
-       {0x042B, 0x002B, 257, 3, 43601, 43607, 43626, 38720, 38724, 38693, 3781, {0, 0, 0, 0}, 138, 138, { 0, 500, 2, 1, 0, ',' }},
-       {0x042C, 0x782C, 257, 7, 43691, 43702, 43734, 38754, 38758, 14519, 43762, {38762, 0, 0, 0}, 139, 139, { 1254, 20905, 10081, 857, 0, ';' }},
-       {0x042D, 0x002D, 257, 32, 43765, 43771, 43786, 38798, 38802, 38780, 41682, {38806, 0, 0, 0}, 140, 140, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x042F, 0x002F, 257, 73, 43805, 43811, 43834, 38861, 38865, 38826, 43878, {38869, 0, 0, 0}, 141, 141, { 1251, 500, 10007, 866, 0, ';' }},
-       {0x0432, 0x0032, 257, 118, 43881, 43887, 38923, 38932, 38936, 38913, 43909, {0, 0, 0, 0}, 142, 142, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0434, 0x0034, 257, 118, 43912, 43918, 38949, 38958, 38962, 38940, 43909, {0, 0, 0, 0}, 143, 143, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0435, 0x0035, 257, 118, 43939, 43945, 43965, 38982, 38986, 38966, 43909, {38990, 0, 0, 0}, 144, 144, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0436, 0x0036, 257, 118, 43993, 43999, 44024, 39024, 39028, 39011, 43909, {39032, 0, 0, 0}, 145, 145, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0437, 0x0037, 257, 38, 44048, 44054, 44073, 39086, 39090, 39052, 44128, {39094, 0, 0, 0}, 146, 146, { 0, 500, 2, 1, 0, ';' }},
-       {0x0438, 0x0038, 257, 35, 44131, 44137, 44161, 39180, 39184, 39159, 44182, {0, 0, 0, 0}, 147, 147, { 1252, 20277, 10079, 850, 0, ';' }},
-       {0x0439, 0x0039, 257, 49, 44185, 44191, 44205, 39216, 39220, 39188, 44239, {39224, 0, 0, 0}, 148, 148, { 0, 500, 2, 1, 0, ',' }},
-       {0x043A, 0x003A, 257, 75, 44242, 44248, 44264, 39282, 39286, 39265, 44278, {39290, 0, 0, 0}, 149, 149, { 0, 500, 2, 1, 0, ',' }},
-       {0x043B, 0x003B, 257, 81, 44281, 44287, 44310, 39345, 39349, 39311, 42469, {0, 0, 0, 0}, 150, 150, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x043E, 0x003E, 257, 77, 44335, 44341, 44358, 39422, 39426, 39399, 44383, {39430, 0, 0, 0}, 151, 151, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0440, 0x0040, 257, 58, 44386, 44392, 44413, 39551, 39555, 39527, 44449, {0, 0, 0, 0}, 152, 152, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0441, 0x0041, 257, 57, 44452, 44458, 44474, 39580, 39584, 39559, 44492, {39588, 0, 0, 0}, 153, 153, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x0443, 0x7C43, 257, 114, 44495, 44506, 44532, 39629, 39633, 39609, 44566, {0, 0, 0, 0}, 154, 154, { 1254, 500, 10029, 857, 0, ';' }},
-       {0x0445, 0x0045, 257, 49, 44569, 44575, 44591, 39664, 39668, 39637, 44239, {39672, 0, 0, 0}, 155, 155, { 0, 500, 2, 1, 0, ',' }},
-       {0x0447, 0x0047, 257, 49, 44622, 44628, 44645, 39809, 39813, 39775, 44239, {39817, 0, 0, 0}, 156, 156, { 0, 500, 2, 1, 0, ',' }},
-       {0x0448, 0x0048, 257, 49, 44682, 44688, 44702, 39895, 39899, 14525, 44239, {0, 0, 0, 0}, 157, 157, { 0, 500, 2, 1, 0, ',' }},
-       {0x0449, 0x0049, 257, 49, 44733, 44739, 44753, 39928, 39932, 39903, 44239, {39936, 0, 0, 0}, 158, 158, { 0, 500, 2, 1, 0, ',' }},
-       {0x044A, 0x004A, 257, 49, 44793, 44799, 44814, 40030, 40034, 40001, 44239, {40038, 0, 0, 0}, 159, 159, { 0, 500, 2, 1, 0, ',' }},
-       {0x044B, 0x004B, 257, 49, 44861, 44867, 44883, 40127, 40131, 35839, 44239, {40135, 0, 0, 0}, 160, 160, { 0, 500, 2, 1, 0, ',' }},
-       {0x044C, 0x004C, 257, 49, 44914, 44920, 44938, 40238, 40242, 40206, 44239, {40246, 0, 0, 0}, 161, 161, { 0, 500, 2, 1, 0, ',' }},
-       {0x044D, 0x004D, 257, 49, 44978, 44984, 45001, 40327, 40331, 14516, 44239, {40335, 0, 0, 0}, 162, 162, { 0, 500, 2, 1, 0, ',' }},
-       {0x044E, 0x004E, 257, 49, 45038, 45044, 45060, 40415, 2565, 40388, 44239, {40419, 0, 0, 0}, 163, 163, { 0, 500, 2, 1, 0, ',' }},
-       {0x0451, 0x0051, 257, 21, 45091, 45097, 45113, 40551, 40555, 40515, 13340, {0, 0, 0, 0}, 164, 164, { 0, 500, 2, 1, 0, ',' }},
-       {0x0452, 0x0052, 257, 37, 45159, 45165, 45188, 40576, 40580, 40559, 45211, {0, 0, 0, 0}, 165, 165, { 1252, 20285, 10000, 850, 0, ',' }},
-       {0x0453, 0x0053, 257, 59, 45214, 45220, 45237, 40621, 40625, 40584, 45289, {0, 0, 0, 0}, 166, 166, { 0, 500, 2, 1, 0, ',' }},
-       {0x0454, 0x0054, 257, 62, 45292, 45298, 45309, 40646, 40650, 40629, 45331, {0, 0, 0, 0}, 167, 167, { 0, 500, 2, 1, 0, ',' }},
-       {0x0456, 0x0056, 257, 32, 45334, 45340, 45357, 40673, 40677, 40654, 41682, {37060, 0, 0, 0}, 168, 168, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0457, 0x0057, 257, 49, 45374, 45381, 45397, 40712, 40681, 40681, 44239, {0, 0, 0, 0}, 169, 169, { 0, 500, 2, 1, 0, ',' }},
-       {0x045B, 0x005B, 257, 65, 45431, 45437, 45457, 40743, 40747, 40716, 45507, {40751, 0, 0, 0}, 170, 170, { 0, 500, 2, 1, 0, ',' }},
-       {0x045E, 0x005E, 257, 33, 45510, 45516, 45535, 40794, 40798, 7865, 45566, {40802, 0, 0, 0}, 171, 171, { 0, 500, 2, 1, 0, ';' }},
-       {0x0461, 0x0061, 257, 82, 45569, 45575, 45590, 40917, 40921, 2059, 45627, {40925, 0, 0, 0}, 172, 172, { 0, 500, 2, 1, 0, ',' }},
-       {0x0463, 0x0063, 1024, 1, 45630, 45636, 45657, 40994, 40998, 40975, 45687, {0, 0, 0, 0}, 173, 173, { 0, 500, 2, 1, 1, ';' }},
-       {0x0464, 0x0064, 257, 87, 45690, 45697, 45720, 41015, 41002, 41002, 45741, {41019, 0, 0, 0}, 174, 174, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x0468, 0x7C68, 257, 78, 45744, 45755, 45778, 41051, 41055, 41042, 45795, {0, 0, 0, 0}, 175, 175, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x046A, 0x006A, 257, 78, 45798, 45804, 45821, 41084, 41088, 41059, 45795, {0, 0, 0, 0}, 176, 176, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x046C, 0x006C, 257, 118, 45867, 45874, 41111, 41128, 41092, 41092, 43909, {0, 0, 0, 0}, 177, 177, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x046F, 0x006F, 257, 39, 45904, 45910, 45934, 41159, 41163, 41132, 45965, {0, 0, 0, 0}, 178, 178, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0470, 0x0070, 257, 78, 45968, 45974, 45974, 41172, 41176, 14510, 45795, {0, 0, 0, 0}, 179, 179, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x0478, 0x0078, 257, 21, 45989, 45995, 46014, 41204, 41208, 41180, 13340, {41212, 0, 0, 0}, 180, 180, { 0, 500, 2, 1, 0, ',' }},
-       {0x047E, 0x007E, 257, 36, 46033, 46039, 46055, 41245, 41249, 41225, 42066, {41253, 0, 0, 0}, 181, 181, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0482, 0x0082, 257, 36, 46074, 46080, 46097, 41292, 41296, 41273, 42066, {0, 0, 0, 0}, 182, 182, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0485, 0x0085, 257, 96, 46115, 46122, 41375, 41393, 41365, 41365, 42710, {0, 0, 0, 0}, 183, 183, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0487, 0x0087, 257, 97, 46137, 46143, 46143, 41412, 41416, 41397, 46164, {0, 0, 0, 0}, 184, 184, { 1252, 37, 10000, 437, 0, ';' }},
-       {0x0491, 0x0091, 257, 37, 46167, 46173, 46206, 41449, 41453, 41420, 45211, {41457, 0, 0, 0}, 185, 185, { 1252, 20285, 10000, 850, 0, ',' }},
-       {0x0801, 0x0001, 257, 50, 46242, 46248, 46262, 46292, 36519, 36490, 46296, {36523, 0, 0, 0}, 186, 186, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x0804, 0x0004, 257, 21, 46299, 36748, 46305, 36722, 36726, 36730, 13340, {36733, 0, 0, 0}, 187, 187, { 936, 500, 10008, 936, 0, ',' }},
-       {0x0807, 0x0007, 257, 19, 46321, 46327, 46348, 46366, 36889, 36867, 13261, {36893, 0, 0, 0}, 188, 188, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x0809, 0x0009, 257, 37, 46370, 46376, 46376, 46401, 37009, 36994, 45211, {37013, 0, 0, 0}, 189, 189, { 1252, 20285, 10000, 850, 0, ',' }},
-       {0x080A, 0x000A, 257, 76, 46405, 46411, 46428, 46447, 37056, 37032, 46451, {37060, 0, 0, 0}, 190, 190, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x080C, 0x000C, 257, 10, 46454, 46460, 46477, 46498, 37156, 37132, 46502, {37160, 0, 0, 0}, 191, 191, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0810, 0x0010, 257, 19, 46505, 46511, 46533, 46553, 37363, 37339, 13261, {37060, 0, 0, 0}, 192, 192, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0813, 0x0013, 257, 10, 46557, 46563, 46579, 46600, 37486, 37462, 46502, {37490, 0, 0, 0}, 193, 193, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0814, 0x7814, 257, 81, 46604, 46610, 46637, 46653, 46657, 46661, 42469, {36846, 0, 0, 0}, 194, 194, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x0816, 0x0016, 257, 91, 46664, 46670, 46692, 46714, 37620, 37591, 46718, {37624, 0, 0, 0}, 195, 195, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x081D, 0x001D, 257, 34, 46721, 46727, 46745, 46763, 37979, 37956, 42022, {36846, 0, 0, 0}, 196, 196, { 1252, 20278, 10000, 850, 0, ';' }},
-       {0x082C, 0x742C, 257, 7, 46767, 46778, 43734, 46813, 38758, 14519, 43762, {38762, 0, 0, 0}, 197, 197, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x083C, 0x003C, 257, 47, 46817, 46823, 46839, 39370, 39374, 39353, 46855, {39378, 0, 0, 0}, 198, 198, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x083E, 0x003E, 257, 13, 46858, 46864, 46879, 46902, 39426, 39399, 46906, {39430, 0, 0, 0}, 199, 199, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x0843, 0x7843, 257, 114, 46909, 46920, 44532, 39629, 39633, 39609, 44566, {0, 0, 0, 0}, 200, 200, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x0845, 0x0045, 257, 9, 46949, 46955, 46976, 47019, 39668, 39637, 47023, {39672, 0, 0, 0}, 201, 201, { 0, 500, 2, 1, 0, ',' }},
-       {0x0850, 0x7C50, 257, 21, 47026, 47037, 40494, 47066, 40511, 40481, 13340, {0, 0, 0, 0}, 202, 202, { 0, 500, 2, 1, 0, ',' }},
-       {0x0C01, 0x0001, 257, 31, 47070, 47076, 47091, 47115, 36519, 36490, 47119, {36523, 0, 0, 0}, 203, 203, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x0C04, 0x7C04, 257, 42, 47122, 47128, 47171, 47208, 36726, 36730, 47212, {41736, 0, 0, 0}, 204, 204, { 950, 500, 10002, 950, 0, ',' }},
-       {0x0C07, 0x0007, 257, 5, 47215, 47221, 47238, 47260, 36889, 36867, 47264, {36893, 0, 0, 0}, 205, 205, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x0C09, 0x0009, 257, 6, 47267, 47273, 47273, 47293, 37009, 36994, 47297, {37013, 0, 0, 0}, 206, 206, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x0C0A, 0x000A, 257, 32, 47300, 47306, 47322, 47341, 37056, 37032, 41682, {37060, 0, 0, 0}, 207, 207, { 1252, 20284, 10000, 850, 0, ';' }},
-       {0x0C0C, 0x000C, 257, 18, 47345, 47351, 47367, 47386, 37156, 37132, 47390, {37160, 0, 0, 0}, 208, 208, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x0C3B, 0x003B, 257, 34, 47393, 47399, 47423, 47449, 47453, 39311, 42022, {0, 0, 0, 0}, 209, 209, { 1252, 20278, 10000, 850, 0, ';' }},
-       {0x1001, 0x0001, 257, 69, 47457, 47463, 47478, 47506, 36519, 36490, 47510, {36523, 0, 0, 0}, 210, 210, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x1004, 0x0004, 257, 100, 47513, 47519, 47551, 47570, 36726, 36730, 47574, {36733, 0, 0, 0}, 211, 211, { 936, 500, 10008, 936, 0, ',' }},
-       {0x1007, 0x0007, 257, 67, 47577, 47583, 47603, 47623, 36889, 36867, 47627, {36893, 0, 0, 0}, 212, 212, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x1009, 0x0009, 257, 18, 47630, 47636, 47636, 47653, 37009, 36994, 47390, {37013, 0, 0, 0}, 213, 213, { 1252, 37, 10000, 850, 0, ',' }},
-       {0x100A, 0x000A, 257, 41, 47657, 47663, 47683, 47704, 37056, 37032, 47708, {37060, 0, 0, 0}, 214, 214, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x100C, 0x000C, 257, 19, 47711, 47717, 47738, 47757, 37156, 37132, 13261, {37160, 0, 0, 0}, 215, 215, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x1401, 0x0001, 257, 28, 47761, 47767, 47784, 47816, 36519, 36490, 47820, {36523, 0, 0, 0}, 216, 216, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x1404, 0x7C04, 257, 74, 47823, 47829, 47868, 47905, 36726, 36730, 47909, {41736, 0, 0, 0}, 217, 217, { 950, 500, 10002, 950, 0, ',' }},
-       {0x1407, 0x0007, 257, 64, 47912, 47918, 47941, 47965, 36889, 36867, 47969, {36893, 0, 0, 0}, 218, 218, { 1252, 20273, 10000, 850, 0, ';' }},
-       {0x1409, 0x0009, 257, 83, 47972, 47978, 47978, 48000, 37009, 36994, 48004, {37013, 0, 0, 0}, 219, 219, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x140A, 0x000A, 257, 23, 48007, 48013, 48034, 48056, 37056, 37032, 48060, {37060, 0, 0, 0}, 220, 220, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x140C, 0x000C, 257, 67, 48063, 48069, 48089, 48112, 37156, 37132, 47627, {37160, 0, 0, 0}, 221, 221, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x1801, 0x0001, 257, 70, 48116, 48122, 48139, 48169, 36519, 36490, 48173, {36523, 0, 0, 0}, 222, 222, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x1809, 0x0009, 257, 47, 48176, 48182, 48182, 48200, 37009, 36994, 46855, {37013, 0, 0, 0}, 223, 223, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x180A, 0x000A, 257, 85, 48204, 48210, 48227, 48246, 37056, 37032, 48250, {37060, 0, 0, 0}, 224, 224, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x180C, 0x000C, 257, 71, 48253, 48259, 48275, 48294, 37156, 37132, 48298, {37160, 0, 0, 0}, 225, 225, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x181A, 0x701A, 257, 8, 48301, 48312, 48352, 48404, 48408, 48412, 48415, {48418, 0, 0, 0}, 226, 226, { 1250, 870, 10082, 852, 0, ';' }},
-       {0x1C01, 0x0001, 257, 107, 48441, 48447, 48464, 48490, 36519, 36490, 48494, {36523, 0, 0, 0}, 227, 227, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x1C09, 0x0009, 257, 118, 48497, 48503, 48503, 48526, 37009, 36994, 43909, {37013, 0, 0, 0}, 228, 228, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x1C0A, 0x000A, 257, 27, 48530, 48536, 48565, 48598, 37056, 37032, 48602, {37060, 0, 0, 0}, 229, 229, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x1C1A, 0x6C1A, 257, 8, 48605, 48616, 48352, 48659, 48663, 48412, 48415, {38869, 0, 0, 0}, 230, 230, { 1251, 21025, 10007, 855, 0, ';' }},
-       {0x2001, 0x0001, 257, 84, 48667, 48673, 48687, 48715, 36519, 36490, 48719, {36523, 0, 0, 0}, 231, 231, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x2009, 0x0009, 257, 54, 48722, 48728, 48728, 48746, 37009, 36994, 48750, {37013, 0, 0, 0}, 232, 232, { 1252, 500, 10000, 850, 0, ',' }},
-       {0x200A, 0x000A, 257, 115, 48753, 48759, 48779, 48800, 37056, 37032, 48804, {37060, 0, 0, 0}, 233, 233, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x2401, 0x0001, 257, 117, 48807, 48813, 48828, 48856, 36519, 36490, 48860, {36523, 0, 0, 0}, 234, 234, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x240A, 0x000A, 257, 22, 48863, 48869, 48888, 48908, 37056, 37032, 48912, {37060, 0, 0, 0}, 235, 235, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x241A, 0x701A, 257, 95, 48915, 48926, 48950, 48978, 9243, 48412, 48982, {48418, 0, 0, 0}, 236, 236, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x2801, 0x0001, 257, 104, 48985, 48991, 49006, 49034, 36519, 36490, 49038, {36523, 0, 0, 0}, 237, 237, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x2809, 0x0009, 257, 17, 49041, 49047, 49047, 49064, 37009, 36994, 49068, {37013, 0, 0, 0}, 238, 238, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x280A, 0x000A, 257, 86, 49071, 49077, 49092, 49109, 37056, 37032, 49113, {37060, 0, 0, 0}, 239, 239, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x281A, 0x6C1A, 257, 95, 49116, 49127, 48950, 49154, 9243, 48412, 48982, {38869, 0, 0, 0}, 240, 240, { 1251, 21025, 10007, 855, 0, ';' }},
-       {0x2C01, 0x0001, 257, 55, 49158, 49164, 49180, 49210, 36519, 36490, 49214, {36523, 0, 0, 0}, 241, 241, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x2C09, 0x0009, 257, 109, 49217, 49223, 49223, 49253, 37009, 36994, 49257, {37013, 0, 0, 0}, 242, 242, { 1252, 500, 10000, 850, 0, ';' }},
-       {0x2C0A, 0x000A, 257, 4, 49260, 49266, 49286, 49307, 37056, 37032, 49311, {37060, 0, 0, 0}, 243, 243, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x2C1A, 0x701A, 257, 72, 49314, 49325, 49353, 49386, 9243, 48412, 49390, {48418, 0, 0, 0}, 244, 244, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x3001, 0x0001, 257, 63, 49393, 49399, 49416, 49444, 36519, 36490, 49448, {36523, 0, 0, 0}, 245, 245, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x3009, 0x0009, 257, 119, 49451, 49457, 49457, 49476, 37009, 36994, 49480, {37013, 0, 0, 0}, 246, 246, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x300A, 0x000A, 257, 29, 49483, 49489, 49507, 49526, 37056, 37032, 49530, {37060, 0, 0, 0}, 247, 247, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x301A, 0x6C1A, 257, 72, 49533, 49544, 49353, 49575, 9243, 48412, 49390, {38869, 0, 0, 0}, 248, 248, { 1251, 21025, 10007, 855, 0, ';' }},
-       {0x3401, 0x0001, 257, 61, 49579, 49585, 49601, 49631, 36519, 36490, 49635, {36523, 0, 0, 0}, 249, 249, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x3409, 0x0009, 257, 87, 49638, 49644, 49644, 49666, 37009, 36994, 45741, {37013, 0, 0, 0}, 250, 250, { 1252, 500, 10000, 437, 0, ',' }},
-       {0x340A, 0x000A, 257, 20, 49670, 49676, 49692, 49709, 37056, 37032, 49713, {37060, 0, 0, 0}, 251, 251, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x3801, 0x0001, 257, 0, 49716, 49722, 49752, 49816, 36519, 36490, 49820, {36523, 0, 0, 0}, 252, 252, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x380A, 0x000A, 257, 113, 49823, 49829, 49847, 49866, 37056, 37032, 49870, {37060, 0, 0, 0}, 253, 253, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x3C01, 0x0001, 257, 12, 49873, 49879, 49896, 49928, 36519, 36490, 49932, {36523, 0, 0, 0}, 254, 254, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x3C0A, 0x000A, 257, 92, 49935, 49941, 49960, 49980, 37056, 37032, 49984, {37060, 0, 0, 0}, 255, 255, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x4001, 0x0001, 257, 93, 49987, 49993, 50008, 50032, 36519, 36490, 50036, {36523, 0, 0, 0}, 256, 256, { 1256, 20420, 10004, 720, 1, ';' }},
-       {0x4009, 0x0009, 257, 49, 50039, 50045, 50045, 50061, 37009, 36994, 44239, {37013, 0, 0, 0}, 257, 257, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x400A, 0x000A, 257, 14, 50065, 50071, 50089, 50108, 37056, 37032, 50112, {37060, 0, 0, 0}, 258, 258, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x440A, 0x000A, 257, 103, 50115, 50121, 50143, 50166, 37056, 37032, 50170, {37060, 0, 0, 0}, 259, 259, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x4809, 0x0009, 257, 100, 50173, 50179, 50179, 50199, 37009, 36994, 47574, {37013, 0, 0, 0}, 260, 260, { 1252, 37, 10000, 437, 0, ',' }},
-       {0x480A, 0x000A, 257, 43, 50203, 50209, 50228, 50248, 37056, 37032, 50252, {37060, 0, 0, 0}, 261, 261, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x4C0A, 0x000A, 257, 79, 50255, 50261, 50281, 50302, 37056, 37032, 50306, {37060, 0, 0, 0}, 262, 262, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x500A, 0x000A, 257, 90, 50309, 50315, 50337, 50360, 37056, 37032, 50364, {37060, 0, 0, 0}, 263, 263, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x540A, 0x000A, 257, 112, 50367, 50373, 50397, 50423, 37056, 37032, 41981, {37060, 0, 0, 0}, 264, 264, { 1252, 20284, 10000, 850, 0, ',' }},
-       {0x6C1A, 0x7C1A, 257, -1, 50427, 50435, 50454, 49154, 9243, 48412, 0, {38869, 0, 0, 0}, 265, 265, { 1251, 21025, 10007, 855, 0, ';' }},
-       {0x701A, 0x7C1A, 257, -1, 50467, 50475, 50454, 48978, 9243, 48412, 0, {48418, 0, 0, 0}, 266, 266, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x742C, 0x002C, 257, -1, 50491, 50499, 38740, 46813, 38758, 14519, 0, {38762, 0, 0, 0}, 267, 267, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x7804, 0x007F, 257, -1, 36730, 36748, 36715, 36722, 36726, 36730, 0, {36733, 0, 0, 0}, 268, 268, { 936, 500, 10008, 936, 0, ',' }},
-       {0x7814, 0x0014, 257, -1, 46661, 50522, 50540, 46653, 46657, 46661, 0, {36846, 0, 0, 0}, 269, 269, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x781A, 0x007F, 257, -1, 50548, 50551, 50559, 50568, 50572, 50548, 0, {48418, 0, 0, 0}, 270, 270, { 1250, 870, 10082, 852, 0, ';' }},
-       {0x782C, 0x002C, 257, -1, 50576, 50584, 38740, 38754, 38758, 14519, 0, {38762, 0, 0, 0}, 271, 271, { 1254, 20905, 10081, 857, 0, ';' }},
-       {0x7843, 0x0043, 257, -1, 50604, 50612, 39618, 39629, 39633, 39609, 0, {0, 0, 0, 0}, 272, 272, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x7850, 0x0050, 257, -1, 50629, 50637, 40494, 50658, 40511, 40481, 0, {0, 0, 0, 0}, 273, 273, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x7C04, 0x7804, 257, -1, 50662, 41691, 36715, 41729, 36726, 36730, 0, {41736, 0, 0, 0}, 274, 274, { 950, 500, 10002, 950, 0, ',' }},
-       {0x7C04, 0x7C04, 257, -1, 50670, 50677, 36715, 41729, 36726, 36730, 0, {41736, 0, 0, 0}, 275, 275, { 950, 500, 10002, 950, 0, ',' }},
-       {0x7C14, 0x0014, 257, -1, 37539, 50706, 50724, 37531, 37535, 37539, 0, {36846, 0, 0, 0}, 276, 276, { 1252, 20277, 10000, 850, 0, ';' }},
-       {0x7C1A, 0x007F, 257, -1, 48412, 50738, 50454, 50746, 9243, 48412, 0, {38869, 0, 0, 0}, 277, 277, { 1250, 500, 10029, 852, 0, ';' }},
-       {0x7C28, 0x0028, 257, -1, 50750, 50758, 0, 38583, 38587, 38574, 0, {0, 0, 0, 0}, 278, 278, { 1251, 20880, 10007, 866, 0, ';' }},
-       {0x7C43, 0x0043, 257, -1, 50775, 50783, 39618, 39629, 39633, 39609, 0, {0, 0, 0, 0}, 279, 279, { 1254, 500, 10029, 857, 0, ';' }},
-       {0x7C50, 0x0050, 257, -1, 50797, 50805, 40494, 47066, 40511, 40481, 0, {0, 0, 0, 0}, 280, 280, { 0, 500, 2, 1, 0, ',' }},
-       {0x7C5F, 0x005F, 257, -1, 50827, 50836, 40877, 40887, 40847, 40847, 0, {0, 0, 0, 0}, 281, 281, { 1252, 20297, 10000, 850, 0, ';' }},
-       {0x7C68, 0x0068, 257, -1, 50870, 50878, 41045, 41051, 41055, 41042, 0, {0, 0, 0, 0}, 282, 282, { 1252, 37, 10000, 437, 0, ',' }}
+       {0x0001, 0x007F, 768, -1, 36492, 36495, 36502, 36517, 36521, 36492, 0, {0, 0, 36525, 0}, 0, 0, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x0002, 0x007F, 257, -1, 36553, 36556, 36566, 36585, 36589, 36553, 0, {36593, 0, 0, 0}, 1, 1, { 1251, 21025, 10007, 866, 0, ';' }},
+       {0x0003, 0x007F, 257, -1, 36635, 36638, 36646, 36654, 36658, 36635, 0, {36662, 0, 0, 0}, 2, 2, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0004, 0x0004, 257, -1, 36682, 36689, 36717, 36724, 36728, 36732, 0, {36735, 0, 0, 0}, 3, 3, { 936, 500, 10008, 936, 0, ',' }},
+       {0x0004, 0x7804, 257, -1, 36742, 36750, 36717, 36724, 36728, 36732, 0, {36735, 0, 0, 0}, 4, 4, { 936, 500, 10008, 936, 0, ',' }},
+       {0x0005, 0x007F, 257, -1, 36771, 36774, 36780, 36790, 36794, 36771, 0, {36798, 0, 0, 0}, 5, 5, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x0006, 0x007F, 257, -1, 36824, 36827, 36834, 36840, 36844, 36824, 0, {36848, 0, 0, 0}, 6, 6, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0007, 0x007F, 257, -1, 36869, 36872, 36879, 36887, 36891, 36869, 0, {36895, 0, 0, 0}, 7, 7, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x0008, 0x007F, 257, -1, 36920, 36923, 36929, 36946, 36950, 36920, 0, {36954, 0, 0, 0}, 8, 8, { 1253, 20273, 10006, 737, 0, ';' }},
+       {0x0009, 0x007F, 257, -1, 36996, 36999, 36999, 37007, 37011, 36996, 0, {37015, 0, 0, 0}, 9, 9, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x000A, 0x007F, 257, -1, 37034, 37037, 37045, 37054, 37058, 37034, 0, {37062, 0, 0, 0}, 10, 10, { 1252, 20284, 10000, 850, 0, ';' }},
+       {0x000B, 0x007F, 257, -1, 37084, 37087, 37095, 37101, 37105, 37084, 0, {37109, 0, 0, 0}, 11, 11, { 1252, 20278, 10000, 850, 0, ';' }},
+       {0x000C, 0x007F, 257, -1, 37134, 37137, 37144, 37154, 37158, 37134, 0, {37162, 0, 0, 0}, 12, 12, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x000D, 0x007F, 257, -1, 37184, 37187, 37194, 37205, 37209, 37184, 0, {37213, 0, 0, 0}, 13, 13, { 1255, 500, 10005, 862, 1, ',' }},
+       {0x000E, 0x007F, 257, -1, 37246, 37249, 37259, 37266, 37270, 37246, 0, {37274, 0, 0, 0}, 14, 14, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x000F, 0x007F, 257, -1, 37290, 37293, 37303, 37313, 37317, 37290, 0, {37321, 0, 0, 0}, 15, 15, { 1252, 20871, 10079, 850, 0, ';' }},
+       {0x0010, 0x007F, 257, -1, 37341, 37344, 37352, 37361, 37365, 37341, 0, {37062, 0, 0, 0}, 16, 16, { 1252, 20280, 10000, 850, 0, ';' }},
+       {0x0011, 0x007F, 257, -1, 37369, 37372, 37381, 37391, 37395, 37369, 0, {37399, 0, 0, 0}, 17, 17, { 932, 20290, 10001, 932, 0, ',' }},
+       {0x0012, 0x007F, 257, -1, 37426, 37429, 37436, 37446, 37450, 37426, 0, {37454, 0, 0, 0}, 18, 18, { 949, 20833, 10003, 949, 0, ',' }},
+       {0x0013, 0x007F, 257, -1, 37464, 37467, 37473, 37484, 37488, 37464, 0, {37492, 0, 0, 0}, 19, 19, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0014, 0x007F, 257, -1, 37514, 37517, 37527, 37533, 37537, 37541, 0, {36848, 0, 0, 0}, 20, 20, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0015, 0x007F, 257, -1, 37544, 37547, 37554, 37561, 37565, 37544, 0, {37569, 0, 0, 0}, 21, 21, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x0016, 0x007F, 257, -1, 37593, 37596, 37607, 37618, 37622, 37593, 0, {37626, 0, 0, 0}, 22, 22, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0017, 0x007F, 257, -1, 37649, 37652, 37660, 37670, 37674, 37649, 0, {37678, 0, 0, 0}, 23, 23, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x0018, 0x007F, 257, -1, 37698, 37701, 37710, 37719, 37723, 37698, 0, {37727, 0, 0, 0}, 24, 24, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x0019, 0x007F, 257, -1, 37746, 37749, 37757, 37772, 37776, 37746, 0, {37780, 0, 0, 0}, 25, 25, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x001A, 0x007F, 257, -1, 37826, 37829, 37838, 37847, 37851, 37826, 0, {37855, 0, 0, 0}, 26, 26, { 1250, 500, 10082, 852, 0, ';' }},
+       {0x001B, 0x007F, 257, -1, 37878, 37881, 37888, 37900, 37904, 37878, 0, {37908, 0, 0, 0}, 27, 27, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x001C, 0x007F, 257, -1, 37932, 37935, 37944, 37950, 37954, 37932, 0, {0, 0, 0, 0}, 28, 28, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x001D, 0x007F, 257, -1, 37958, 37961, 37969, 37977, 37981, 37958, 0, {36848, 0, 0, 0}, 29, 29, { 1252, 20278, 10000, 850, 0, ';' }},
+       {0x001E, 0x007F, 512, -1, 37985, 37988, 37993, 38003, 38007, 37985, 0, {0, 38011, 0, 0}, 30, 30, { 874, 20838, 10021, 874, 0, ',' }},
+       {0x001F, 0x007F, 257, -1, 38042, 38045, 38053, 38062, 38066, 38042, 0, {38070, 0, 0, 0}, 31, 31, { 1254, 20905, 10081, 857, 0, ';' }},
+       {0x0020, 0x007F, 257, -1, 38084, 38087, 38092, 38101, 38105, 38084, 0, {38109, 0, 0, 0}, 32, 32, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x0021, 0x007F, 257, -1, 38139, 38142, 38153, 38170, 38174, 38139, 0, {38178, 0, 0, 0}, 33, 33, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0022, 0x007F, 257, -1, 38197, 38200, 38210, 38231, 38235, 38197, 0, {38239, 0, 0, 0}, 34, 34, { 1251, 500, 10017, 866, 0, ';' }},
+       {0x0023, 0x007F, 257, -1, 38285, 38288, 38299, 38320, 38324, 38285, 0, {38328, 0, 0, 0}, 35, 35, { 1251, 500, 10007, 866, 0, ';' }},
+       {0x0024, 0x007F, 257, -1, 38370, 38373, 38383, 38397, 38401, 38370, 0, {38405, 0, 0, 0}, 36, 36, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x0025, 0x007F, 257, -1, 38427, 38430, 38439, 38445, 38449, 38427, 0, {38453, 0, 0, 0}, 37, 37, { 1257, 500, 10029, 775, 0, ';' }},
+       {0x0026, 0x007F, 257, -1, 38473, 38476, 38484, 38494, 38498, 38473, 0, {38502, 0, 0, 0}, 38, 38, { 1257, 500, 10029, 775, 0, ';' }},
+       {0x0027, 0x007F, 257, -1, 38521, 38524, 38535, 38545, 38549, 38521, 0, {38553, 0, 0, 0}, 39, 39, { 1257, 500, 10029, 775, 0, ';' }},
+       {0x0028, 0x007F, 257, -1, 38576, 38579, 0, 38585, 38589, 38576, 0, {0, 0, 0, 0}, 40, 40, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0029, 0x007F, 257, -1, 38593, 38596, 38604, 38615, 38619, 38593, 0, {38623, 0, 0, 0}, 41, 41, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x002A, 0x007F, 257, -1, 38647, 38650, 38661, 38676, 4121, 38647, 0, {38680, 0, 0, 0}, 42, 42, { 1258, 500, 10000, 1258, 0, ',' }},
+       {0x002B, 0x007F, 257, -1, 38695, 38698, 38707, 38722, 38726, 38695, 0, {0, 0, 0, 0}, 43, 43, { 0, 500, 2, 1, 0, ',' }},
+       {0x002C, 0x007F, 257, -1, 14519, 38730, 38742, 38756, 38760, 14519, 0, {38764, 0, 0, 0}, 44, 44, { 1254, 20905, 10081, 857, 0, ';' }},
+       {0x002D, 0x007F, 257, -1, 38782, 38785, 38792, 38800, 38804, 38782, 0, {38808, 0, 0, 0}, 45, 45, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x002F, 0x007F, 257, -1, 38828, 38831, 38842, 38863, 38867, 38828, 0, {38871, 0, 0, 0}, 46, 46, { 1251, 500, 10007, 866, 0, ';' }},
+       {0x0032, 0x007F, 257, -1, 38915, 38918, 38925, 38934, 38938, 38915, 0, {0, 0, 0, 0}, 47, 47, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0034, 0x007F, 257, -1, 38942, 38945, 38951, 38960, 38964, 38942, 0, {0, 0, 0, 0}, 48, 48, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0035, 0x007F, 257, -1, 38968, 38971, 38976, 38984, 38988, 38968, 0, {38992, 0, 0, 0}, 49, 49, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0036, 0x007F, 257, -1, 39013, 39016, 39016, 39026, 39030, 39013, 0, {39034, 0, 0, 0}, 50, 50, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0037, 0x007F, 257, -1, 39054, 39057, 39066, 39088, 39092, 39054, 0, {39096, 0, 0, 0}, 51, 51, { 0, 500, 2, 1, 0, ';' }},
+       {0x0038, 0x007F, 257, -1, 39161, 39164, 39172, 39182, 39186, 39161, 0, {0, 0, 0, 0}, 52, 52, { 1252, 20277, 10079, 850, 0, ';' }},
+       {0x0039, 0x007F, 257, -1, 39190, 39193, 39199, 39218, 39222, 39190, 0, {39226, 0, 0, 0}, 53, 53, { 0, 500, 2, 1, 0, ',' }},
+       {0x003A, 0x007F, 257, -1, 39267, 39270, 39278, 39284, 39288, 39267, 0, {39292, 0, 0, 0}, 54, 54, { 0, 500, 2, 1, 0, ',' }},
+       {0x003B, 0x007F, 257, -1, 39313, 39316, 39330, 39347, 39351, 39313, 0, {0, 0, 0, 0}, 55, 55, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x003C, 0x007F, 257, -1, 39355, 39358, 39364, 39372, 39376, 39355, 0, {39380, 0, 0, 0}, 56, 56, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x003E, 0x007F, 257, -1, 39401, 39404, 39410, 39424, 39428, 39401, 0, {39432, 0, 0, 0}, 57, 57, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x003F, 0x007F, 257, -1, 39449, 39452, 39459, 39479, 39483, 39449, 0, {39487, 0, 0, 0}, 58, 58, { 0, 500, 2, 1, 0, ';' }},
+       {0x0040, 0x007F, 257, -1, 39529, 39532, 39540, 39553, 39557, 39529, 0, {0, 0, 0, 0}, 59, 59, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0041, 0x007F, 257, -1, 39561, 39564, 39572, 39582, 39586, 39561, 0, {39590, 0, 0, 0}, 60, 60, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x0043, 0x007F, 257, -1, 39611, 39614, 39620, 39631, 39635, 39611, 0, {0, 0, 0, 0}, 61, 61, { 1254, 500, 10029, 857, 0, ';' }},
+       {0x0045, 0x007F, 257, -1, 39639, 39642, 39650, 39666, 39670, 39639, 0, {39674, 0, 0, 0}, 62, 62, { 0, 500, 2, 1, 0, ',' }},
+       {0x0046, 0x007F, 257, -1, 39739, 39742, 39750, 39769, 39773, 39739, 0, {0, 0, 0, 0}, 63, 63, { 0, 500, 2, 1, 0, ',' }},
+       {0x0047, 0x007F, 257, -1, 39777, 39780, 39789, 39811, 39815, 39777, 0, {39819, 0, 0, 0}, 64, 64, { 0, 500, 2, 1, 0, ',' }},
+       {0x0048, 0x007F, 257, -1, 14525, 39875, 39881, 39897, 39901, 14525, 0, {0, 0, 0, 0}, 65, 65, { 0, 500, 2, 1, 0, ',' }},
+       {0x0049, 0x007F, 257, -1, 39905, 39908, 39914, 39930, 39934, 39905, 0, {39938, 0, 0, 0}, 66, 66, { 0, 500, 2, 1, 0, ',' }},
+       {0x004A, 0x007F, 257, -1, 40003, 40006, 40013, 40032, 40036, 40003, 0, {40040, 0, 0, 0}, 67, 67, { 0, 500, 2, 1, 0, ',' }},
+       {0x004B, 0x007F, 257, -1, 35841, 40105, 40113, 40129, 40133, 35841, 0, {40137, 0, 0, 0}, 68, 68, { 0, 500, 2, 1, 0, ',' }},
+       {0x004C, 0x007F, 257, -1, 40208, 40211, 40221, 40240, 40244, 40208, 0, {40248, 0, 0, 0}, 69, 69, { 0, 500, 2, 1, 0, ',' }},
+       {0x004D, 0x007F, 257, -1, 14516, 40298, 40307, 40329, 40333, 14516, 0, {40337, 0, 0, 0}, 70, 70, { 0, 500, 2, 1, 0, ',' }},
+       {0x004E, 0x007F, 257, -1, 40390, 40393, 40401, 40417, 2565, 40390, 0, {40421, 0, 0, 0}, 71, 71, { 0, 500, 2, 1, 0, ',' }},
+       {0x0050, 0x007F, 257, -1, 40483, 40486, 40496, 40509, 40513, 40483, 0, {0, 0, 0, 0}, 72, 72, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0051, 0x007F, 257, -1, 40517, 40520, 40528, 40553, 40557, 40517, 0, {0, 0, 0, 0}, 73, 73, { 0, 500, 2, 1, 0, ',' }},
+       {0x0052, 0x007F, 257, -1, 40561, 40564, 40570, 40578, 40582, 40561, 0, {0, 0, 0, 0}, 74, 74, { 1252, 20285, 10000, 850, 0, ',' }},
+       {0x0053, 0x007F, 257, -1, 40586, 40589, 40595, 40623, 40627, 40586, 0, {0, 0, 0, 0}, 75, 75, { 0, 500, 2, 1, 0, ',' }},
+       {0x0054, 0x007F, 257, -1, 40631, 40634, 40638, 40648, 40652, 40631, 0, {0, 0, 0, 0}, 76, 76, { 0, 500, 2, 1, 0, ',' }},
+       {0x0056, 0x007F, 257, -1, 40656, 40659, 40668, 40675, 40679, 40656, 0, {37062, 0, 0, 0}, 77, 77, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0057, 0x007F, 257, -1, 40683, 40687, 40695, 40714, 40683, 40683, 0, {0, 0, 0, 0}, 78, 78, { 0, 500, 2, 1, 0, ',' }},
+       {0x005B, 0x007F, 257, -1, 40718, 40721, 40729, 40745, 40749, 40718, 0, {40753, 0, 0, 0}, 79, 79, { 0, 500, 2, 1, 0, ',' }},
+       {0x005E, 0x007F, 257, -1, 7865, 40775, 40783, 40796, 40800, 7865, 0, {40804, 0, 0, 0}, 80, 80, { 0, 500, 2, 1, 0, ';' }},
+       {0x005F, 0x007F, 257, -1, 40849, 40853, 40879, 40889, 40849, 40849, 0, {0, 0, 0, 0}, 81, 81, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0061, 0x007F, 257, -1, 2059, 40893, 40900, 40919, 40923, 2059, 0, {40927, 0, 0, 0}, 82, 82, { 0, 500, 2, 1, 0, ',' }},
+       {0x0063, 0x007F, 1024, -1, 40977, 40980, 40987, 40996, 41000, 40977, 0, {0, 0, 0, 0}, 83, 83, { 0, 500, 2, 1, 1, ';' }},
+       {0x0064, 0x007F, 257, -1, 41004, 41008, 41008, 41017, 41004, 41004, 0, {41021, 0, 0, 0}, 84, 84, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x0068, 0x007F, 257, -1, 41044, 41047, 41047, 41053, 41057, 41044, 0, {0, 0, 0, 0}, 85, 85, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x006A, 0x007F, 257, -1, 41061, 41064, 41071, 41086, 41090, 41061, 0, {0, 0, 0, 0}, 86, 86, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x006C, 0x007F, 257, -1, 41094, 41098, 41113, 41130, 41094, 41094, 0, {0, 0, 0, 0}, 87, 87, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x006F, 0x007F, 257, -1, 41134, 41137, 41149, 41161, 41165, 41134, 0, {0, 0, 0, 0}, 88, 88, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0070, 0x007F, 257, -1, 14510, 41169, 41169, 41174, 41178, 14510, 0, {0, 0, 0, 0}, 89, 89, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x0078, 0x007F, 257, -1, 41182, 41185, 41196, 41206, 41210, 41182, 0, {41214, 0, 0, 0}, 90, 90, { 0, 500, 2, 1, 0, ',' }},
+       {0x007E, 0x007F, 257, -1, 41227, 41230, 41237, 41247, 41251, 41227, 0, {41255, 0, 0, 0}, 91, 91, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0082, 0x007F, 257, -1, 41275, 41278, 41286, 41294, 41298, 41275, 0, {0, 0, 0, 0}, 92, 92, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0084, 0x007F, 257, -1, 41302, 41306, 41319, 41338, 41302, 41302, 0, {41342, 0, 0, 0}, 93, 93, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0085, 0x007F, 257, -1, 41367, 41371, 41377, 41395, 41367, 41367, 0, {0, 0, 0, 0}, 94, 94, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0087, 0x007F, 257, -1, 41399, 41402, 41402, 41414, 41418, 41399, 0, {0, 0, 0, 0}, 95, 95, { 1252, 37, 10000, 437, 0, ';' }},
+       {0x0091, 0x007F, 257, -1, 41422, 41425, 41441, 41451, 41455, 41422, 0, {41459, 0, 0, 0}, 96, 96, { 1252, 20285, 10000, 850, 0, ',' }},
+       {0x0401, 0x0001, 768, 98, 41484, 41490, 41512, 36517, 36521, 36492, 13258, {0, 0, 36525, 0}, 97, 97, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x0402, 0x0002, 257, 11, 41576, 41582, 41603, 36585, 36589, 36553, 41641, {36593, 0, 0, 0}, 98, 98, { 1251, 21025, 10007, 866, 0, ';' }},
+       {0x0403, 0x0003, 257, 32, 41644, 41650, 41666, 36654, 36658, 36635, 41684, {36662, 0, 0, 0}, 99, 99, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0404, 0x7C04, 257, 110, 41687, 41693, 41715, 41731, 36728, 36732, 41735, {41738, 0, 0, 0}, 100, 100, { 950, 500, 10002, 950, 0, ',' }},
+       {0x0405, 0x0005, 257, 24, 41745, 41751, 41774, 36790, 36794, 36771, 41804, {36798, 0, 0, 0}, 101, 101, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x0406, 0x0006, 257, 26, 41807, 41813, 41830, 36840, 36844, 36824, 41846, {36848, 0, 0, 0}, 102, 102, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0407, 0x0007, 257, 25, 41849, 41855, 41872, 36887, 36891, 36869, 41894, {36895, 0, 0, 0}, 103, 103, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x0408, 0x0008, 257, 40, 41897, 41903, 41918, 36946, 36950, 36920, 41950, {36954, 0, 0, 0}, 104, 104, { 1253, 20273, 10006, 737, 0, ';' }},
+       {0x0409, 0x0009, 257, 112, 41953, 41959, 41959, 37007, 37011, 36996, 41983, {37015, 0, 0, 0}, 105, 105, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x040B, 0x000B, 257, 34, 41986, 41992, 42010, 37101, 37105, 37084, 42024, {37109, 0, 0, 0}, 106, 106, { 1252, 20278, 10000, 850, 0, ';' }},
+       {0x040C, 0x000C, 257, 36, 42027, 42033, 42049, 37154, 37158, 37134, 42068, {37162, 0, 0, 0}, 107, 107, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x040D, 0x000D, 257, 48, 42071, 42077, 42093, 37205, 37209, 37184, 42117, {37213, 0, 0, 0}, 108, 108, { 1255, 500, 10005, 862, 1, ',' }},
+       {0x040E, 0x000E, 257, 45, 42120, 42126, 42146, 37266, 37270, 37246, 42169, {37274, 0, 0, 0}, 109, 109, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x040F, 0x000F, 257, 52, 42172, 42178, 42198, 37313, 37317, 37290, 42218, {37321, 0, 0, 0}, 110, 110, { 1252, 20871, 10079, 850, 0, ';' }},
+       {0x0410, 0x0010, 257, 53, 42221, 42227, 42243, 37361, 37365, 37341, 42261, {37062, 0, 0, 0}, 111, 111, { 1252, 20280, 10000, 850, 0, ';' }},
+       {0x0411, 0x0011, 257, 56, 42264, 42270, 42287, 37391, 37395, 37369, 42306, {37399, 0, 0, 0}, 112, 112, { 932, 20290, 10001, 932, 0, ',' }},
+       {0x0412, 0x0012, 257, 60, 42309, 42315, 42336, 37446, 37450, 37426, 42361, {37454, 0, 0, 0}, 113, 113, { 949, 20833, 10003, 949, 0, ',' }},
+       {0x0413, 0x0013, 257, 80, 42364, 42370, 42390, 37484, 37488, 37464, 42413, {37492, 0, 0, 0}, 114, 114, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0414, 0x7C14, 257, 81, 42416, 42422, 42449, 37533, 37537, 37541, 42471, {36848, 0, 0, 0}, 115, 115, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0415, 0x0015, 257, 89, 42474, 42480, 42496, 37561, 37565, 37544, 42512, {37569, 0, 0, 0}, 116, 116, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x0416, 0x0016, 257, 15, 42515, 42521, 42541, 37618, 37622, 37593, 42561, {37626, 0, 0, 0}, 117, 117, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0417, 0x0017, 257, 19, 42564, 42570, 42592, 37670, 37674, 37649, 13261, {37678, 0, 0, 0}, 118, 118, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x0418, 0x0018, 257, 94, 42611, 42617, 42636, 37719, 37723, 37698, 42656, {37727, 0, 0, 0}, 119, 119, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x0419, 0x0019, 257, 96, 42659, 42665, 42682, 37772, 37776, 37746, 42712, {37780, 0, 0, 0}, 120, 120, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x041A, 0x001A, 257, 44, 42715, 42721, 42740, 37847, 37851, 37826, 42760, {37855, 0, 0, 0}, 121, 121, { 1250, 500, 10082, 852, 0, ';' }},
+       {0x041B, 0x001B, 257, 102, 42763, 42769, 42787, 37900, 37904, 37878, 42822, {37908, 0, 0, 0}, 122, 122, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x041C, 0x001C, 257, 2, 42825, 42831, 42850, 37950, 37954, 37932, 42869, {0, 0, 0, 0}, 123, 123, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x041D, 0x001D, 257, 99, 42872, 42878, 42895, 37977, 37981, 37958, 42913, {36848, 0, 0, 0}, 124, 124, { 1252, 20278, 10000, 850, 0, ';' }},
+       {0x041E, 0x001E, 512, 105, 42916, 42922, 42938, 38003, 38007, 37985, 42960, {0, 38011, 0, 0}, 125, 125, { 874, 20838, 10021, 874, 0, ',' }},
+       {0x041F, 0x001F, 257, 108, 42963, 42969, 42986, 38062, 38066, 38042, 43006, {38070, 0, 0, 0}, 126, 126, { 1254, 20905, 10081, 857, 0, ';' }},
+       {0x0420, 0x0020, 257, 88, 43009, 43015, 43031, 38101, 38105, 38084, 43057, {38109, 0, 0, 0}, 127, 127, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x0421, 0x0021, 257, 46, 43060, 43066, 43089, 38170, 38174, 38139, 43118, {38178, 0, 0, 0}, 128, 128, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0422, 0x0022, 257, 111, 43121, 43127, 43147, 38231, 38235, 38197, 43185, {38239, 0, 0, 0}, 129, 129, { 1251, 500, 10017, 866, 0, ';' }},
+       {0x0423, 0x0023, 257, 16, 43188, 43194, 43215, 38320, 38324, 38285, 43255, {38328, 0, 0, 0}, 130, 130, { 1251, 500, 10007, 866, 0, ';' }},
+       {0x0424, 0x0024, 257, 101, 43258, 43264, 43285, 38397, 38401, 38370, 43311, {38405, 0, 0, 0}, 131, 131, { 1250, 20880, 10029, 852, 0, ';' }},
+       {0x0425, 0x0025, 257, 30, 43314, 43320, 43339, 38445, 38449, 38427, 43353, {38453, 0, 0, 0}, 132, 132, { 1257, 500, 10029, 775, 0, ';' }},
+       {0x0426, 0x0026, 257, 68, 43356, 43362, 43379, 38494, 38498, 38473, 43399, {38502, 0, 0, 0}, 133, 133, { 1257, 500, 10029, 775, 0, ';' }},
+       {0x0427, 0x0027, 257, 66, 43402, 43408, 43431, 38545, 38549, 38521, 43451, {38553, 0, 0, 0}, 134, 134, { 1257, 500, 10029, 775, 0, ';' }},
+       {0x0428, 0x7C28, 257, 106, 43454, 43465, 0, 38585, 38589, 38576, 43494, {0, 0, 0, 0}, 135, 135, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0429, 0x0029, 257, 51, 43497, 43503, 43518, 38615, 38619, 38593, 43542, {38623, 0, 0, 0}, 136, 136, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x042A, 0x002A, 257, 116, 43545, 43551, 43572, 38676, 4121, 38647, 43600, {38680, 0, 0, 0}, 137, 137, { 1258, 500, 10000, 1258, 0, ',' }},
+       {0x042B, 0x002B, 257, 3, 43603, 43609, 43628, 38722, 38726, 38695, 3781, {0, 0, 0, 0}, 138, 138, { 0, 500, 2, 1, 0, ',' }},
+       {0x042C, 0x782C, 257, 7, 43693, 43704, 43736, 38756, 38760, 14519, 43764, {38764, 0, 0, 0}, 139, 139, { 1254, 20905, 10081, 857, 0, ';' }},
+       {0x042D, 0x002D, 257, 32, 43767, 43773, 43788, 38800, 38804, 38782, 41684, {38808, 0, 0, 0}, 140, 140, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x042F, 0x002F, 257, 73, 43807, 43813, 43836, 38863, 38867, 38828, 43880, {38871, 0, 0, 0}, 141, 141, { 1251, 500, 10007, 866, 0, ';' }},
+       {0x0432, 0x0032, 257, 118, 43883, 43889, 38925, 38934, 38938, 38915, 43911, {0, 0, 0, 0}, 142, 142, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0434, 0x0034, 257, 118, 43914, 43920, 38951, 38960, 38964, 38942, 43911, {0, 0, 0, 0}, 143, 143, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0435, 0x0035, 257, 118, 43941, 43947, 43967, 38984, 38988, 38968, 43911, {38992, 0, 0, 0}, 144, 144, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0436, 0x0036, 257, 118, 43995, 44001, 44026, 39026, 39030, 39013, 43911, {39034, 0, 0, 0}, 145, 145, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0437, 0x0037, 257, 38, 44050, 44056, 44075, 39088, 39092, 39054, 44130, {39096, 0, 0, 0}, 146, 146, { 0, 500, 2, 1, 0, ';' }},
+       {0x0438, 0x0038, 257, 35, 44133, 44139, 44163, 39182, 39186, 39161, 44184, {0, 0, 0, 0}, 147, 147, { 1252, 20277, 10079, 850, 0, ';' }},
+       {0x0439, 0x0039, 257, 49, 44187, 44193, 44207, 39218, 39222, 39190, 44241, {39226, 0, 0, 0}, 148, 148, { 0, 500, 2, 1, 0, ',' }},
+       {0x043A, 0x003A, 257, 75, 44244, 44250, 44266, 39284, 39288, 39267, 44280, {39292, 0, 0, 0}, 149, 149, { 0, 500, 2, 1, 0, ',' }},
+       {0x043B, 0x003B, 257, 81, 44283, 44289, 44312, 39347, 39351, 39313, 42471, {0, 0, 0, 0}, 150, 150, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x043E, 0x003E, 257, 77, 44337, 44343, 44360, 39424, 39428, 39401, 44385, {39432, 0, 0, 0}, 151, 151, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0440, 0x0040, 257, 58, 44388, 44394, 44415, 39553, 39557, 39529, 44451, {0, 0, 0, 0}, 152, 152, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0441, 0x0041, 257, 57, 44454, 44460, 44476, 39582, 39586, 39561, 44494, {39590, 0, 0, 0}, 153, 153, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x0443, 0x7C43, 257, 114, 44497, 44508, 44534, 39631, 39635, 39611, 44568, {0, 0, 0, 0}, 154, 154, { 1254, 500, 10029, 857, 0, ';' }},
+       {0x0445, 0x0045, 257, 49, 44571, 44577, 44593, 39666, 39670, 39639, 44241, {39674, 0, 0, 0}, 155, 155, { 0, 500, 2, 1, 0, ',' }},
+       {0x0447, 0x0047, 257, 49, 44624, 44630, 44647, 39811, 39815, 39777, 44241, {39819, 0, 0, 0}, 156, 156, { 0, 500, 2, 1, 0, ',' }},
+       {0x0448, 0x0048, 257, 49, 44684, 44690, 44704, 39897, 39901, 14525, 44241, {0, 0, 0, 0}, 157, 157, { 0, 500, 2, 1, 0, ',' }},
+       {0x0449, 0x0049, 257, 49, 44735, 44741, 44755, 39930, 39934, 39905, 44241, {39938, 0, 0, 0}, 158, 158, { 0, 500, 2, 1, 0, ',' }},
+       {0x044A, 0x004A, 257, 49, 44795, 44801, 44816, 40032, 40036, 40003, 44241, {40040, 0, 0, 0}, 159, 159, { 0, 500, 2, 1, 0, ',' }},
+       {0x044B, 0x004B, 257, 49, 44863, 44869, 44885, 40129, 40133, 35841, 44241, {40137, 0, 0, 0}, 160, 160, { 0, 500, 2, 1, 0, ',' }},
+       {0x044C, 0x004C, 257, 49, 44916, 44922, 44940, 40240, 40244, 40208, 44241, {40248, 0, 0, 0}, 161, 161, { 0, 500, 2, 1, 0, ',' }},
+       {0x044D, 0x004D, 257, 49, 44980, 44986, 45003, 40329, 40333, 14516, 44241, {40337, 0, 0, 0}, 162, 162, { 0, 500, 2, 1, 0, ',' }},
+       {0x044E, 0x004E, 257, 49, 45040, 45046, 45062, 40417, 2565, 40390, 44241, {40421, 0, 0, 0}, 163, 163, { 0, 500, 2, 1, 0, ',' }},
+       {0x0451, 0x0051, 257, 21, 45093, 45099, 45115, 40553, 40557, 40517, 13340, {0, 0, 0, 0}, 164, 164, { 0, 500, 2, 1, 0, ',' }},
+       {0x0452, 0x0052, 257, 37, 45161, 45167, 45190, 40578, 40582, 40561, 45213, {0, 0, 0, 0}, 165, 165, { 1252, 20285, 10000, 850, 0, ',' }},
+       {0x0453, 0x0053, 257, 59, 45216, 45222, 45239, 40623, 40627, 40586, 45291, {0, 0, 0, 0}, 166, 166, { 0, 500, 2, 1, 0, ',' }},
+       {0x0454, 0x0054, 257, 62, 45294, 45300, 45311, 40648, 40652, 40631, 45333, {0, 0, 0, 0}, 167, 167, { 0, 500, 2, 1, 0, ',' }},
+       {0x0456, 0x0056, 257, 32, 45336, 45342, 45359, 40675, 40679, 40656, 41684, {37062, 0, 0, 0}, 168, 168, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0457, 0x0057, 257, 49, 45376, 45383, 45399, 40714, 40683, 40683, 44241, {0, 0, 0, 0}, 169, 169, { 0, 500, 2, 1, 0, ',' }},
+       {0x045B, 0x005B, 257, 65, 45433, 45439, 45459, 40745, 40749, 40718, 45509, {40753, 0, 0, 0}, 170, 170, { 0, 500, 2, 1, 0, ',' }},
+       {0x045E, 0x005E, 257, 33, 45512, 45518, 45537, 40796, 40800, 7865, 45568, {40804, 0, 0, 0}, 171, 171, { 0, 500, 2, 1, 0, ';' }},
+       {0x0461, 0x0061, 257, 82, 45571, 45577, 45592, 40919, 40923, 2059, 45629, {40927, 0, 0, 0}, 172, 172, { 0, 500, 2, 1, 0, ',' }},
+       {0x0463, 0x0063, 1024, 1, 45632, 45638, 45659, 40996, 41000, 40977, 45689, {0, 0, 0, 0}, 173, 173, { 0, 500, 2, 1, 1, ';' }},
+       {0x0464, 0x0064, 257, 87, 45692, 45699, 45722, 41017, 41004, 41004, 45743, {41021, 0, 0, 0}, 174, 174, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x0468, 0x7C68, 257, 78, 45746, 45757, 45780, 41053, 41057, 41044, 45797, {0, 0, 0, 0}, 175, 175, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x046A, 0x006A, 257, 78, 45800, 45806, 45823, 41086, 41090, 41061, 45797, {0, 0, 0, 0}, 176, 176, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x046C, 0x006C, 257, 118, 45869, 45876, 41113, 41130, 41094, 41094, 43911, {0, 0, 0, 0}, 177, 177, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x046F, 0x006F, 257, 39, 45906, 45912, 45936, 41161, 41165, 41134, 45967, {0, 0, 0, 0}, 178, 178, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0470, 0x0070, 257, 78, 45970, 45976, 45976, 41174, 41178, 14510, 45797, {0, 0, 0, 0}, 179, 179, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x0478, 0x0078, 257, 21, 45991, 45997, 46016, 41206, 41210, 41182, 13340, {41214, 0, 0, 0}, 180, 180, { 0, 500, 2, 1, 0, ',' }},
+       {0x047E, 0x007E, 257, 36, 46035, 46041, 46057, 41247, 41251, 41227, 42068, {41255, 0, 0, 0}, 181, 181, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0482, 0x0082, 257, 36, 46076, 46082, 46099, 41294, 41298, 41275, 42068, {0, 0, 0, 0}, 182, 182, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0485, 0x0085, 257, 96, 46117, 46124, 41377, 41395, 41367, 41367, 42712, {0, 0, 0, 0}, 183, 183, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0487, 0x0087, 257, 97, 46139, 46145, 46145, 41414, 41418, 41399, 46166, {0, 0, 0, 0}, 184, 184, { 1252, 37, 10000, 437, 0, ';' }},
+       {0x0491, 0x0091, 257, 37, 46169, 46175, 46208, 41451, 41455, 41422, 45213, {41459, 0, 0, 0}, 185, 185, { 1252, 20285, 10000, 850, 0, ',' }},
+       {0x0801, 0x0001, 257, 50, 46244, 46250, 46264, 46294, 36521, 36492, 46298, {36525, 0, 0, 0}, 186, 186, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x0804, 0x0004, 257, 21, 46301, 36750, 46307, 36724, 36728, 36732, 13340, {36735, 0, 0, 0}, 187, 187, { 936, 500, 10008, 936, 0, ',' }},
+       {0x0807, 0x0007, 257, 19, 46323, 46329, 46350, 46368, 36891, 36869, 13261, {36895, 0, 0, 0}, 188, 188, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x0809, 0x0009, 257, 37, 46372, 46378, 46378, 46403, 37011, 36996, 45213, {37015, 0, 0, 0}, 189, 189, { 1252, 20285, 10000, 850, 0, ',' }},
+       {0x080A, 0x000A, 257, 76, 46407, 46413, 46430, 46449, 37058, 37034, 46453, {37062, 0, 0, 0}, 190, 190, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x080C, 0x000C, 257, 10, 46456, 46462, 46479, 46500, 37158, 37134, 46504, {37162, 0, 0, 0}, 191, 191, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0810, 0x0010, 257, 19, 46507, 46513, 46535, 46555, 37365, 37341, 13261, {37062, 0, 0, 0}, 192, 192, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0813, 0x0013, 257, 10, 46559, 46565, 46581, 46602, 37488, 37464, 46504, {37492, 0, 0, 0}, 193, 193, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0814, 0x7814, 257, 81, 46606, 46612, 46639, 46655, 46659, 46663, 42471, {36848, 0, 0, 0}, 194, 194, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x0816, 0x0016, 257, 91, 46666, 46672, 46694, 46716, 37622, 37593, 46720, {37626, 0, 0, 0}, 195, 195, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x081D, 0x001D, 257, 34, 46723, 46729, 46747, 46765, 37981, 37958, 42024, {36848, 0, 0, 0}, 196, 196, { 1252, 20278, 10000, 850, 0, ';' }},
+       {0x082C, 0x742C, 257, 7, 46769, 46780, 43736, 46815, 38760, 14519, 43764, {38764, 0, 0, 0}, 197, 197, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x083C, 0x003C, 257, 47, 46819, 46825, 46841, 39372, 39376, 39355, 46857, {39380, 0, 0, 0}, 198, 198, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x083E, 0x003E, 257, 13, 46860, 46866, 46881, 46904, 39428, 39401, 46908, {39432, 0, 0, 0}, 199, 199, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x0843, 0x7843, 257, 114, 46911, 46922, 44534, 39631, 39635, 39611, 44568, {0, 0, 0, 0}, 200, 200, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x0845, 0x0045, 257, 9, 46951, 46957, 46978, 47021, 39670, 39639, 47025, {39674, 0, 0, 0}, 201, 201, { 0, 500, 2, 1, 0, ',' }},
+       {0x0850, 0x7C50, 257, 21, 47028, 47039, 40496, 47068, 40513, 40483, 13340, {0, 0, 0, 0}, 202, 202, { 0, 500, 2, 1, 0, ',' }},
+       {0x0C01, 0x0001, 257, 31, 47072, 47078, 47093, 47117, 36521, 36492, 47121, {36525, 0, 0, 0}, 203, 203, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x0C04, 0x7C04, 257, 42, 47124, 47130, 47173, 47210, 36728, 36732, 47214, {41738, 0, 0, 0}, 204, 204, { 950, 500, 10002, 950, 0, ',' }},
+       {0x0C07, 0x0007, 257, 5, 47217, 47223, 47240, 47262, 36891, 36869, 47266, {36895, 0, 0, 0}, 205, 205, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x0C09, 0x0009, 257, 6, 47269, 47275, 47275, 47295, 37011, 36996, 47299, {37015, 0, 0, 0}, 206, 206, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x0C0A, 0x000A, 257, 32, 47302, 47308, 47324, 47343, 37058, 37034, 41684, {37062, 0, 0, 0}, 207, 207, { 1252, 20284, 10000, 850, 0, ';' }},
+       {0x0C0C, 0x000C, 257, 18, 47347, 47353, 47369, 47388, 37158, 37134, 47392, {37162, 0, 0, 0}, 208, 208, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x0C3B, 0x003B, 257, 34, 47395, 47401, 47425, 47451, 47455, 39313, 42024, {0, 0, 0, 0}, 209, 209, { 1252, 20278, 10000, 850, 0, ';' }},
+       {0x1001, 0x0001, 257, 69, 47459, 47465, 47480, 47508, 36521, 36492, 47512, {36525, 0, 0, 0}, 210, 210, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x1004, 0x0004, 257, 100, 47515, 47521, 47553, 47572, 36728, 36732, 47576, {36735, 0, 0, 0}, 211, 211, { 936, 500, 10008, 936, 0, ',' }},
+       {0x1007, 0x0007, 257, 67, 47579, 47585, 47605, 47625, 36891, 36869, 47629, {36895, 0, 0, 0}, 212, 212, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x1009, 0x0009, 257, 18, 47632, 47638, 47638, 47655, 37011, 36996, 47392, {37015, 0, 0, 0}, 213, 213, { 1252, 37, 10000, 850, 0, ',' }},
+       {0x100A, 0x000A, 257, 41, 47659, 47665, 47685, 47706, 37058, 37034, 47710, {37062, 0, 0, 0}, 214, 214, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x100C, 0x000C, 257, 19, 47713, 47719, 47740, 47759, 37158, 37134, 13261, {37162, 0, 0, 0}, 215, 215, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x1401, 0x0001, 257, 28, 47763, 47769, 47786, 47818, 36521, 36492, 47822, {36525, 0, 0, 0}, 216, 216, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x1404, 0x7C04, 257, 74, 47825, 47831, 47870, 47907, 36728, 36732, 47911, {41738, 0, 0, 0}, 217, 217, { 950, 500, 10002, 950, 0, ',' }},
+       {0x1407, 0x0007, 257, 64, 47914, 47920, 47943, 47967, 36891, 36869, 47971, {36895, 0, 0, 0}, 218, 218, { 1252, 20273, 10000, 850, 0, ';' }},
+       {0x1409, 0x0009, 257, 83, 47974, 47980, 47980, 48002, 37011, 36996, 48006, {37015, 0, 0, 0}, 219, 219, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x140A, 0x000A, 257, 23, 48009, 48015, 48036, 48058, 37058, 37034, 48062, {37062, 0, 0, 0}, 220, 220, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x140C, 0x000C, 257, 67, 48065, 48071, 48091, 48114, 37158, 37134, 47629, {37162, 0, 0, 0}, 221, 221, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x1801, 0x0001, 257, 70, 48118, 48124, 48141, 48171, 36521, 36492, 48175, {36525, 0, 0, 0}, 222, 222, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x1809, 0x0009, 257, 47, 48178, 48184, 48184, 48202, 37011, 36996, 46857, {37015, 0, 0, 0}, 223, 223, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x180A, 0x000A, 257, 85, 48206, 48212, 48229, 48248, 37058, 37034, 48252, {37062, 0, 0, 0}, 224, 224, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x180C, 0x000C, 257, 71, 48255, 48261, 48277, 48296, 37158, 37134, 48300, {37162, 0, 0, 0}, 225, 225, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x181A, 0x701A, 257, 8, 48303, 48314, 48354, 48406, 48410, 48414, 48417, {48420, 0, 0, 0}, 226, 226, { 1250, 870, 10082, 852, 0, ';' }},
+       {0x1C01, 0x0001, 257, 107, 48443, 48449, 48466, 48492, 36521, 36492, 48496, {36525, 0, 0, 0}, 227, 227, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x1C09, 0x0009, 257, 118, 48499, 48505, 48505, 48528, 37011, 36996, 43911, {37015, 0, 0, 0}, 228, 228, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x1C0A, 0x000A, 257, 27, 48532, 48538, 48567, 48600, 37058, 37034, 48604, {37062, 0, 0, 0}, 229, 229, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x1C1A, 0x6C1A, 257, 8, 48607, 48618, 48354, 48661, 48665, 48414, 48417, {38871, 0, 0, 0}, 230, 230, { 1251, 21025, 10007, 855, 0, ';' }},
+       {0x2001, 0x0001, 257, 84, 48669, 48675, 48689, 48717, 36521, 36492, 48721, {36525, 0, 0, 0}, 231, 231, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x2009, 0x0009, 257, 54, 48724, 48730, 48730, 48748, 37011, 36996, 48752, {37015, 0, 0, 0}, 232, 232, { 1252, 500, 10000, 850, 0, ',' }},
+       {0x200A, 0x000A, 257, 115, 48755, 48761, 48781, 48802, 37058, 37034, 48806, {37062, 0, 0, 0}, 233, 233, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x2401, 0x0001, 257, 117, 48809, 48815, 48830, 48858, 36521, 36492, 48862, {36525, 0, 0, 0}, 234, 234, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x240A, 0x000A, 257, 22, 48865, 48871, 48890, 48910, 37058, 37034, 48914, {37062, 0, 0, 0}, 235, 235, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x241A, 0x701A, 257, 95, 48917, 48928, 48952, 48980, 9243, 48414, 48984, {48420, 0, 0, 0}, 236, 236, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x2801, 0x0001, 257, 104, 48987, 48993, 49008, 49036, 36521, 36492, 49040, {36525, 0, 0, 0}, 237, 237, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x2809, 0x0009, 257, 17, 49043, 49049, 49049, 49066, 37011, 36996, 49070, {37015, 0, 0, 0}, 238, 238, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x280A, 0x000A, 257, 86, 49073, 49079, 49094, 49111, 37058, 37034, 49115, {37062, 0, 0, 0}, 239, 239, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x281A, 0x6C1A, 257, 95, 49118, 49129, 48952, 49156, 9243, 48414, 48984, {38871, 0, 0, 0}, 240, 240, { 1251, 21025, 10007, 855, 0, ';' }},
+       {0x2C01, 0x0001, 257, 55, 49160, 49166, 49182, 49212, 36521, 36492, 49216, {36525, 0, 0, 0}, 241, 241, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x2C09, 0x0009, 257, 109, 49219, 49225, 49225, 49255, 37011, 36996, 49259, {37015, 0, 0, 0}, 242, 242, { 1252, 500, 10000, 850, 0, ';' }},
+       {0x2C0A, 0x000A, 257, 4, 49262, 49268, 49288, 49309, 37058, 37034, 49313, {37062, 0, 0, 0}, 243, 243, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x2C1A, 0x701A, 257, 72, 49316, 49327, 49355, 49388, 9243, 48414, 49392, {48420, 0, 0, 0}, 244, 244, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x3001, 0x0001, 257, 63, 49395, 49401, 49418, 49446, 36521, 36492, 49450, {36525, 0, 0, 0}, 245, 245, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x3009, 0x0009, 257, 119, 49453, 49459, 49459, 49478, 37011, 36996, 49482, {37015, 0, 0, 0}, 246, 246, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x300A, 0x000A, 257, 29, 49485, 49491, 49509, 49528, 37058, 37034, 49532, {37062, 0, 0, 0}, 247, 247, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x301A, 0x6C1A, 257, 72, 49535, 49546, 49355, 49577, 9243, 48414, 49392, {38871, 0, 0, 0}, 248, 248, { 1251, 21025, 10007, 855, 0, ';' }},
+       {0x3401, 0x0001, 257, 61, 49581, 49587, 49603, 49633, 36521, 36492, 49637, {36525, 0, 0, 0}, 249, 249, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x3409, 0x0009, 257, 87, 49640, 49646, 49646, 49668, 37011, 36996, 45743, {37015, 0, 0, 0}, 250, 250, { 1252, 500, 10000, 437, 0, ',' }},
+       {0x340A, 0x000A, 257, 20, 49672, 49678, 49694, 49711, 37058, 37034, 49715, {37062, 0, 0, 0}, 251, 251, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x3801, 0x0001, 257, 0, 49718, 49724, 49754, 49818, 36521, 36492, 49822, {36525, 0, 0, 0}, 252, 252, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x380A, 0x000A, 257, 113, 49825, 49831, 49849, 49868, 37058, 37034, 49872, {37062, 0, 0, 0}, 253, 253, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x3C01, 0x0001, 257, 12, 49875, 49881, 49898, 49930, 36521, 36492, 49934, {36525, 0, 0, 0}, 254, 254, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x3C0A, 0x000A, 257, 92, 49937, 49943, 49962, 49982, 37058, 37034, 49986, {37062, 0, 0, 0}, 255, 255, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x4001, 0x0001, 257, 93, 49989, 49995, 50010, 50034, 36521, 36492, 50038, {36525, 0, 0, 0}, 256, 256, { 1256, 20420, 10004, 720, 1, ';' }},
+       {0x4009, 0x0009, 257, 49, 50041, 50047, 50047, 50063, 37011, 36996, 44241, {37015, 0, 0, 0}, 257, 257, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x400A, 0x000A, 257, 14, 50067, 50073, 50091, 50110, 37058, 37034, 50114, {37062, 0, 0, 0}, 258, 258, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x440A, 0x000A, 257, 103, 50117, 50123, 50145, 50168, 37058, 37034, 50172, {37062, 0, 0, 0}, 259, 259, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x4809, 0x0009, 257, 100, 50175, 50181, 50181, 50201, 37011, 36996, 47576, {37015, 0, 0, 0}, 260, 260, { 1252, 37, 10000, 437, 0, ',' }},
+       {0x480A, 0x000A, 257, 43, 50205, 50211, 50230, 50250, 37058, 37034, 50254, {37062, 0, 0, 0}, 261, 261, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x4C0A, 0x000A, 257, 79, 50257, 50263, 50283, 50304, 37058, 37034, 50308, {37062, 0, 0, 0}, 262, 262, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x500A, 0x000A, 257, 90, 50311, 50317, 50339, 50362, 37058, 37034, 50366, {37062, 0, 0, 0}, 263, 263, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x540A, 0x000A, 257, 112, 50369, 50375, 50399, 50425, 37058, 37034, 41983, {37062, 0, 0, 0}, 264, 264, { 1252, 20284, 10000, 850, 0, ',' }},
+       {0x6C1A, 0x7C1A, 257, -1, 50429, 50437, 50456, 49156, 9243, 48414, 0, {38871, 0, 0, 0}, 265, 265, { 1251, 21025, 10007, 855, 0, ';' }},
+       {0x701A, 0x7C1A, 257, -1, 50469, 50477, 50456, 48980, 9243, 48414, 0, {48420, 0, 0, 0}, 266, 266, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x742C, 0x002C, 257, -1, 50493, 50501, 38742, 46815, 38760, 14519, 0, {38764, 0, 0, 0}, 267, 267, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x7804, 0x007F, 257, -1, 36732, 36750, 36717, 36724, 36728, 36732, 0, {36735, 0, 0, 0}, 268, 268, { 936, 500, 10008, 936, 0, ',' }},
+       {0x7814, 0x0014, 257, -1, 46663, 50524, 50542, 46655, 46659, 46663, 0, {36848, 0, 0, 0}, 269, 269, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x781A, 0x007F, 257, -1, 50550, 50553, 50561, 50570, 50574, 50550, 0, {48420, 0, 0, 0}, 270, 270, { 1250, 870, 10082, 852, 0, ';' }},
+       {0x782C, 0x002C, 257, -1, 50578, 50586, 38742, 38756, 38760, 14519, 0, {38764, 0, 0, 0}, 271, 271, { 1254, 20905, 10081, 857, 0, ';' }},
+       {0x7843, 0x0043, 257, -1, 50606, 50614, 39620, 39631, 39635, 39611, 0, {0, 0, 0, 0}, 272, 272, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x7850, 0x0050, 257, -1, 50631, 50639, 40496, 50660, 40513, 40483, 0, {0, 0, 0, 0}, 273, 273, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x7C04, 0x7804, 257, -1, 50664, 41693, 36717, 41731, 36728, 36732, 0, {41738, 0, 0, 0}, 274, 274, { 950, 500, 10002, 950, 0, ',' }},
+       {0x7C04, 0x7C04, 257, -1, 50672, 50679, 36717, 41731, 36728, 36732, 0, {41738, 0, 0, 0}, 275, 275, { 950, 500, 10002, 950, 0, ',' }},
+       {0x7C14, 0x0014, 257, -1, 37541, 50708, 50726, 37533, 37537, 37541, 0, {36848, 0, 0, 0}, 276, 276, { 1252, 20277, 10000, 850, 0, ';' }},
+       {0x7C1A, 0x007F, 257, -1, 48414, 50740, 50456, 50748, 9243, 48414, 0, {38871, 0, 0, 0}, 277, 277, { 1250, 500, 10029, 852, 0, ';' }},
+       {0x7C28, 0x0028, 257, -1, 50752, 50760, 0, 38585, 38589, 38576, 0, {0, 0, 0, 0}, 278, 278, { 1251, 20880, 10007, 866, 0, ';' }},
+       {0x7C43, 0x0043, 257, -1, 50777, 50785, 39620, 39631, 39635, 39611, 0, {0, 0, 0, 0}, 279, 279, { 1254, 500, 10029, 857, 0, ';' }},
+       {0x7C50, 0x0050, 257, -1, 50799, 50807, 40496, 47068, 40513, 40483, 0, {0, 0, 0, 0}, 280, 280, { 0, 500, 2, 1, 0, ',' }},
+       {0x7C5F, 0x005F, 257, -1, 50829, 50838, 40879, 40889, 40849, 40849, 0, {0, 0, 0, 0}, 281, 281, { 1252, 20297, 10000, 850, 0, ';' }},
+       {0x7C68, 0x0068, 257, -1, 50872, 50880, 41047, 41053, 41057, 41044, 0, {0, 0, 0, 0}, 282, 282, { 1252, 37, 10000, 437, 0, ',' }}
 };
 
 
 static const CultureInfoNameEntry culture_name_entries [] = {
-       {39011, 50},     /* af */
-       {50892, 145},    /* af-za */
+       {39013, 50},     /* af */
+       {50894, 145},    /* af-za */
        {7865, 80},      /* am */
-       {50898, 171},    /* am-et */
-       {36490, 0},      /* ar */
-       {50904, 252},    /* ar-ae */
-       {50910, 254},    /* ar-bh */
-       {50916, 216},    /* ar-dz */
-       {50922, 203},    /* ar-eg */
-       {50928, 186},    /* ar-iq */
-       {50934, 241},    /* ar-jo */
-       {50940, 249},    /* ar-kw */
-       {50946, 245},    /* ar-lb */
-       {50952, 210},    /* ar-ly */
-       {50958, 222},    /* ar-ma */
-       {50964, 231},    /* ar-om */
-       {50970, 256},    /* ar-qa */
-       {50976, 97},     /* ar-sa */
-       {50982, 237},    /* ar-sy */
-       {50988, 227},    /* ar-tn */
-       {50994, 234},    /* ar-ye */
+       {50900, 171},    /* am-et */
+       {36492, 0},      /* ar */
+       {50906, 252},    /* ar-ae */
+       {50912, 254},    /* ar-bh */
+       {50918, 216},    /* ar-dz */
+       {50924, 203},    /* ar-eg */
+       {50930, 186},    /* ar-iq */
+       {50936, 241},    /* ar-jo */
+       {50942, 249},    /* ar-kw */
+       {50948, 245},    /* ar-lb */
+       {50954, 210},    /* ar-ly */
+       {50960, 222},    /* ar-ma */
+       {50966, 231},    /* ar-om */
+       {50972, 256},    /* ar-qa */
+       {50978, 97},     /* ar-sa */
+       {50984, 237},    /* ar-sy */
+       {50990, 227},    /* ar-tn */
+       {50996, 234},    /* ar-ye */
        {14516, 70},     /* as */
-       {51000, 162},    /* as-in */
+       {51002, 162},    /* as-in */
        {14519, 44},     /* az */
-       {51006, 267},    /* az-cyrl */
-       {51014, 197},    /* az-cyrl-az */
-       {51025, 271},    /* az-latn */
-       {51033, 139},    /* az-latn-az */
-       {38283, 35},     /* be */
-       {51044, 130},    /* be-by */
-       {36551, 1},      /* bg */
-       {51050, 98},     /* bg-bg */
-       {39637, 62},     /* bn */
-       {51056, 201},    /* bn-bd */
-       {51062, 155},    /* bn-in */
-       {40515, 73},     /* bo */
-       {51068, 164},    /* bo-cn */
-       {41225, 91},     /* br */
-       {51074, 181},    /* br-fr */
-       {50548, 270},    /* bs */
-       {36633, 2},      /* ca */
-       {51080, 99},     /* ca-es */
-       {36769, 5},      /* cs */
-       {51086, 101},    /* cs-cz */
-       {40559, 74},     /* cy */
-       {51092, 165},    /* cy-gb */
-       {36822, 6},      /* da */
-       {51098, 102},    /* da-dk */
-       {36867, 7},      /* de */
-       {51104, 205},    /* de-at */
-       {51110, 188},    /* de-ch */
-       {51116, 103},    /* de-de */
-       {51122, 218},    /* de-li */
-       {51128, 212},    /* de-lu */
-       {36918, 8},      /* el */
-       {51134, 104},    /* el-gr */
-       {36994, 9},      /* en */
-       {51140, 206},    /* en-au */
-       {51146, 238},    /* en-bz */
-       {51152, 213},    /* en-ca */
-       {51158, 189},    /* en-gb */
-       {51164, 223},    /* en-ie */
-       {51170, 257},    /* en-in */
-       {51176, 232},    /* en-jm */
-       {51182, 219},    /* en-nz */
-       {51188, 250},    /* en-ph */
-       {51194, 260},    /* en-sg */
-       {51200, 242},    /* en-tt */
-       {51206, 105},    /* en-us */
-       {51212, 228},    /* en-za */
-       {51218, 246},    /* en-zw */
-       {37032, 10},     /* es */
-       {51224, 243},    /* es-ar */
-       {51230, 258},    /* es-bo */
-       {51236, 251},    /* es-cl */
-       {51242, 235},    /* es-co */
-       {51248, 220},    /* es-cr */
-       {51254, 229},    /* es-do */
-       {51260, 247},    /* es-ec */
-       {51266, 207},    /* es-es */
-       {51272, 214},    /* es-gt */
-       {51278, 261},    /* es-hn */
-       {51284, 190},    /* es-mx */
-       {51290, 262},    /* es-ni */
-       {51296, 224},    /* es-pa */
-       {51302, 239},    /* es-pe */
-       {51308, 263},    /* es-pr */
-       {51314, 255},    /* es-py */
-       {51320, 259},    /* es-sv */
-       {51326, 264},    /* es-us */
-       {51332, 253},    /* es-uy */
-       {51338, 233},    /* es-ve */
-       {38425, 37},     /* et */
-       {51344, 132},    /* et-ee */
-       {38780, 45},     /* eu */
-       {51350, 140},    /* eu-es */
-       {38591, 41},     /* fa */
-       {51356, 136},    /* fa-ir */
-       {37082, 11},     /* fi */
-       {51362, 106},    /* fi-fi */
-       {41002, 84},     /* fil */
-       {51368, 174},    /* fil-ph */
-       {39159, 52},     /* fo */
-       {51375, 147},    /* fo-fo */
-       {37132, 12},     /* fr */
-       {51381, 191},    /* fr-be */
-       {51387, 208},    /* fr-ca */
-       {51393, 215},    /* fr-ch */
-       {51399, 107},    /* fr-fr */
-       {51405, 221},    /* fr-lu */
-       {51411, 225},    /* fr-mc */
-       {39353, 56},     /* ga */
-       {51417, 198},    /* ga-ie */
-       {41420, 96},     /* gd */
-       {51423, 185},    /* gd-gb */
-       {40654, 77},     /* gl */
-       {51429, 168},    /* gl-es */
-       {41300, 93},     /* gsw */
-       {39775, 64},     /* gu */
-       {51435, 156},    /* gu-in */
-       {41042, 85},     /* ha */
-       {51441, 282},    /* ha-latn */
-       {51449, 175},    /* ha-latn-ng */
-       {37182, 13},     /* he */
-       {51460, 108},    /* he-il */
-       {39188, 53},     /* hi */
-       {51466, 148},    /* hi-in */
-       {37824, 26},     /* hr */
-       {51472, 121},    /* hr-hr */
-       {37244, 14},     /* hu */
-       {51478, 109},    /* hu-hu */
-       {38693, 43},     /* hy */
-       {51484, 138},    /* hy-am */
-       {38137, 33},     /* id */
-       {51490, 128},    /* id-id */
+       {51008, 267},    /* az-cyrl */
+       {51016, 197},    /* az-cyrl-az */
+       {51027, 271},    /* az-latn */
+       {51035, 139},    /* az-latn-az */
+       {38285, 35},     /* be */
+       {51046, 130},    /* be-by */
+       {36553, 1},      /* bg */
+       {51052, 98},     /* bg-bg */
+       {39639, 62},     /* bn */
+       {51058, 201},    /* bn-bd */
+       {51064, 155},    /* bn-in */
+       {40517, 73},     /* bo */
+       {51070, 164},    /* bo-cn */
+       {41227, 91},     /* br */
+       {51076, 181},    /* br-fr */
+       {50550, 270},    /* bs */
+       {36635, 2},      /* ca */
+       {51082, 99},     /* ca-es */
+       {36771, 5},      /* cs */
+       {51088, 101},    /* cs-cz */
+       {40561, 74},     /* cy */
+       {51094, 165},    /* cy-gb */
+       {36824, 6},      /* da */
+       {51100, 102},    /* da-dk */
+       {36869, 7},      /* de */
+       {51106, 205},    /* de-at */
+       {51112, 188},    /* de-ch */
+       {51118, 103},    /* de-de */
+       {51124, 218},    /* de-li */
+       {51130, 212},    /* de-lu */
+       {36920, 8},      /* el */
+       {51136, 104},    /* el-gr */
+       {36996, 9},      /* en */
+       {51142, 206},    /* en-au */
+       {51148, 238},    /* en-bz */
+       {51154, 213},    /* en-ca */
+       {51160, 189},    /* en-gb */
+       {51166, 223},    /* en-ie */
+       {51172, 257},    /* en-in */
+       {51178, 232},    /* en-jm */
+       {51184, 219},    /* en-nz */
+       {51190, 250},    /* en-ph */
+       {51196, 260},    /* en-sg */
+       {51202, 242},    /* en-tt */
+       {51208, 105},    /* en-us */
+       {51214, 228},    /* en-za */
+       {51220, 246},    /* en-zw */
+       {37034, 10},     /* es */
+       {51226, 243},    /* es-ar */
+       {51232, 258},    /* es-bo */
+       {51238, 251},    /* es-cl */
+       {51244, 235},    /* es-co */
+       {51250, 220},    /* es-cr */
+       {51256, 229},    /* es-do */
+       {51262, 247},    /* es-ec */
+       {51268, 207},    /* es-es */
+       {51274, 214},    /* es-gt */
+       {51280, 261},    /* es-hn */
+       {51286, 190},    /* es-mx */
+       {51292, 262},    /* es-ni */
+       {51298, 224},    /* es-pa */
+       {51304, 239},    /* es-pe */
+       {51310, 263},    /* es-pr */
+       {51316, 255},    /* es-py */
+       {51322, 259},    /* es-sv */
+       {51328, 264},    /* es-us */
+       {51334, 253},    /* es-uy */
+       {51340, 233},    /* es-ve */
+       {38427, 37},     /* et */
+       {51346, 132},    /* et-ee */
+       {38782, 45},     /* eu */
+       {51352, 140},    /* eu-es */
+       {38593, 41},     /* fa */
+       {51358, 136},    /* fa-ir */
+       {37084, 11},     /* fi */
+       {51364, 106},    /* fi-fi */
+       {41004, 84},     /* fil */
+       {51370, 174},    /* fil-ph */
+       {39161, 52},     /* fo */
+       {51377, 147},    /* fo-fo */
+       {37134, 12},     /* fr */
+       {51383, 191},    /* fr-be */
+       {51389, 208},    /* fr-ca */
+       {51395, 215},    /* fr-ch */
+       {51401, 107},    /* fr-fr */
+       {51407, 221},    /* fr-lu */
+       {51413, 225},    /* fr-mc */
+       {39355, 56},     /* ga */
+       {51419, 198},    /* ga-ie */
+       {41422, 96},     /* gd */
+       {51425, 185},    /* gd-gb */
+       {40656, 77},     /* gl */
+       {51431, 168},    /* gl-es */
+       {41302, 93},     /* gsw */
+       {39777, 64},     /* gu */
+       {51437, 156},    /* gu-in */
+       {41044, 85},     /* ha */
+       {51443, 282},    /* ha-latn */
+       {51451, 175},    /* ha-latn-ng */
+       {37184, 13},     /* he */
+       {51462, 108},    /* he-il */
+       {39190, 53},     /* hi */
+       {51468, 148},    /* hi-in */
+       {37826, 26},     /* hr */
+       {51474, 121},    /* hr-hr */
+       {37246, 14},     /* hu */
+       {51480, 109},    /* hu-hu */
+       {38695, 43},     /* hy */
+       {51486, 138},    /* hy-am */
+       {38139, 33},     /* id */
+       {51492, 128},    /* id-id */
        {14510, 89},     /* ig */
-       {51496, 179},    /* ig-ng */
-       {41180, 90},     /* ii */
-       {51502, 180},    /* ii-cn */
-       {37288, 15},     /* is */
-       {51508, 110},    /* is-is */
-       {37339, 16},     /* it */
-       {51514, 192},    /* it-ch */
-       {51520, 111},    /* it-it */
-       {37367, 17},     /* ja */
-       {51526, 112},    /* ja-jp */
-       {39052, 51},     /* ka */
-       {51532, 146},    /* ka-ge */
-       {39447, 58},     /* kk */
-       {41132, 88},     /* kl */
-       {51538, 178},    /* kl-gl */
-       {40584, 75},     /* km */
-       {51544, 166},    /* km-kh */
-       {35839, 68},     /* kn */
-       {51550, 160},    /* kn-in */
-       {37424, 18},     /* ko */
-       {51556, 113},    /* ko-kr */
-       {40681, 78},     /* kok */
-       {51562, 169},    /* kok-in */
-       {39527, 59},     /* ky */
-       {51569, 152},    /* ky-kg */
-       {40629, 76},     /* lo */
-       {51575, 167},    /* lo-la */
-       {38519, 39},     /* lt */
-       {51581, 134},    /* lt-lt */
-       {38471, 38},     /* lv */
-       {51587, 133},    /* lv-lv */
-       {38826, 46},     /* mk */
-       {51593, 141},    /* mk-mk */
-       {40206, 69},     /* ml */
-       {51599, 161},    /* ml-in */
-       {40481, 72},     /* mn */
-       {51605, 273},    /* mn-cyrl */
-       {51613, 280},    /* mn-mong */
-       {51621, 202},    /* mn-mong-cn */
-       {40388, 71},     /* mr */
-       {51632, 163},    /* mr-in */
-       {39399, 57},     /* ms */
-       {51638, 199},    /* ms-bn */
-       {51644, 151},    /* ms-my */
-       {39265, 54},     /* mt */
-       {51650, 149},    /* mt-mt */
-       {37539, 276},    /* nb */
-       {51656, 115},    /* nb-no */
+       {51498, 179},    /* ig-ng */
+       {41182, 90},     /* ii */
+       {51504, 180},    /* ii-cn */
+       {37290, 15},     /* is */
+       {51510, 110},    /* is-is */
+       {37341, 16},     /* it */
+       {51516, 192},    /* it-ch */
+       {51522, 111},    /* it-it */
+       {37369, 17},     /* ja */
+       {51528, 112},    /* ja-jp */
+       {39054, 51},     /* ka */
+       {51534, 146},    /* ka-ge */
+       {39449, 58},     /* kk */
+       {41134, 88},     /* kl */
+       {51540, 178},    /* kl-gl */
+       {40586, 75},     /* km */
+       {51546, 166},    /* km-kh */
+       {35841, 68},     /* kn */
+       {51552, 160},    /* kn-in */
+       {37426, 18},     /* ko */
+       {51558, 113},    /* ko-kr */
+       {40683, 78},     /* kok */
+       {51564, 169},    /* kok-in */
+       {39529, 59},     /* ky */
+       {51571, 152},    /* ky-kg */
+       {40631, 76},     /* lo */
+       {51577, 167},    /* lo-la */
+       {38521, 39},     /* lt */
+       {51583, 134},    /* lt-lt */
+       {38473, 38},     /* lv */
+       {51589, 133},    /* lv-lv */
+       {38828, 46},     /* mk */
+       {51595, 141},    /* mk-mk */
+       {40208, 69},     /* ml */
+       {51601, 161},    /* ml-in */
+       {40483, 72},     /* mn */
+       {51607, 273},    /* mn-cyrl */
+       {51615, 280},    /* mn-mong */
+       {51623, 202},    /* mn-mong-cn */
+       {40390, 71},     /* mr */
+       {51634, 163},    /* mr-in */
+       {39401, 57},     /* ms */
+       {51640, 199},    /* ms-bn */
+       {51646, 151},    /* ms-my */
+       {39267, 54},     /* mt */
+       {51652, 149},    /* mt-mt */
+       {37541, 276},    /* nb */
+       {51658, 115},    /* nb-no */
        {2059, 82},      /* ne */
-       {51662, 172},    /* ne-np */
-       {37462, 19},     /* nl */
-       {51668, 193},    /* nl-be */
-       {51674, 114},    /* nl-nl */
-       {46661, 269},    /* nn */
-       {51680, 194},    /* nn-no */
-       {37512, 20},     /* no */
-       {41092, 87},     /* nso */
-       {51686, 177},    /* nso-za */
-       {41273, 92},     /* oc */
-       {51693, 182},    /* oc-fr */
+       {51664, 172},    /* ne-np */
+       {37464, 19},     /* nl */
+       {51670, 193},    /* nl-be */
+       {51676, 114},    /* nl-nl */
+       {46663, 269},    /* nn */
+       {51682, 194},    /* nn-no */
+       {37514, 20},     /* no */
+       {41094, 87},     /* nso */
+       {51688, 177},    /* nso-za */
+       {41275, 92},     /* oc */
+       {51695, 182},    /* oc-fr */
        {14525, 65},     /* or */
-       {51699, 157},    /* or-in */
-       {39737, 63},     /* pa */
-       {37542, 21},     /* pl */
-       {51705, 116},    /* pl-pl */
-       {40975, 83},     /* ps */
-       {51711, 173},    /* ps-af */
-       {37591, 22},     /* pt */
-       {51717, 117},    /* pt-br */
-       {51723, 195},    /* pt-pt */
-       {37647, 23},     /* rm */
-       {51729, 118},    /* rm-ch */
-       {37696, 24},     /* ro */
-       {51735, 119},    /* ro-ro */
-       {37744, 25},     /* ru */
-       {51741, 120},    /* ru-ru */
-       {41397, 95},     /* rw */
-       {51747, 184},    /* rw-rw */
-       {41365, 94},     /* sah */
-       {51753, 183},    /* sah-ru */
-       {39311, 55},     /* se */
-       {51760, 209},    /* se-fi */
-       {51766, 150},    /* se-no */
-       {40716, 79},     /* si */
-       {51772, 170},    /* si-lk */
-       {37876, 27},     /* sk */
-       {51778, 122},    /* sk-sk */
-       {38368, 36},     /* sl */
-       {51784, 131},    /* sl-si */
-       {37930, 28},     /* sq */
-       {51790, 123},    /* sq-al */
-       {48412, 277},    /* sr */
-       {51796, 265},    /* sr-cyrl */
-       {51804, 230},    /* sr-cyrl-ba */
-       {51815, 248},    /* sr-cyrl-me */
-       {51826, 240},    /* sr-cyrl-rs */
-       {51837, 266},    /* sr-latn */
-       {51845, 226},    /* sr-latn-ba */
-       {51856, 244},    /* sr-latn-me */
-       {51867, 236},    /* sr-latn-rs */
-       {37956, 29},     /* sv */
-       {51878, 196},    /* sv-fi */
-       {51884, 124},    /* sv-se */
-       {39559, 60},     /* sw */
-       {51890, 153},    /* sw-ke */
-       {39903, 66},     /* ta */
-       {51896, 158},    /* ta-in */
-       {40001, 67},     /* te */
-       {51902, 159},    /* te-in */
-       {38574, 40},     /* tg */
-       {51908, 278},    /* tg-cyrl */
-       {51916, 135},    /* tg-cyrl-tj */
-       {37983, 30},     /* th */
-       {51927, 125},    /* th-th */
-       {38913, 47},     /* tn */
-       {51933, 142},    /* tn-za */
-       {38040, 31},     /* tr */
-       {51939, 126},    /* tr-tr */
-       {40847, 81},     /* tzm */
-       {51945, 281},    /* tzm-latn */
-       {38195, 34},     /* uk */
-       {51954, 129},    /* uk-ua */
-       {38082, 32},     /* ur */
-       {51960, 127},    /* ur-pk */
-       {39609, 61},     /* uz */
-       {51966, 272},    /* uz-cyrl */
-       {51974, 200},    /* uz-cyrl-uz */
-       {51985, 279},    /* uz-latn */
-       {51993, 154},    /* uz-latn-uz */
-       {38645, 42},     /* vi */
-       {52004, 137},    /* vi-vn */
-       {38940, 48},     /* xh */
-       {52010, 143},    /* xh-za */
-       {41059, 86},     /* yo */
-       {52016, 176},    /* yo-ng */
-       {36730, 268},    /* zh */
-       {52022, 3},      /* zh-chs */
-       {52029, 275},    /* zh-cht */
-       {52036, 187},    /* zh-cn */
-       {52042, 4},      /* zh-hans */
-       {52050, 274},    /* zh-hant */
-       {52058, 204},    /* zh-hk */
-       {52064, 217},    /* zh-mo */
-       {52070, 211},    /* zh-sg */
-       {52076, 100},    /* zh-tw */
-       {38966, 49},     /* zu */
-       {52082, 144}     /* zu-za */
+       {51701, 157},    /* or-in */
+       {39739, 63},     /* pa */
+       {37544, 21},     /* pl */
+       {51707, 116},    /* pl-pl */
+       {40977, 83},     /* ps */
+       {51713, 173},    /* ps-af */
+       {37593, 22},     /* pt */
+       {51719, 117},    /* pt-br */
+       {51725, 195},    /* pt-pt */
+       {37649, 23},     /* rm */
+       {51731, 118},    /* rm-ch */
+       {37698, 24},     /* ro */
+       {51737, 119},    /* ro-ro */
+       {37746, 25},     /* ru */
+       {51743, 120},    /* ru-ru */
+       {41399, 95},     /* rw */
+       {51749, 184},    /* rw-rw */
+       {41367, 94},     /* sah */
+       {51755, 183},    /* sah-ru */
+       {39313, 55},     /* se */
+       {51762, 209},    /* se-fi */
+       {51768, 150},    /* se-no */
+       {40718, 79},     /* si */
+       {51774, 170},    /* si-lk */
+       {37878, 27},     /* sk */
+       {51780, 122},    /* sk-sk */
+       {38370, 36},     /* sl */
+       {51786, 131},    /* sl-si */
+       {37932, 28},     /* sq */
+       {51792, 123},    /* sq-al */
+       {48414, 277},    /* sr */
+       {51798, 265},    /* sr-cyrl */
+       {51806, 230},    /* sr-cyrl-ba */
+       {51817, 248},    /* sr-cyrl-me */
+       {51828, 240},    /* sr-cyrl-rs */
+       {51839, 266},    /* sr-latn */
+       {51847, 226},    /* sr-latn-ba */
+       {51858, 244},    /* sr-latn-me */
+       {51869, 236},    /* sr-latn-rs */
+       {37958, 29},     /* sv */
+       {51880, 196},    /* sv-fi */
+       {51886, 124},    /* sv-se */
+       {39561, 60},     /* sw */
+       {51892, 153},    /* sw-ke */
+       {39905, 66},     /* ta */
+       {51898, 158},    /* ta-in */
+       {40003, 67},     /* te */
+       {51904, 159},    /* te-in */
+       {38576, 40},     /* tg */
+       {51910, 278},    /* tg-cyrl */
+       {51918, 135},    /* tg-cyrl-tj */
+       {37985, 30},     /* th */
+       {51929, 125},    /* th-th */
+       {38915, 47},     /* tn */
+       {51935, 142},    /* tn-za */
+       {38042, 31},     /* tr */
+       {51941, 126},    /* tr-tr */
+       {40849, 81},     /* tzm */
+       {51947, 281},    /* tzm-latn */
+       {38197, 34},     /* uk */
+       {51956, 129},    /* uk-ua */
+       {38084, 32},     /* ur */
+       {51962, 127},    /* ur-pk */
+       {39611, 61},     /* uz */
+       {51968, 272},    /* uz-cyrl */
+       {51976, 200},    /* uz-cyrl-uz */
+       {51987, 279},    /* uz-latn */
+       {51995, 154},    /* uz-latn-uz */
+       {38647, 42},     /* vi */
+       {52006, 137},    /* vi-vn */
+       {38942, 48},     /* xh */
+       {52012, 143},    /* xh-za */
+       {41061, 86},     /* yo */
+       {52018, 176},    /* yo-ng */
+       {36732, 268},    /* zh */
+       {52024, 3},      /* zh-chs */
+       {52031, 275},    /* zh-cht */
+       {52038, 187},    /* zh-cn */
+       {52044, 4},      /* zh-hans */
+       {52052, 274},    /* zh-hant */
+       {52060, 204},    /* zh-hk */
+       {52066, 217},    /* zh-mo */
+       {52072, 211},    /* zh-sg */
+       {52078, 100},    /* zh-tw */
+       {38968, 49},     /* zu */
+       {52084, 144}     /* zu-za */
 };
 
 
 static const RegionInfoEntry region_entries [] = {
-       { 224,49820,47115,47115,52088,52109,36426,52156,52160,52188},
-       { 3,45687,52212,52212,52216,52228,36206,52247,52251,52266},
-       { 6,42867,52279,52279,52283,52291,35842,52302,52306,0},
-       { 7,3781,48169,48169,52319,52327,35987,52375,52379,0},
-       { 11,49311,47816,47816,52393,52393,35586,49034,52403,52418},
-       { 14,47264,52433,52433,52437,52445,35481,52457,52461,52461},
-       { 12,47297,52466,52466,52470,52470,35586,52480,52484,52484},
-       { 5,43762,38754,38754,52502,52513,36234,52525,52529,52547},
-       { 25,48415,52567,52567,52571,52594,36324,52631,52635,52671},
-       { 23,47023,52714,52714,52718,52729,36272,52754,52758,52775},
-       { 21,46502,38318,38318,52816,52824,35481,52457,52461,52833},
-       { 35,41639,36583,36583,52838,52847,35465,52864,52868,52882},
-       { 17,49932,52908,52908,52912,52920,36436,52935,52939,52954},
-       { 37,46906,52978,52978,52982,52982,35586,52989,52993,53007},
-       { 26,50112,53020,53020,53024,53024,36460,40551,53032,53051},
-       { 32,42559,53061,53061,53065,53072,35735,53079,53083,53098},
-       { 29,43253,53114,53114,53118,53126,0,53143,53147,53164},
-       { 24,49068,53196,53196,53200,53200,35586,53207,53211,53211},
-       { 39,47390,53225,53225,53229,53229,35586,53236,53240,53256},
-       { 223,13261,53272,53272,53276,53288,0,53295,53299,53311},
-       { 46,49713,53325,53325,53329,53329,35586,53335,53339,53352},
-       { 45,13340,53365,53365,53369,53375,36162,53394,53398,53411},
-       { 51,48912,53430,53430,53434,53434,35586,53443,53447,53462},
-       { 54,48060,53478,53478,53482,53482,36306,53493,53497,53516},
-       { 75,41802,53537,53537,53541,53556,35506,53574,53578,53600},
-       { 94,41892,36885,36885,53615,53623,35481,52457,52461,52461},
-       { 61,41844,53635,53635,53639,53647,35534,53655,53659,53672},
-       { 65,48602,53684,53684,53688,53707,35586,53729,53733,53748},
-       { 4,47820,53764,53764,53768,53776,36296,53791,53795,53810},
-       { 66,49530,53834,53834,53838,53838,35586,53846,53850,53860},
-       { 70,43351,50423,50423,53882,53890,35481,52457,52461,52833},
-       { 67,47119,53896,53896,53900,53906,36276,53913,53917,53932},
-       { 217,41682,37052,37052,53950,53956,35481,52457,52461,52833},
-       { 73,45566,53964,53964,53968,53977,36186,53993,53997,54012},
-       { 77,42022,37099,37099,54038,54046,35481,52457,52461,52833},
-       { 81,44182,54052,54052,54056,54070,35534,53655,53659,54079},
-       { 84,42066,37152,37152,54092,54092,35481,52457,52461,52833},
-       { 242,45211,54099,54099,54103,54118,36167,54131,54135,54158},
-       { 88,44128,54180,54180,54184,54192,0,54223,54227,54241},
-       { 93,45965,54276,54276,54280,54290,35534,53655,53659,54307},
-       { 98,41948,54325,54325,54329,54336,35481,52457,52461,54349},
-       { 99,47708,54358,54358,54362,54362,7774,54372,54376,54395},
-       { 104,47212,54416,54416,54420,54440,35586,54468,54472,54489},
-       { 106,50252,54496,54496,54500,54500,2471,54509,54513,54530},
-       { 108,42758,37845,37845,54549,54557,35839,54566,54570,54584},
-       { 109,42167,37264,37264,54589,54597,35636,54611,54615,54632},
-       { 111,43116,54646,54646,54650,54650,35865,54660,54664,54682},
-       { 68,46855,54699,54699,54703,54711,35481,52457,52461,52461},
-       { 117,42115,54717,54717,54721,54728,35632,54739,54743,54762},
-       { 113,44239,38168,38168,54769,54775,36012,54788,54792,54805},
-       { 121,46296,54840,54840,54844,54849,36245,54862,54866,54878},
-       { 116,43540,54900,54900,54904,54909,35979,54920,54924,54937},
-       { 110,42216,37311,37311,54957,54965,35534,54973,54977,54994},
-       { 118,42259,37359,37359,55010,55016,35481,52457,52461,52461},
-       { 124,48750,55023,55023,55027,55027,35586,55035,55039,55039},
-       { 126,49214,55055,55055,55059,55066,36396,55079,55083,55099},
-       { 122,42304,37389,37389,55121,55127,35502,55134,55138,55151},
-       { 129,44492,55161,55161,55165,55165,36026,55171,55175,55191},
-       { 130,44449,55209,55209,55213,55224,36019,55245,55249,0},
-       { 40,45289,40621,40621,55264,55273,36170,55295,55299,55314},
-       { 134,42359,37444,37444,55319,55331,35670,55344,55348,55365},
-       { 136,49635,55382,55382,55386,55393,36416,55406,55410,55424},
-       { 138,45331,40646,40646,55446,40636,36174,55451,55455,55467},
-       { 139,49448,55477,55477,55481,55489,36406,55500,55504,55519},
-       { 145,47969,55541,55541,55545,55545,0,53295,53299,55559},
-       { 42,45507,55577,55577,55581,55591,36178,55623,55627,55644},
-       { 141,43449,55679,55679,55683,55693,35955,55701,55705,55722},
-       { 147,47627,55728,55728,55732,55743,35481,52457,52461,52461},
-       { 140,43397,55753,55753,55757,55764,35915,55772,55776,55789},
-       { 148,47510,55803,55803,55807,55813,36286,55824,55828,55841},
-       { 159,48173,40415,40415,55861,55869,36310,55882,55886,55902},
-       { 158,48298,55922,55922,55926,55926,35481,52457,52461,52833},
-       { 270,49390,55933,55933,55937,55948,35481,52457,52461,55966},
-       { 19618,43878,55971,55971,55975,55985,0,55971,56006,56023},
-       { 151,47909,56055,56055,56059,56075,0,56103,56107,56123},
-       { 163,44278,39282,39282,56133,56133,35481,52457,52461,56139},
-       { 166,46451,56144,56144,56148,56155,35586,56163,56167,56180},
-       { 167,44383,56194,56194,56198,56198,36016,56207,56211,56229},
-       { 175,45795,56246,56246,56250,56258,36213,56267,56271,56286},
-       { 182,50306,56292,56292,56296,56296,36467,56306,56310,56330},
-       { 176,42411,37482,37482,56353,56365,35481,52457,52461,52461},
-       { 177,42469,37531,37531,56375,56382,35534,56388,56392,56408},
-       { 178,45627,56422,56422,56426,56432,36193,56448,56452,0},
-       { 183,48004,56467,56467,56471,56471,35586,56483,56487,56487},
-       { 164,48719,56506,56506,56510,56515,36343,56526,56530,56541},
-       { 192,48250,39767,39767,56561,56568,36320,56576,56580,56598},
-       { 187,49113,56615,56615,56619,56624,36384,56630,56634,56653},
-       { 201,45741,56671,56671,56675,56687,36209,56697,56701,56701},
-       { 190,43055,56717,56717,56721,56730,35860,56745,56749,56765},
-       { 191,42510,56793,56793,56797,56804,35693,56811,56815,56828},
-       { 202,50364,56842,56842,56846,56846,35586,53846,53850,53860},
-       { 193,46718,56858,56858,56862,56862,35481,52457,52461,52461},
-       { 185,49984,56871,56871,56875,56875,36446,56884,56888,56907},
-       { 197,50036,56926,56926,56930,56936,36450,56943,56947,56959},
-       { 200,42654,56977,56977,56981,56989,0,56998,57002,57015},
-       { 271,48982,50746,50746,57029,57036,36369,57049,57053,57067},
-       { 203,42710,37770,37770,57080,57087,35760,57100,57104,57118},
-       { 204,46164,57150,57150,57154,57154,36217,57161,57165,0},
-       { 205,13258,57179,57179,57183,57196,35409,57243,57247,57259},
-       { 221,42911,57279,57279,57283,57290,35534,57298,57302,57316},
-       { 215,47574,57329,57329,57333,57343,0,57353,57357,57374},
-       { 212,43309,57387,57387,57391,57400,35481,52457,52461,57410},
-       { 143,42820,57415,57415,57419,57428,35481,52457,52461,52461},
-       { 72,50170,38395,38395,57449,57449,36463,53846,53850,53860},
-       { 222,49038,57461,57461,57465,57471,36374,57482,57486,57499},
-       { 227,42958,38001,38001,57519,37991,35853,57528,57532,57542},
-       { 228,43492,57561,57561,57565,0,36019,57576,57580,57599},
-       { 234,48494,57612,57612,57616,57624,36327,57633,57637,57652},
-       { 235,43004,57673,57673,57677,57684,35857,57693,57697,57710},
-       { 225,49257,57724,57724,57728,57728,35586,57748,57752,57752},
-       { 237,41733,57779,57779,57783,57790,36220,57797,57801,57819},
-       { 241,43183,38229,38229,57829,57837,35868,57852,57856,57874},
-       { 244,41981,57908,57908,57912,57912,35586,53846,53850,53850},
-       { 246,49870,57926,57926,57930,57930,35586,57938,57942,57957},
-       { 247,44566,39629,39629,57971,57982,36239,58003,58007,58022},
-       { 249,48804,58041,58041,58045,58045,36353,58055,58059,58079},
-       { 251,43598,58099,58099,58103,58111,35983,58122,58126,58142},
-       { 261,48860,58150,58150,58154,58160,36359,58171,58175,58187},
-       { 209,43909,58205,58205,58209,0,10511,58222,58226,0},
-       { 264,49480,58245,58245,58249,58249,35586,53846,53850,53850}
+       { 224,49822,47117,47117,52090,52111,36428,52158,52162,52190},
+       { 3,45689,52214,52214,52218,52230,36210,52249,52253,52268},
+       { 6,42869,52281,52281,52285,52293,35844,52304,52308,0},
+       { 7,3781,48171,48171,52321,52329,35991,52377,52381,0},
+       { 11,49313,47818,47818,52395,52395,35586,49036,52405,52420},
+       { 14,47266,52435,52435,52439,52447,35481,52459,52463,52463},
+       { 12,47299,52468,52468,52472,52472,35586,52482,52486,52486},
+       { 5,43764,38756,38756,52504,52515,36238,52527,52531,52549},
+       { 25,48417,52569,52569,52573,52596,36326,52633,52637,52673},
+       { 23,47025,52716,52716,52720,52731,36274,52756,52760,52777},
+       { 21,46504,38320,38320,52818,52826,35481,52459,52463,52835},
+       { 35,41641,36585,36585,52840,52849,35465,52866,52870,52884},
+       { 17,49934,52910,52910,52914,52922,36438,52937,52941,52956},
+       { 37,46908,52980,52980,52984,52984,35586,52991,52995,53009},
+       { 26,50114,53022,53022,53026,53026,36462,40553,53034,53053},
+       { 32,42561,53063,53063,53067,53074,35735,53081,53085,53100},
+       { 29,43255,53116,53116,53120,53128,0,53145,53149,53166},
+       { 24,49070,53198,53198,53202,53202,35586,53209,53213,53213},
+       { 39,47392,53227,53227,53231,53231,35586,53238,53242,53258},
+       { 223,13261,53274,53274,53278,53290,0,53297,53301,53313},
+       { 46,49715,53327,53327,53331,53331,35586,53337,53341,53354},
+       { 45,13340,53367,53367,53371,53377,36166,53396,53400,53413},
+       { 51,48914,53432,53432,53436,53436,35586,53445,53449,53464},
+       { 54,48062,53480,53480,53484,53484,36308,53495,53499,53518},
+       { 75,41804,53539,53539,53543,53558,35506,53576,53580,53602},
+       { 94,41894,36887,36887,53617,53625,35481,52459,52463,52463},
+       { 61,41846,53637,53637,53641,53649,35534,53657,53661,53674},
+       { 65,48604,53686,53686,53690,53709,35586,53731,53735,53750},
+       { 4,47822,53766,53766,53770,53778,36298,53793,53797,53812},
+       { 66,49532,53836,53836,53840,53840,35586,53848,53852,53862},
+       { 70,43353,50425,50425,53884,53892,35481,52459,52463,52835},
+       { 67,47121,53898,53898,53902,53908,36278,53915,53919,53934},
+       { 217,41684,37054,37054,53952,53958,35481,52459,52463,52835},
+       { 73,45568,53966,53966,53970,53979,36190,53995,53999,54014},
+       { 77,42024,37101,37101,54040,54048,35481,52459,52463,52835},
+       { 81,44184,54054,54054,54058,54072,35534,53657,53661,54081},
+       { 84,42068,37154,37154,54094,54094,35481,52459,52463,52835},
+       { 242,45213,54101,54101,54105,54120,36171,54133,54137,54160},
+       { 88,44130,54182,54182,54186,54194,0,54225,54229,54243},
+       { 93,45967,54278,54278,54282,54292,35534,53657,53661,54309},
+       { 98,41950,54327,54327,54331,54338,35481,52459,52463,54351},
+       { 99,47710,54360,54360,54364,54364,7774,54374,54378,54397},
+       { 104,47214,54418,54418,54422,54442,35586,54470,54474,54491},
+       { 106,50254,54498,54498,54502,54502,2471,54511,54515,54532},
+       { 108,42760,37847,37847,54551,54559,35841,54568,54572,54586},
+       { 109,42169,37266,37266,54591,54599,35636,54613,54617,54634},
+       { 111,43118,54648,54648,54652,54652,35867,54662,54666,54684},
+       { 68,46857,54701,54701,54705,54713,35481,52459,52463,52463},
+       { 117,42117,54719,54719,54723,54730,35632,54741,54745,54764},
+       { 113,44241,38170,38170,54771,54777,36016,54790,54794,54807},
+       { 121,46298,54842,54842,54846,54851,36249,54864,54868,54880},
+       { 116,43542,54902,54902,54906,54911,35983,54922,54926,54939},
+       { 110,42218,37313,37313,54959,54967,35534,54975,54979,54996},
+       { 118,42261,37361,37361,55012,55018,35481,52459,52463,52463},
+       { 124,48752,55025,55025,55029,55029,35586,55037,55041,55041},
+       { 126,49216,55057,55057,55061,55068,36398,55081,55085,55101},
+       { 122,42306,37391,37391,55123,55129,35502,55136,55140,55153},
+       { 129,44494,55163,55163,55167,55167,36030,55173,55177,55193},
+       { 130,44451,55211,55211,55215,55226,36023,55247,55251,0},
+       { 40,45291,40623,40623,55266,55275,36174,55297,55301,55316},
+       { 134,42361,37446,37446,55321,55333,35670,55346,55350,55367},
+       { 136,49637,55384,55384,55388,55395,36418,55408,55412,55426},
+       { 138,45333,40648,40648,55448,40638,36178,55453,55457,55469},
+       { 139,49450,55479,55479,55483,55491,36408,55502,55506,55521},
+       { 145,47971,55543,55543,55547,55547,0,53297,53301,55561},
+       { 42,45509,55579,55579,55583,55593,36182,55625,55629,55646},
+       { 141,43451,55681,55681,55685,55695,35957,55703,55707,55724},
+       { 147,47629,55730,55730,55734,55745,35481,52459,52463,52463},
+       { 140,43399,55755,55755,55759,55766,35917,55774,55778,55791},
+       { 148,47512,55805,55805,55809,55815,36288,55826,55830,55843},
+       { 159,48175,40417,40417,55863,55871,36312,55884,55888,55904},
+       { 158,48300,55924,55924,55928,55928,35481,52459,52463,52835},
+       { 270,49392,55935,55935,55939,55950,35481,52459,52463,55968},
+       { 19618,43880,55973,55973,55977,55987,0,55973,56008,56025},
+       { 151,47911,56057,56057,56061,56077,0,56105,56109,56125},
+       { 163,44280,39284,39284,56135,56135,35481,52459,52463,56141},
+       { 166,46453,56146,56146,56150,56157,35586,56165,56169,56182},
+       { 167,44385,56196,56196,56200,56200,36020,56209,56213,56231},
+       { 175,45797,56248,56248,56252,56260,36217,56269,56273,56288},
+       { 182,50308,56294,56294,56298,56298,36469,56308,56312,56332},
+       { 176,42413,37484,37484,56355,56367,35481,52459,52463,52463},
+       { 177,42471,37533,37533,56377,56384,35534,56390,56394,56410},
+       { 178,45629,56424,56424,56428,56434,36197,56450,56454,0},
+       { 183,48006,56469,56469,56473,56473,35586,56485,56489,56489},
+       { 164,48721,56508,56508,56512,56517,36345,56528,56532,56543},
+       { 192,48252,39769,39769,56563,56570,36322,56578,56582,56600},
+       { 187,49115,56617,56617,56621,56626,36386,56632,56636,56655},
+       { 201,45743,56673,56673,56677,56689,36213,56699,56703,56703},
+       { 190,43057,56719,56719,56723,56732,35862,56747,56751,56767},
+       { 191,42512,56795,56795,56799,56806,35693,56813,56817,56830},
+       { 202,50366,56844,56844,56848,56848,35586,53848,53852,53862},
+       { 193,46720,56860,56860,56864,56864,35481,52459,52463,52463},
+       { 185,49986,56873,56873,56877,56877,36448,56886,56890,56909},
+       { 197,50038,56928,56928,56932,56938,36452,56945,56949,56961},
+       { 200,42656,56979,56979,56983,56991,0,57000,57004,57017},
+       { 271,48984,50748,50748,57031,57038,36371,57051,57055,57069},
+       { 203,42712,37772,37772,57082,57089,35762,57102,57106,57120},
+       { 204,46166,57152,57152,57156,57156,36221,57163,57167,0},
+       { 205,13258,57181,57181,57185,57198,35411,57245,57249,57261},
+       { 221,42913,57281,57281,57285,57292,35534,57300,57304,57318},
+       { 215,47576,57331,57331,57335,57345,0,57355,57359,57376},
+       { 212,43311,57389,57389,57393,57402,35481,52459,52463,57412},
+       { 143,42822,57417,57417,57421,57430,35481,52459,52463,52463},
+       { 72,50172,38397,38397,57451,57451,36465,53848,53852,53862},
+       { 222,49040,57463,57463,57467,57473,36376,57484,57488,57501},
+       { 227,42960,38003,38003,57521,37993,35855,57530,57534,57544},
+       { 228,43494,57563,57563,57567,0,36023,57578,57582,57601},
+       { 234,48496,57614,57614,57618,57626,36329,57635,57639,57654},
+       { 235,43006,57675,57675,57679,57686,35859,57695,57699,57712},
+       { 225,49259,57726,57726,57730,57730,35586,57750,57754,57754},
+       { 237,41735,57781,57781,57785,57792,36224,57799,57803,57821},
+       { 241,43185,38231,38231,57831,57839,35870,57854,57858,57876},
+       { 244,41983,57910,57910,57914,57914,35586,53848,53852,53852},
+       { 246,49872,57928,57928,57932,57932,35586,57940,57944,57959},
+       { 247,44568,39631,39631,57973,57984,36243,58005,58009,58024},
+       { 249,48806,58043,58043,58047,58047,36355,58057,58061,58081},
+       { 251,43600,58101,58101,58105,58113,35987,58124,58128,58144},
+       { 261,48862,58152,58152,58156,58162,36361,58173,58177,58189},
+       { 209,43911,58207,58207,58211,0,10511,58224,58228,0},
+       { 264,49482,58247,58247,58251,58251,35586,53848,53852,53852}
 };
 
 
 static const RegionInfoNameEntry region_name_entries [] = {
-       {49820, 0},      /* AE */
-       {45687, 1},      /* AF */
-       {42867, 2},      /* AL */
+       {49822, 0},      /* AE */
+       {45689, 1},      /* AF */
+       {42869, 2},      /* AL */
        {3781, 3},       /* AM */
-       {49311, 4},      /* AR */
-       {47264, 5},      /* AT */
-       {47297, 6},      /* AU */
-       {43762, 7},      /* AZ */
-       {48415, 8},      /* BA */
-       {47023, 9},      /* BD */
-       {46502, 10},     /* BE */
-       {41639, 11},     /* BG */
-       {49932, 12},     /* BH */
-       {46906, 13},     /* BN */
-       {50112, 14},     /* BO */
-       {42559, 15},     /* BR */
-       {43253, 16},     /* BY */
-       {49068, 17},     /* BZ */
-       {47390, 18},     /* CA */
+       {49313, 4},      /* AR */
+       {47266, 5},      /* AT */
+       {47299, 6},      /* AU */
+       {43764, 7},      /* AZ */
+       {48417, 8},      /* BA */
+       {47025, 9},      /* BD */
+       {46504, 10},     /* BE */
+       {41641, 11},     /* BG */
+       {49934, 12},     /* BH */
+       {46908, 13},     /* BN */
+       {50114, 14},     /* BO */
+       {42561, 15},     /* BR */
+       {43255, 16},     /* BY */
+       {49070, 17},     /* BZ */
+       {47392, 18},     /* CA */
        {13261, 19},     /* CH */
-       {49713, 20},     /* CL */
+       {49715, 20},     /* CL */
        {13340, 21},     /* CN */
-       {48912, 22},     /* CO */
-       {48060, 23},     /* CR */
-       {41802, 24},     /* CZ */
-       {41892, 25},     /* DE */
-       {41844, 26},     /* DK */
-       {48602, 27},     /* DO */
-       {47820, 28},     /* DZ */
-       {49530, 29},     /* EC */
-       {43351, 30},     /* EE */
-       {47119, 31},     /* EG */
-       {41682, 32},     /* ES */
-       {45566, 33},     /* ET */
-       {42022, 34},     /* FI */
-       {44182, 35},     /* FO */
-       {42066, 36},     /* FR */
-       {45211, 37},     /* GB */
-       {44128, 38},     /* GE */
-       {45965, 39},     /* GL */
-       {41948, 40},     /* GR */
-       {47708, 41},     /* GT */
-       {47212, 42},     /* HK */
-       {50252, 43},     /* HN */
-       {42758, 44},     /* HR */
-       {42167, 45},     /* HU */
-       {43116, 46},     /* ID */
-       {46855, 47},     /* IE */
-       {42115, 48},     /* IL */
-       {44239, 49},     /* IN */
-       {46296, 50},     /* IQ */
-       {43540, 51},     /* IR */
-       {42216, 52},     /* IS */
-       {42259, 53},     /* IT */
-       {48750, 54},     /* JM */
-       {49214, 55},     /* JO */
-       {42304, 56},     /* JP */
-       {44492, 57},     /* KE */
-       {44449, 58},     /* KG */
-       {45289, 59},     /* KH */
-       {42359, 60},     /* KR */
-       {49635, 61},     /* KW */
-       {45331, 62},     /* LA */
-       {49448, 63},     /* LB */
-       {47969, 64},     /* LI */
-       {45507, 65},     /* LK */
-       {43449, 66},     /* LT */
-       {47627, 67},     /* LU */
-       {43397, 68},     /* LV */
-       {47510, 69},     /* LY */
-       {48173, 70},     /* MA */
-       {48298, 71},     /* MC */
-       {49390, 72},     /* ME */
-       {43878, 73},     /* MK */
-       {47909, 74},     /* MO */
-       {44278, 75},     /* MT */
-       {46451, 76},     /* MX */
-       {44383, 77},     /* MY */
-       {45795, 78},     /* NG */
-       {50306, 79},     /* NI */
-       {42411, 80},     /* NL */
-       {42469, 81},     /* NO */
-       {45627, 82},     /* NP */
-       {48004, 83},     /* NZ */
-       {48719, 84},     /* OM */
-       {48250, 85},     /* PA */
-       {49113, 86},     /* PE */
-       {45741, 87},     /* PH */
-       {43055, 88},     /* PK */
-       {42510, 89},     /* PL */
-       {50364, 90},     /* PR */
-       {46718, 91},     /* PT */
-       {49984, 92},     /* PY */
-       {50036, 93},     /* QA */
-       {42654, 94},     /* RO */
-       {48982, 95},     /* RS */
-       {42710, 96},     /* RU */
-       {46164, 97},     /* RW */
+       {48914, 22},     /* CO */
+       {48062, 23},     /* CR */
+       {41804, 24},     /* CZ */
+       {41894, 25},     /* DE */
+       {41846, 26},     /* DK */
+       {48604, 27},     /* DO */
+       {47822, 28},     /* DZ */
+       {49532, 29},     /* EC */
+       {43353, 30},     /* EE */
+       {47121, 31},     /* EG */
+       {41684, 32},     /* ES */
+       {45568, 33},     /* ET */
+       {42024, 34},     /* FI */
+       {44184, 35},     /* FO */
+       {42068, 36},     /* FR */
+       {45213, 37},     /* GB */
+       {44130, 38},     /* GE */
+       {45967, 39},     /* GL */
+       {41950, 40},     /* GR */
+       {47710, 41},     /* GT */
+       {47214, 42},     /* HK */
+       {50254, 43},     /* HN */
+       {42760, 44},     /* HR */
+       {42169, 45},     /* HU */
+       {43118, 46},     /* ID */
+       {46857, 47},     /* IE */
+       {42117, 48},     /* IL */
+       {44241, 49},     /* IN */
+       {46298, 50},     /* IQ */
+       {43542, 51},     /* IR */
+       {42218, 52},     /* IS */
+       {42261, 53},     /* IT */
+       {48752, 54},     /* JM */
+       {49216, 55},     /* JO */
+       {42306, 56},     /* JP */
+       {44494, 57},     /* KE */
+       {44451, 58},     /* KG */
+       {45291, 59},     /* KH */
+       {42361, 60},     /* KR */
+       {49637, 61},     /* KW */
+       {45333, 62},     /* LA */
+       {49450, 63},     /* LB */
+       {47971, 64},     /* LI */
+       {45509, 65},     /* LK */
+       {43451, 66},     /* LT */
+       {47629, 67},     /* LU */
+       {43399, 68},     /* LV */
+       {47512, 69},     /* LY */
+       {48175, 70},     /* MA */
+       {48300, 71},     /* MC */
+       {49392, 72},     /* ME */
+       {43880, 73},     /* MK */
+       {47911, 74},     /* MO */
+       {44280, 75},     /* MT */
+       {46453, 76},     /* MX */
+       {44385, 77},     /* MY */
+       {45797, 78},     /* NG */
+       {50308, 79},     /* NI */
+       {42413, 80},     /* NL */
+       {42471, 81},     /* NO */
+       {45629, 82},     /* NP */
+       {48006, 83},     /* NZ */
+       {48721, 84},     /* OM */
+       {48252, 85},     /* PA */
+       {49115, 86},     /* PE */
+       {45743, 87},     /* PH */
+       {43057, 88},     /* PK */
+       {42512, 89},     /* PL */
+       {50366, 90},     /* PR */
+       {46720, 91},     /* PT */
+       {49986, 92},     /* PY */
+       {50038, 93},     /* QA */
+       {42656, 94},     /* RO */
+       {48984, 95},     /* RS */
+       {42712, 96},     /* RU */
+       {46166, 97},     /* RW */
        {13258, 98},     /* SA */
-       {42911, 99},     /* SE */
-       {47574, 100},    /* SG */
-       {43309, 101},    /* SI */
-       {42820, 102},    /* SK */
-       {50170, 103},    /* SV */
-       {49038, 104},    /* SY */
-       {42958, 105},    /* TH */
-       {43492, 106},    /* TJ */
-       {48494, 107},    /* TN */
-       {43004, 108},    /* TR */
-       {49257, 109},    /* TT */
-       {41733, 110},    /* TW */
-       {43183, 111},    /* UA */
-       {41981, 112},    /* US */
-       {49870, 113},    /* UY */
-       {44566, 114},    /* UZ */
-       {48804, 115},    /* VE */
-       {43598, 116},    /* VN */
-       {48860, 117},    /* YE */
-       {43909, 118},    /* ZA */
-       {49480, 119}     /* ZW */
+       {42913, 99},     /* SE */
+       {47576, 100},    /* SG */
+       {43311, 101},    /* SI */
+       {42822, 102},    /* SK */
+       {50172, 103},    /* SV */
+       {49040, 104},    /* SY */
+       {42960, 105},    /* TH */
+       {43494, 106},    /* TJ */
+       {48496, 107},    /* TN */
+       {43006, 108},    /* TR */
+       {49259, 109},    /* TT */
+       {41735, 110},    /* TW */
+       {43185, 111},    /* UA */
+       {41983, 112},    /* US */
+       {49872, 113},    /* UY */
+       {44568, 114},    /* UZ */
+       {48806, 115},    /* VE */
+       {43600, 116},    /* VN */
+       {48862, 117},    /* YE */
+       {43911, 118},    /* ZA */
+       {49482, 119}     /* ZW */
 };
 
 
@@ -4911,6 +4911,7 @@ static const char locale_strings [] = {
        "\xd9\x83\xd8\xa7\xd9\x86\xd9\x88\xd9\x86 \xd8\xa7\xd9\x84\xd8\xa3\xd9\x88\xd9\x84\0"
        "\xd1\x81\xd1\x80\xd0\xb5\0"
        "dddd, d MMMM, yyyy\0"
+       ",\0"
        "\xd9\xab\0"
        "\xd9\xac\0"
        "\xd8\xb1.\xd8\xb3.\xe2\x80\x8f\0"
@@ -4920,7 +4921,6 @@ static const char locale_strings [] = {
        "-Infinity\0"
        "Infinity\0"
        "+\0"
-       ",\0"
        "\xc2\xa0\0"
        "\xd0\xbb\xd0\xb2.\0"
        "%\0"
@@ -4956,6 +4956,7 @@ static const char locale_strings [] = {
        "-niesko\xc5\x84\x63zono\xc5\x9b\xc4\x87\0"
        "+niesko\xc5\x84\x63zono\xc5\x9b\xc4\x87\0"
        "R$\0"
+       "'\0"
        "\xe2\x80\x99\0"
        "-infinit\0"
        "+infinit\0"
@@ -4981,6 +4982,7 @@ static const char locale_strings [] = {
        "Lt\0"
        "-begalyb\xc4\x97\0"
        "begalyb\xc4\x97\0"
+       ";\0"
        "\xef\xb7\xbc\0"
        "\xe2\x82\xab\0"
        "\xd5\xa4\xd6\x80.\0"
@@ -5012,7 +5014,6 @@ static const char locale_strings [] = {
        "man.\0"
        "so\xca\xbcm\0"
        "\xd8\xaf.\xd8\xb9.\xe2\x80\x8f\0"
-       "'\0"
        "\xd0\xbc\xd0\xb0\xd0\xbd.\0"
        "\xd1\x81\xd1\x9e\xd0\xbc\0"
        "\xe0\xa7\xb3\0"
index fde7069c16a6674d8879d4b69aa6ca2bfaab6be5..8ffe885532fd84f833320445a4b00331c0e62452 100644 (file)
@@ -213,6 +213,8 @@ struct _MonoJitInfo {
        gboolean    dbg_hidden:1;
        /* Whenever this jit info was loaded in async context */
        gboolean    async:1;
+       gboolean    dbg_step_through_inited:1;
+       gboolean    dbg_step_through:1;
 
        /* FIXME: Embed this after the structure later*/
        gpointer    gc_info; /* Currently only used by SGen */
diff --git a/mono/metadata/gc-memfuncs.c b/mono/metadata/gc-memfuncs.c
new file mode 100644 (file)
index 0000000..532635d
--- /dev/null
@@ -0,0 +1,214 @@
+/*
+ * test-sgen-qsort.c: Our own bzero/memmove.
+ *
+ * Copyright (C) 2013 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * SGen cannot deal with invalid pointers on the heap or in registered roots.  Sometimes we
+ * need to copy or zero out memory in code that might be interrupted by collections.  To
+ * guarantee that those operations will not result in invalid pointers, we must do it
+ * word-atomically.
+ *
+ * libc's bzero() and memcpy()/memmove() functions do not guarantee word-atomicity, even in
+ * cases where one would assume so.  For instance, some implementations (like Darwin's on
+ * x86) have variants of memcpy() using vector instructions.  Those may copy bytewise for
+ * the region preceding the first vector-aligned address.  That region could be
+ * word-aligned, but it would still be copied byte-wise.
+ *
+ * All our memory writes here are to "volatile" locations.  This is so that C compilers
+ * don't "optimize" our code back to calls to bzero()/memmove().  LLVM, specifically, will
+ * do that.
+ */
+
+#include <config.h>
+
+#include "metadata/gc-internal.h"
+
+#define ptr_mask ((sizeof (void*) - 1))
+#define _toi(ptr) ((size_t)ptr)
+#define unaligned_bytes(ptr) (_toi(ptr) & ptr_mask)
+#define align_down(ptr) ((void*)(_toi(ptr) & ~ptr_mask))
+#define align_up(ptr) ((void*) ((_toi(ptr) + ptr_mask) & ~ptr_mask))
+#if SIZEOF_VOID_P == 4
+#define bytes_to_words(n)      ((size_t)(n) >> 2)
+#elif SIZEOF_VOID_P == 8
+#define bytes_to_words(n)      ((size_t)(n) >> 3)
+#else
+#error We only support 32 and 64 bit architectures.
+#endif
+
+#define BZERO_WORDS(dest,words) do {                   \
+               void * volatile *__d = (void* volatile*)(dest);         \
+               int __n = (words);                      \
+               int __i;                                \
+               for (__i = 0; __i < __n; ++__i)         \
+                       __d [__i] = NULL;               \
+       } while (0)
+
+/**
+ * mono_gc_bzero:
+ * @dest: address to start to clear
+ * @size: size of the region to clear
+ *
+ * Zero @size bytes starting at @dest.
+ *
+ * Use this to zero memory that can hold managed pointers.
+ *
+ * FIXME borrow faster code from some BSD libc or bionic
+ */
+void
+mono_gc_bzero (void *dest, size_t size)
+{
+       volatile char *d = (char*)dest;
+       size_t tail_bytes, word_bytes;
+
+       /*
+       If we're copying less than a word, just use memset.
+
+       We cannot bail out early if both are aligned because some implementations
+       use byte copying for sizes smaller than 16. OSX, on this case.
+       */
+       if (size < sizeof(void*)) {
+               memset (dest, 0, size);
+               return;
+       }
+
+       /*align to word boundary */
+       while (unaligned_bytes (d) && size) {
+               *d++ = 0;
+               --size;
+       }
+
+       /* copy all words with memmove */
+       word_bytes = (size_t)align_down (size);
+       switch (word_bytes) {
+       case sizeof (void*) * 1:
+               BZERO_WORDS (d, 1);
+               break;
+       case sizeof (void*) * 2:
+               BZERO_WORDS (d, 2);
+               break;
+       case sizeof (void*) * 3:
+               BZERO_WORDS (d, 3);
+               break;
+       case sizeof (void*) * 4:
+               BZERO_WORDS (d, 4);
+               break;
+       default:
+               BZERO_WORDS (d, bytes_to_words (word_bytes));
+       }
+
+       tail_bytes = unaligned_bytes (size);
+       if (tail_bytes) {
+               d += word_bytes;
+               do {
+                       *d++ = 0;
+               } while (--tail_bytes);
+       }
+}
+
+#define MEMMOVE_WORDS_UPWARD(dest,src,words) do {      \
+               void * volatile *__d = (void* volatile*)(dest);         \
+               void **__s = (void**)(src);             \
+               int __n = (int)(words);                 \
+               int __i;                                \
+               for (__i = 0; __i < __n; ++__i)         \
+                       __d [__i] = __s [__i];          \
+       } while (0)
+
+#define MEMMOVE_WORDS_DOWNWARD(dest,src,words) do {    \
+               void * volatile *__d = (void* volatile*)(dest);         \
+               void **__s = (void**)(src);             \
+               int __n = (int)(words);                 \
+               int __i;                                \
+               for (__i = __n - 1; __i >= 0; --__i)    \
+                       __d [__i] = __s [__i];          \
+       } while (0)
+
+/**
+ * mono_gc_memmove:
+ * @dest: destination of the move
+ * @src: source
+ * @size: size of the block to move
+ *
+ * Move @size bytes from @src to @dest.
+ * size MUST be a multiple of sizeof (gpointer)
+ *
+ */
+void
+mono_gc_memmove (void *dest, const void *src, size_t size)
+{
+       /*
+       If we're copying less than a word we don't need to worry about word tearing
+       so we bailout to memmove early.
+       */
+       if (size < sizeof(void*)) {
+               memmove (dest, src, size);
+               return;
+       }
+
+       /*
+        * A bit of explanation on why we align only dest before doing word copies.
+        * Pointers to managed objects must always be stored in word aligned addresses, so
+        * even if dest is misaligned, src will be by the same amount - this ensure proper atomicity of reads.
+        *
+        * We don't need to case when source and destination have different alignments since we only do word stores
+        * using memmove, which must handle it.
+        */
+       if (dest > src && ((size_t)((char*)dest - (char*)src) < size)) { /*backward copy*/
+               volatile char *p = (char*)dest + size;
+                       char *s = (char*)src + size;
+                       char *start = (char*)dest;
+                       char *align_end = MAX((char*)dest, (char*)align_down (p));
+                       char *word_start;
+                       size_t bytes_to_memmove;
+
+                       while (p > align_end)
+                               *--p = *--s;
+
+                       word_start = align_up (start);
+                       bytes_to_memmove = p - word_start;
+                       p -= bytes_to_memmove;
+                       s -= bytes_to_memmove;
+                       MEMMOVE_WORDS_DOWNWARD (p, s, bytes_to_words (bytes_to_memmove));
+
+                       while (p > start)
+                               *--p = *--s;
+       } else {
+               volatile char *d = (char*)dest;
+               const char *s = (const char*)src;
+               size_t tail_bytes;
+
+               /*align to word boundary */
+               while (unaligned_bytes (d)) {
+                       *d++ = *s++;
+                       --size;
+               }
+
+               /* copy all words with memmove */
+               MEMMOVE_WORDS_UPWARD (d, s, bytes_to_words (align_down (size)));
+
+               tail_bytes = unaligned_bytes (size);
+               if (tail_bytes) {
+                       d += (size_t)align_down (size);
+                       s += (size_t)align_down (size);
+                       do {
+                               *d++ = *s++;
+                       } while (--tail_bytes);
+               }
+       }
+}
index 465f6d1974d6d693f7171d3d79d2327f3001708d..52f8b0366fba6bfcbe916065cac3b39bdd1c588b 100644 (file)
@@ -1551,157 +1551,3 @@ mono_gc_reference_queue_free (MonoReferenceQueue *queue)
 {
        queue->should_be_deleted = TRUE;
 }
-
-#define ptr_mask ((sizeof (void*) - 1))
-#define _toi(ptr) ((size_t)ptr)
-#define unaligned_bytes(ptr) (_toi(ptr) & ptr_mask)
-#define align_down(ptr) ((void*)(_toi(ptr) & ~ptr_mask))
-#define align_up(ptr) ((void*) ((_toi(ptr) + ptr_mask) & ~ptr_mask))
-
-#define BZERO_WORDS(dest,words) do {   \
-       int __i;        \
-       for (__i = 0; __i < (words); ++__i)     \
-               ((void **)(dest))[__i] = 0;     \
-} while (0)
-
-/**
- * mono_gc_bzero:
- * @dest: address to start to clear
- * @size: size of the region to clear
- *
- * Zero @size bytes starting at @dest.
- *
- * Use this to zero memory that can hold managed pointers.
- *
- * FIXME borrow faster code from some BSD libc or bionic
- */
-void
-mono_gc_bzero (void *dest, size_t size)
-{
-       char *d = (char*)dest;
-       size_t tail_bytes, word_bytes;
-
-       /*
-       If we're copying less than a word, just use memset.
-
-       We cannot bail out early if both are aligned because some implementations
-       use byte copying for sizes smaller than 16. OSX, on this case.
-       */
-       if (size < sizeof(void*)) {
-               memset (dest, 0, size);
-               return;
-       }
-
-       /*align to word boundary */
-       while (unaligned_bytes (d) && size) {
-               *d++ = 0;
-               --size;
-       }
-
-       /* copy all words with memmove */
-       word_bytes = (size_t)align_down (size);
-       switch (word_bytes) {
-       case sizeof (void*) * 1:
-               BZERO_WORDS (d, 1);
-               break;
-       case sizeof (void*) * 2:
-               BZERO_WORDS (d, 2);
-               break;
-       case sizeof (void*) * 3:
-               BZERO_WORDS (d, 3);
-               break;
-       case sizeof (void*) * 4:
-               BZERO_WORDS (d, 4);
-               break;
-       default:
-               memset (d, 0, word_bytes);
-       }
-
-       tail_bytes = unaligned_bytes (size);
-       if (tail_bytes) {
-               d += word_bytes;
-               do {
-                       *d++ = 0;
-               } while (--tail_bytes);
-       }
-}
-
-/**
- * mono_gc_memmove:
- * @dest: destination of the move
- * @src: source
- * @size: size of the block to move
- *
- * Move @size bytes from @src to @dest.
- * size MUST be a multiple of sizeof (gpointer)
- *
- */
-void
-mono_gc_memmove (void *dest, const void *src, size_t size)
-{
-       /*
-       If we're copying less than a word we don't need to worry about word tearing
-       so we bailout to memmove early.
-
-       If both dest is aligned and size is a multiple of word size, we can go straigh
-       to memmove.
-
-       */
-       if (size < sizeof(void*) || !((_toi (dest) | (size)) & sizeof (void*))) {
-               memmove (dest, src, size);
-               return;
-       }
-
-       /*
-        * A bit of explanation on why we align only dest before doing word copies.
-        * Pointers to managed objects must always be stored in word aligned addresses, so
-        * even if dest is misaligned, src will be by the same amount - this ensure proper atomicity of reads.
-        *
-        * We don't need to case when source and destination have different alignments since we only do word stores
-        * using memmove, which must handle it.
-        */
-       if (dest > src && ((size_t)((char*)dest - (char*)src) < size)) { /*backward copy*/
-               char *p = (char*)dest + size;
-                       char *s = (char*)src + size;
-                       char *start = (char*)dest;
-                       char *align_end = MAX((char*)dest, (char*)align_down (p));
-                       char *word_start;
-                       size_t bytes_to_memmove;
-
-                       while (p > align_end)
-                               *--p = *--s;
-
-                       word_start = align_up (start);
-                       bytes_to_memmove = p - word_start;
-                       p -= bytes_to_memmove;
-                       s -= bytes_to_memmove;
-                       memmove (p, s, bytes_to_memmove);
-
-                       while (p > start)
-                               *--p = *--s;
-       } else {
-               char *d = (char*)dest;
-               const char *s = (const char*)src;
-               size_t tail_bytes;
-
-               /*align to word boundary */
-               while (unaligned_bytes (d)) {
-                       *d++ = *s++;
-                       --size;
-               }
-
-               /* copy all words with memmove */
-               memmove (d, s, (size_t)align_down (size));
-
-               tail_bytes = unaligned_bytes (size);
-               if (tail_bytes) {
-                       d += (size_t)align_down (size);
-                       s += (size_t)align_down (size);
-                       do {
-                               *d++ = *s++;
-                       } while (--tail_bytes);
-               }
-       }
-}
-
-
index ac2e0278ab59297036cc421c3929461481e73df3..63fb708d200d33abf586b6941996cd1345d5b27d 100644 (file)
@@ -286,11 +286,10 @@ ICALL(COMPINF_6, "internal_index(string,int,int,string,System.Globalization.Comp
 
 ICALL_TYPE(CULINF, "System.Globalization.CultureInfo", CULINF_2)
 ICALL(CULINF_2, "construct_datetime_format", ves_icall_System_Globalization_CultureInfo_construct_datetime_format)
-ICALL(CULINF_4, "construct_internal_locale_from_current_locale", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_current_locale)
 ICALL(CULINF_5, "construct_internal_locale_from_lcid", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid)
 ICALL(CULINF_6, "construct_internal_locale_from_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name)
-ICALL(CULINF_7, "construct_internal_locale_from_specific_name", ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specific_name)
 ICALL(CULINF_8, "construct_number_format", ves_icall_System_Globalization_CultureInfo_construct_number_format)
+ICALL(CULINF_7, "get_current_locale_name", ves_icall_System_Globalization_CultureInfo_get_current_locale_name)
 ICALL(CULINF_9, "internal_get_cultures", ves_icall_System_Globalization_CultureInfo_internal_get_cultures)
 //ICALL(CULINF_10, "internal_is_lcid_neutral", ves_icall_System_Globalization_CultureInfo_internal_is_lcid_neutral)
 
index 618e4da40afbdf4d87aecbe8fc2d1bbccfb7759e..9ae6be8cdf46ef6f2e8cb5092ad6c7c35c5cb8f4 100644 (file)
@@ -85,6 +85,7 @@
 #include <mono/utils/mono-io-portability.h>
 #include <mono/utils/mono-digest.h>
 #include <mono/utils/bsearch.h>
+#include <mono/utils/mono-mutex.h>
 
 #if defined (HOST_WIN32)
 #include <windows.h>
@@ -1510,10 +1511,8 @@ ves_icall_type_is_subtype_of (MonoReflectionType *type, MonoReflectionType *c, M
                mono_class_init_or_throw (klass);
                mono_class_init_or_throw (klassc);
        } else if (!klass->supertypes || !klassc->supertypes) {
-               mono_loader_lock ();
                mono_class_setup_supertypes (klass);
                mono_class_setup_supertypes (klassc);
-               mono_loader_unlock ();
        }
 
        if (type->type->byref)
@@ -2669,9 +2668,9 @@ ves_icall_MonoMethod_GetGenericMethodDefinition (MonoReflectionMethod *method)
                 * FIXME: Why is this stuff needed at all ? Why can't the code below work for
                 * the dynamic case as well ?
                 */
-               mono_loader_lock ();
+               mono_image_lock ((MonoImage*)image);
                res = mono_g_hash_table_lookup (image->generic_def_objects, imethod);
-               mono_loader_unlock ();
+               mono_image_unlock ((MonoImage*)image);
 
                if (res)
                        return res;
@@ -5930,10 +5929,12 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
        struct tm start, tt;
        time_t t;
 
-       long int gmtoff;
-       int is_daylight = 0, day;
+       long int gmtoff, gmtoff_after, gmtoff_st, gmtoff_ds;
+       int day, transitioned;
        char tzone [64];
 
+       gmtoff_st = gmtoff_ds = transitioned = 0;
+
        MONO_ARCH_SAVE_REGS;
 
        MONO_CHECK_ARG_NULL (data);
@@ -5969,13 +5970,15 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
        gmtoff = gmt_offset (&start, t);
 
        /* For each day of the year, calculate the tm_gmtoff. */
-       for (day = 0; day < 365; day++) {
+       for (day = 0; day < 365 && transitioned < 2; day++) {
 
                t += 3600*24;
                tt = *localtime (&t);
 
+        gmtoff_after = gmt_offset(&tt, t);
+
                /* Daylight saving starts or ends here. */
-               if (gmt_offset (&tt, t) != gmtoff) {
+               if (gmtoff_after != gmtoff) {
                        struct tm tt1;
                        time_t t1;
 
@@ -5995,36 +5998,37 @@ ves_icall_System_CurrentSystemTimeZone_GetTimeZoneData (guint32 year, MonoArray
                        strftime (tzone, sizeof (tzone), "%Z", &tt);
                        
                        /* Write data, if we're already in daylight saving, we're done. */
-                       if (is_daylight) {
-                               mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
-                               mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
-                               return 1;
+                       if (tt.tm_isdst) {
+                               mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
+                               mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
+                               if (gmtoff_ds == 0) {
+                                       gmtoff_st = gmtoff;
+                                       gmtoff_ds = gmtoff_after;
+                               }
+                               transitioned++;
                        } else {
-                               struct tm end;
                                time_t te;
+                               te = mktime (&tt);
                                
-                               memset (&end, 0, sizeof (end));
-                               end.tm_year = year-1900 + 1;
-                               end.tm_mday = 1;
-                               
-                               te = mktime (&end);
-                               
-                               mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
-                               mono_array_set ((*data), gint64, 0, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
                                mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
-                               mono_array_set ((*data), gint64, 1, ((gint64)te + EPOCH_ADJUST) * 10000000L);
-                               is_daylight = 1;
+                               mono_array_set ((*data), gint64, 1, ((gint64)t1 + EPOCH_ADJUST) * 10000000L);
+                               if (gmtoff_ds == 0) {
+                                       gmtoff_st = gmtoff_after;
+                                       gmtoff_ds = gmtoff;
+                               }
+                               transitioned++;
                        }
 
                        /* This is only set once when we enter daylight saving. */
-                       mono_array_set ((*data), gint64, 2, (gint64)gmtoff * 10000000L);
-                       mono_array_set ((*data), gint64, 3, (gint64)(gmt_offset (&tt, t) - gmtoff) * 10000000L);
-
+                       if (tt1.tm_isdst) {
+                               mono_array_set ((*data), gint64, 2, (gint64)gmtoff_st * 10000000L);
+                               mono_array_set ((*data), gint64, 3, (gint64)(gmtoff_ds - gmtoff_st) * 10000000L);
+                       }
                        gmtoff = gmt_offset (&tt, t);
                }
        }
 
-       if (!is_daylight) {
+       if (transitioned < 2) {
                strftime (tzone, sizeof (tzone), "%Z", &tt);
                mono_array_setref ((*names), 0, mono_string_new (domain, tzone));
                mono_array_setref ((*names), 1, mono_string_new (domain, tzone));
@@ -6495,6 +6499,8 @@ ves_icall_System_Environment_Exit (int result)
 {
        MONO_ARCH_SAVE_REGS;
 
+       mono_environment_exitcode_set (result);
+
 /* FIXME: There are some cleanup hangs that should be worked out, but
  * if the program is going to exit, everything will be cleaned up when
  * NaCl exits anyway.
@@ -7026,7 +7032,7 @@ ves_icall_get_resources_ptr (MonoReflectionAssembly *assembly, gpointer *result,
 ICALL_EXPORT MonoBoolean
 ves_icall_System_Diagnostics_Debugger_IsAttached_internal (void)
 {
-       return mono_debug_using_mono_debugger () || mono_is_debugger_attached ();
+       return mono_is_debugger_attached ();
 }
 
 ICALL_EXPORT MonoBoolean
@@ -7852,6 +7858,7 @@ icall_symbols [] = {
 
 #endif /* DISABLE_ICALL_TABLES */
 
+static mono_mutex_t icall_mutex;
 static GHashTable *icall_hash = NULL;
 static GHashTable *jit_icall_hash_name = NULL;
 static GHashTable *jit_icall_hash_addr = NULL;
@@ -7889,6 +7896,19 @@ mono_icall_init (void)
 #endif
 
        icall_hash = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
+       mono_mutex_init (&icall_mutex);
+}
+
+static void
+mono_icall_lock (void)
+{
+       mono_locks_mutex_acquire (&icall_mutex, IcallLock);
+}
+
+static void
+mono_icall_unlock (void)
+{
+       mono_locks_mutex_release (&icall_mutex, IcallLock);
 }
 
 void
@@ -7897,16 +7917,17 @@ mono_icall_cleanup (void)
        g_hash_table_destroy (icall_hash);
        g_hash_table_destroy (jit_icall_hash_name);
        g_hash_table_destroy (jit_icall_hash_addr);
+       mono_mutex_destroy (&icall_mutex);
 }
 
 void
 mono_add_internal_call (const char *name, gconstpointer method)
 {
-       mono_loader_lock ();
+       mono_icall_lock ();
 
        g_hash_table_insert (icall_hash, g_strdup (name), (gpointer) method);
 
-       mono_loader_unlock ();
+       mono_icall_unlock ();
 }
 
 #ifndef DISABLE_ICALL_TABLES
@@ -8069,23 +8090,23 @@ mono_lookup_internal_call (MonoMethod *method)
        sigstart [siglen + 2] = 0;
        g_free (tmpsig);
        
-       mono_loader_lock ();
+       mono_icall_lock ();
 
        res = g_hash_table_lookup (icall_hash, mname);
        if (res) {
-               mono_loader_unlock ();
+               mono_icall_unlock ();;
                return res;
        }
        /* try without signature */
        *sigstart = 0;
        res = g_hash_table_lookup (icall_hash, mname);
        if (res) {
-               mono_loader_unlock ();
+               mono_icall_unlock ();
                return res;
        }
 
 #ifdef DISABLE_ICALL_TABLES
-       mono_loader_unlock ();
+       mono_icall_unlock ();
        /* Fail only when the result is actually used */
        /* mono_marshal_get_native_wrapper () depends on this */
        if (method->klass == mono_defaults.string_class && !strcmp (method->name, ".ctor"))
@@ -8095,19 +8116,19 @@ mono_lookup_internal_call (MonoMethod *method)
 #else
        /* it wasn't found in the static call tables */
        if (!imap) {
-               mono_loader_unlock ();
+               mono_icall_unlock ();
                return NULL;
        }
        res = find_method_icall (imap, sigstart - mlen);
        if (res) {
-               mono_loader_unlock ();
+               mono_icall_unlock ();
                return res;
        }
        /* try _with_ signature */
        *sigstart = '(';
        res = find_method_icall (imap, sigstart - mlen);
        if (res) {
-               mono_loader_unlock ();
+               mono_icall_unlock ();
                return res;
        }
 
@@ -8119,7 +8140,7 @@ mono_lookup_internal_call (MonoMethod *method)
        g_print ("If you see other errors or faults after this message they are probably related\n");
        g_print ("and you need to fix your mono install first.\n");
 
-       mono_loader_unlock ();
+       mono_icall_unlock ();
 
        return NULL;
 #endif
@@ -8244,20 +8265,24 @@ type_from_typename (char *typename)
        return &klass->byval_arg;
 }
 
+/**
+ * LOCKING: Take the corlib image lock.
+ */
 MonoMethodSignature*
 mono_create_icall_signature (const char *sigstr)
 {
        gchar **parts;
        int i, len;
        gchar **tmp;
-       MonoMethodSignature *res;
+       MonoMethodSignature *res, *res2;
+       MonoImage *corlib = mono_defaults.corlib;
 
-       mono_loader_lock ();
-       res = g_hash_table_lookup (mono_defaults.corlib->helper_signatures, sigstr);
-       if (res) {
-               mono_loader_unlock ();
+       mono_image_lock (corlib);
+       res = g_hash_table_lookup (corlib->helper_signatures, sigstr);
+       mono_image_unlock (corlib);
+
+       if (res)
                return res;
-       }
 
        parts = g_strsplit (sigstr, " ", 256);
 
@@ -8268,7 +8293,7 @@ mono_create_icall_signature (const char *sigstr)
                tmp ++;
        }
 
-       res = mono_metadata_signature_alloc (mono_defaults.corlib, len - 1);
+       res = mono_metadata_signature_alloc (corlib, len - 1);
        res->pinvoke = 1;
 
 #ifdef HOST_WIN32
@@ -8286,9 +8311,13 @@ mono_create_icall_signature (const char *sigstr)
 
        g_strfreev (parts);
 
-       g_hash_table_insert (mono_defaults.corlib->helper_signatures, (gpointer)sigstr, res);
-
-       mono_loader_unlock ();
+       mono_image_lock (corlib);
+       res2 = g_hash_table_lookup (corlib->helper_signatures, sigstr);
+       if (res2)
+               res = res2; /*Value is allocated in the image pool*/
+       else
+               g_hash_table_insert (corlib->helper_signatures, (gpointer)sigstr, res);
+       mono_image_unlock (corlib);
 
        return res;
 }
@@ -8299,9 +8328,9 @@ mono_find_jit_icall_by_name (const char *name)
        MonoJitICallInfo *info;
        g_assert (jit_icall_hash_name);
 
-       mono_loader_lock ();
+       mono_icall_lock ();
        info = g_hash_table_lookup (jit_icall_hash_name, name);
-       mono_loader_unlock ();
+       mono_icall_unlock ();
        return info;
 }
 
@@ -8311,9 +8340,9 @@ mono_find_jit_icall_by_addr (gconstpointer addr)
        MonoJitICallInfo *info;
        g_assert (jit_icall_hash_addr);
 
-       mono_loader_lock ();
+       mono_icall_lock ();
        info = g_hash_table_lookup (jit_icall_hash_addr, (gpointer)addr);
-       mono_loader_unlock ();
+       mono_icall_unlock ();
 
        return info;
 }
@@ -8322,7 +8351,7 @@ mono_find_jit_icall_by_addr (gconstpointer addr)
  * mono_get_jit_icall_info:
  *
  *   Return the hashtable mapping JIT icall names to MonoJitICallInfo structures. The
- * caller should access it while holding the loader lock.
+ * caller should access it while holding the icall lock.
  */
 GHashTable*
 mono_get_jit_icall_info (void)
@@ -8341,20 +8370,20 @@ mono_lookup_jit_icall_symbol (const char *name)
        MonoJitICallInfo *info;
        const char *res = NULL;
 
-       mono_loader_lock ();
+       mono_icall_lock ();
        info = g_hash_table_lookup (jit_icall_hash_name, name);
        if (info)
                res = info->c_symbol;
-       mono_loader_unlock ();
+       mono_icall_unlock ();
        return res;
 }
 
 void
 mono_register_jit_icall_wrapper (MonoJitICallInfo *info, gconstpointer wrapper)
 {
-       mono_loader_lock ();
+       mono_icall_lock ();
        g_hash_table_insert (jit_icall_hash_addr, (gpointer)wrapper, info);
-       mono_loader_unlock ();
+       mono_icall_unlock ();
 }
 
 MonoJitICallInfo *
@@ -8365,7 +8394,7 @@ mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSi
        g_assert (func);
        g_assert (name);
 
-       mono_loader_lock ();
+       mono_icall_lock ();
 
        if (!jit_icall_hash_name) {
                jit_icall_hash_name = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, g_free);
@@ -8393,7 +8422,7 @@ mono_register_jit_icall_full (gconstpointer func, const char *name, MonoMethodSi
        g_hash_table_insert (jit_icall_hash_name, (gpointer)info->name, info);
        g_hash_table_insert (jit_icall_hash_addr, (gpointer)func, info);
 
-       mono_loader_unlock ();
+       mono_icall_unlock ();
        return info;
 }
 
index 7140a630bad2630e1e332dd5dd3b7c2e1ef089e6..1673eededde9e24b0f5b98a259f625980bc98ab1 100644 (file)
@@ -1488,7 +1488,6 @@ mono_image_close_except_pools (MonoImage *image)
        MonoImage *image2;
        GHashTable *loaded_images;
        int i;
-       GSList *free_list;
 
        g_return_val_if_fail (image != NULL, FALSE);
 
@@ -1533,7 +1532,7 @@ mono_image_close_except_pools (MonoImage *image)
 
        mono_image_invoke_unload_hook (image);
 
-       free_list = mono_metadata_clean_for_image (image);
+       mono_metadata_clean_for_image (image);
 
        /*
         * The caches inside a MonoImage might refer to metadata which is stored in referenced 
@@ -1653,9 +1652,7 @@ mono_image_close_except_pools (MonoImage *image)
        free_hash (image->pinvoke_scope_filenames);
 
        /* The ownership of signatures is not well defined */
-       //g_hash_table_foreach (image->memberref_signatures, free_mr_signatures, NULL);
        g_hash_table_destroy (image->memberref_signatures);
-       //g_hash_table_foreach (image->helper_signatures, free_mr_signatures, NULL);
        g_hash_table_destroy (image->helper_signatures);
        g_hash_table_destroy (image->method_signatures);
 
@@ -1665,8 +1662,12 @@ mono_image_close_except_pools (MonoImage *image)
        if (image->property_hash)
                mono_property_hash_destroy (image->property_hash);
 
-       g_slist_free (image->reflection_info_unregister_classes);
-       image->reflection_info_unregister_classes = free_list;
+       /*
+       reflection_info_unregister_classes is only required by dynamic images, which will not be properly
+       cleared during shutdown as we don't perform regular appdomain unload for the root one.
+       */
+       g_assert (!image->reflection_info_unregister_classes || mono_runtime_is_shutting_down ());
+       image->reflection_info_unregister_classes = NULL;
 
        if (image->interface_bitset) {
                mono_unload_interface_ids (image->interface_bitset);
@@ -1710,12 +1711,6 @@ void
 mono_image_close_finish (MonoImage *image)
 {
        int i;
-       GSList *l;
-
-       for (l = image->reflection_info_unregister_classes; l; l = l->next)
-               g_free (l->data);
-       g_slist_free (image->reflection_info_unregister_classes);
-       image->reflection_info_unregister_classes = NULL;
 
        if (image->references && !image->dynamic) {
                for (i = 0; i < image->nreferences; i++) {
@@ -2363,3 +2358,13 @@ mono_image_property_remove (MonoImage *image, gpointer subject)
        mono_property_hash_remove_object (image->property_hash, subject);
        mono_image_unlock (image);
 }
+
+void
+mono_image_append_class_to_reflection_info_set (MonoClass *class)
+{
+       MonoImage *image = class->image;
+       g_assert (image->dynamic);
+       mono_image_lock (image);
+       image->reflection_info_unregister_classes = g_slist_prepend_mempool (image->mempool, image->reflection_info_unregister_classes, class);
+       mono_image_unlock (image);
+}
index 6983eb71e5bf45fa54e04112adb949c44cfc228e..18941dc4a2a4acb1e1c657cdb21913b6e84534c3 100644 (file)
@@ -129,6 +129,7 @@ mono_loader_cleanup (void)
 static void
 set_loader_error (MonoLoaderError *error)
 {
+       mono_loader_clear_error ();
        mono_native_tls_set_value (loader_error_thread_id, error);
 }
 
@@ -1811,7 +1812,7 @@ MonoMethod *
 mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
                      MonoGenericContext *context)
 {
-       MonoMethod *result;
+       MonoMethod *result = NULL;
        gboolean used_context = FALSE;
 
        /* We do everything inside the lock to prevent creation races */
@@ -1822,7 +1823,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
                if (!image->method_cache)
                        image->method_cache = g_hash_table_new (NULL, NULL);
                result = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)));
-       } else {
+       } else if (!image->dynamic) {
                if (!image->methodref_cache)
                        image->methodref_cache = g_hash_table_new (NULL, NULL);
                result = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token));
@@ -1832,16 +1833,18 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
        if (result)
                return result;
 
+
        result = mono_get_method_from_token (image, token, klass, context, &used_context);
        if (!result)
                return NULL;
 
        mono_image_lock (image);
        if (!used_context && !result->is_inflated) {
-               MonoMethod *result2;
+               MonoMethod *result2 = NULL;
+
                if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
                        result2 = g_hash_table_lookup (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)));
-               else
+               else if (!image->dynamic)
                        result2 = g_hash_table_lookup (image->methodref_cache, GINT_TO_POINTER (token));
 
                if (result2) {
@@ -1851,7 +1854,7 @@ mono_get_method_full (MonoImage *image, guint32 token, MonoClass *klass,
 
                if (mono_metadata_token_table (token) == MONO_TABLE_METHOD)
                        g_hash_table_insert (image->method_cache, GINT_TO_POINTER (mono_metadata_token_index (token)), result);
-               else
+               else if (!image->dynamic)
                        g_hash_table_insert (image->methodref_cache, GINT_TO_POINTER (token), result);
        }
 
index 1474a105737e7086789fbef0d35708ce50c0c086..7fffad9cc8c5bf8206e0b34cefc24362c19d081a 100644 (file)
@@ -306,28 +306,6 @@ construct_region (MonoRegionInfo *this, const RegionInfoEntry *ri)
        return TRUE;
 }
 
-static gboolean
-construct_culture_from_specific_name (MonoCultureInfo *ci, gchar *name)
-{
-       const CultureInfoEntry *entry;
-       const CultureInfoNameEntry *ne;
-
-       MONO_ARCH_SAVE_REGS;
-
-       ne = mono_binary_search (name, culture_name_entries, NUM_CULTURE_ENTRIES,
-                       sizeof (CultureInfoNameEntry), culture_name_locator);
-
-       if (ne == NULL)
-               return FALSE;
-
-       entry = &culture_entries [ne->culture_entry_index];
-
-       if (entry)
-               return construct_culture (ci, entry);
-       else
-               return FALSE;
-}
-
 static const CultureInfoEntry*
 culture_info_entry_from_lcid (int lcid)
 {
@@ -478,6 +456,9 @@ get_current_locale_name (void)
        p = strchr (locale, '@');
        if (p != NULL)
                *p = 0;
+       p = strchr (locale, '_');
+       if (p != NULL)
+               *p = '-';
 
        ret = g_ascii_strdown (locale, -1);
        g_free (locale);
@@ -485,22 +466,22 @@ get_current_locale_name (void)
        return ret;
 }
 
-MonoBoolean
-ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_current_locale (MonoCultureInfo *ci)
+MonoString*
+ves_icall_System_Globalization_CultureInfo_get_current_locale_name (void)
 {
        gchar *locale;
-       gboolean ret;
+       MonoString* ret;
+       MonoDomain *domain;
 
        MONO_ARCH_SAVE_REGS;
 
        locale = get_current_locale_name ();
        if (locale == NULL)
-               return FALSE;
+               return NULL;
 
-       ret = construct_culture_from_specific_name (ci, locale);
+       domain = mono_domain_get ();
+       ret = mono_string_new (domain, locale);
        g_free (locale);
-       ci->is_read_only = TRUE;
-       ci->use_user_override = TRUE;
 
        return ret;
 }
@@ -542,7 +523,7 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name (
 
        return construct_culture (this, &culture_entries [ne->culture_entry_index]);
 }
-
+/*
 MonoBoolean
 ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specific_name (MonoCultureInfo *ci,
                MonoString *name)
@@ -558,7 +539,7 @@ ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specif
 
        return ret;
 }
-
+*/
 MonoBoolean
 ves_icall_System_Globalization_RegionInfo_construct_internal_region_from_lcid (MonoRegionInfo *this,
                gint lcid)
index c0ec1067922ac326c50ac2873d59e667e774566d..7ebdde0133c12f92a5cb6aac442d5cbccfcd22a5 100644 (file)
@@ -27,10 +27,9 @@ typedef enum {
 } MonoCompareOptions;
 
 extern void ves_icall_System_Globalization_CultureInfo_construct_internal_locale (MonoCultureInfo *this, MonoString *locale) MONO_INTERNAL;
-extern MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_current_locale (MonoCultureInfo *ci) MONO_INTERNAL;
+extern MonoString* ves_icall_System_Globalization_CultureInfo_get_current_locale_name (void) MONO_INTERNAL;
 extern MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_lcid (MonoCultureInfo *this, gint lcid) MONO_INTERNAL;
 extern MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_name (MonoCultureInfo *this, MonoString *name) MONO_INTERNAL;
-extern MonoBoolean ves_icall_System_Globalization_CultureInfo_construct_internal_locale_from_specific_name (MonoCultureInfo *ci, MonoString *name) MONO_INTERNAL;
 extern MonoArray *ves_icall_System_Globalization_CultureInfo_internal_get_cultures (MonoBoolean neutral, MonoBoolean specific, MonoBoolean installed) MONO_INTERNAL;
 extern void ves_icall_System_Globalization_CultureInfo_construct_datetime_format (MonoCultureInfo *this) MONO_INTERNAL;
 extern void ves_icall_System_Globalization_CultureInfo_construct_number_format (MonoCultureInfo *this) MONO_INTERNAL;
index d75e9c302cb4f5cb1e8d75f68d2da2d1196858d6..0f04817ced9d077f54b828f963f7947fd2da0a96 100644 (file)
@@ -24,6 +24,7 @@
 
 #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.
 
 #ifdef LOCK_TRACER
 
+#ifdef TARGET_OSX
+#include <dlfcn.h>
+#endif
+
 static FILE *trace_file;
 static CRITICAL_SECTION tracer_lock;
+static size_t base_address;
 
 typedef enum {
        RECORD_MUST_NOT_HOLD_ANY,
@@ -62,6 +68,8 @@ typedef enum {
 void
 mono_locks_tracer_init (void)
 {
+       Dl_info info;
+       int res;
        char *name;
        InitializeCriticalSection (&tracer_lock);
        if (!g_getenv ("MONO_ENABLE_LOCK_TRACER"))
@@ -69,6 +77,13 @@ mono_locks_tracer_init (void)
        name = g_strdup_printf ("locks.%d", getpid ());
        trace_file = fopen (name, "w+");
        g_free (name);
+
+#ifdef TARGET_OSX
+       res = dladdr ((void*)&mono_locks_tracer_init, &info);
+       /* The 0x1000 offset was found by empirically trying it. */
+       if (res)
+               base_address = (size_t)info.dli_fbase - 0x1000;
+#endif
 }
 
 
@@ -93,6 +108,7 @@ mono_backtrace (gpointer array[], int traces)
 static void
 add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock)
 {
+       int i = 0;
        gpointer frames[10];
        char *msg;
        if (!trace_file)
@@ -100,6 +116,8 @@ add_record (RecordType record_kind, RuntimeLocks kind, gpointer lock)
 
        memset (frames, 0, sizeof (gpointer));
        mono_backtrace (frames, 6);
+       for (i = 0; i < 6; ++i)
+               frames [i] = (gpointer)((size_t)frames[i] - base_address);
 
        /*We only dump 5 frames, which should be more than enough to most analysis.*/
        msg = g_strdup_printf ("%x,%d,%d,%p,%p,%p,%p,%p,%p\n", (guint32)GetCurrentThreadId (), record_kind, kind, lock, frames [1], frames [2], frames [3], frames [4], frames [5]);
index 40beac748e8c30c76f4182a53dd7c5c2e826847e..215b683ba4beb910514d98422f2c3fc8b039e78e 100644 (file)
@@ -15,6 +15,9 @@ typedef enum {
        DomainLock,
        DomainAssembliesLock,
        DomainJitCodeHashLock,
+       IcallLock,
+       AssemblyBindingLock,
+       MarshalLock
 } RuntimeLocks;
 
 #ifdef LOCK_TRACER
@@ -43,6 +46,15 @@ void mono_locks_lock_released (RuntimeLocks kind, gpointer lock) MONO_INTERNAL;
        LeaveCriticalSection (LOCK); \
 } while (0)
 
+#define mono_locks_mutex_acquire(LOCK, NAME) do { \
+       mono_mutex_lock (LOCK); \
+       mono_locks_lock_acquired (NAME, LOCK); \
+} while (0)
+
+#define mono_locks_mutex_release(LOCK, NAME) do { \
+       mono_locks_lock_released (NAME, LOCK); \
+       mono_mutex_unlock (LOCK); \
+} while (0)
 G_END_DECLS
 
 #endif /* __MONO_METADATA_LOCK_TRACER_H__ */
index a6114b1b7e7d5d071e7589322ceae6dcd012a816..fa50598f7d72c68a36f2b4396988c2f24a6b61ba 100644 (file)
@@ -72,11 +72,12 @@ typedef struct _MonoRemotingMethods MonoRemotingMethods;
 /* 
  * This mutex protects the various marshalling related caches in MonoImage
  * and a few other data structures static to this file.
- * Note that when this lock is held it is not possible to take other runtime
- * locks like the loader lock.
+ *
+ * The marshal lock is a non-recursive complex lock that sits below the domain lock in the
+ * runtime locking latice. Which means it can take simple locks suck as the image lock.
  */
-#define mono_marshal_lock() EnterCriticalSection (&marshal_mutex)
-#define mono_marshal_unlock() LeaveCriticalSection (&marshal_mutex)
+#define mono_marshal_lock() mono_locks_acquire (&marshal_mutex, MarshalLock)
+#define mono_marshal_unlock() mono_locks_release (&marshal_mutex, MarshalLock)
 static CRITICAL_SECTION marshal_mutex;
 static gboolean marshal_mutex_initialized;
 
@@ -5209,14 +5210,14 @@ mono_marshal_get_runtime_invoke_dynamic (void)
        mono_mb_emit_byte (mb, CEE_RET);
 #endif /* DISABLE_JIT */
 
-       mono_loader_lock ();
+       mono_marshal_lock ();
        /* double-checked locking */
        if (!method) {
                method = mono_mb_create_method (mb, csig, 16);
                info = mono_wrapper_info_create (method, WRAPPER_SUBTYPE_RUNTIME_INVOKE_DYNAMIC);
                mono_marshal_set_wrapper_info (method, info);
        }
-       mono_loader_unlock ();
+       mono_marshal_unlock ();
 
        mono_mb_free (mb);
 
@@ -10462,7 +10463,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
        clause->flags = MONO_EXCEPTION_CLAUSE_FINALLY;
 #endif
 
-       mono_loader_lock ();
+       mono_marshal_lock ();
 
        if (!enter_method) {
                MonoMethodDesc *desc;
@@ -10483,7 +10484,7 @@ mono_marshal_get_synchronized_wrapper (MonoMethod *method)
                mono_method_desc_free (desc);
        }
 
-       mono_loader_unlock ();
+       mono_marshal_unlock ();
 
 #ifndef DISABLE_JIT
        /* Push this or the type object */
@@ -12212,12 +12213,8 @@ mono_marshal_load_type_info (MonoClass* klass)
        if (!klass->inited)
                mono_class_init (klass);
 
-       mono_loader_lock ();
-
-       if (klass->marshal_info) {
-               mono_loader_unlock ();
+       if (klass->marshal_info)
                return klass->marshal_info;
-       }
 
        /*
         * This function can recursively call itself, so we keep the list of classes which are
@@ -12332,12 +12329,13 @@ mono_marshal_load_type_info (MonoClass* klass)
        loads_list = g_slist_remove (loads_list, klass);
        mono_native_tls_set_value (load_type_info_tls_id, loads_list);
 
-       /*We do double-checking locking on marshal_info */
-       mono_memory_barrier ();
-
-       klass->marshal_info = info;
-
-       mono_loader_unlock ();
+       mono_marshal_lock ();
+       if (!klass->marshal_info) {
+               /*We do double-checking locking on marshal_info */
+               mono_memory_barrier ();
+               klass->marshal_info = info;
+       }
+       mono_marshal_unlock ();
 
        return klass->marshal_info;
 }
index a9f3149d952a4f4d0c33302c03383dacb949ae7a..497d77b12dcb3049215409ff5cb6e4b71abe1976 100644 (file)
@@ -572,6 +572,9 @@ mono_install_image_unload_hook (MonoImageUnloadFunc func, gpointer user_data) MO
 void
 mono_remove_image_unload_hook (MonoImageUnloadFunc func, gpointer user_data) MONO_INTERNAL;
 
+void
+mono_image_append_class_to_reflection_info_set (MonoClass *class) MONO_INTERNAL;
+
 gpointer
 mono_image_set_alloc  (MonoImageSet *set, guint size) MONO_INTERNAL;
 
@@ -586,7 +589,7 @@ mono_image_set_strdup (MonoImageSet *set, const char *s) MONO_INTERNAL;
 MonoType*
 mono_metadata_get_shared_type (MonoType *type) MONO_INTERNAL;
 
-GSList*
+void
 mono_metadata_clean_for_image (MonoImage *image) MONO_INTERNAL;
 
 void
index 18c1be537c80fa677a3f20a3827365a1acb9f021..e1452cb77b250e98b098afc08d8ab5ae98819933 100644 (file)
@@ -2609,11 +2609,11 @@ check_image_sets (MonoImage *image)
        }
 }
 
-GSList*
+void
 mono_metadata_clean_for_image (MonoImage *image)
 {
        CleanForImageUserData ginst_data, gclass_data;
-       GSList *l, *set_list, *free_list = NULL;
+       GSList *l, *set_list;
 
        //check_image_sets (image);
 
@@ -2653,8 +2653,6 @@ mono_metadata_clean_for_image (MonoImage *image)
        g_slist_free (set_list);
 
        mono_loader_unlock ();
-
-       return free_list;
 }
 
 static void
index 43a5e83933cb4202383cc99ac07da7eb688f482a..0ed15e721aa12dcc9a4d4241a92bd082d4f65fd5 100644 (file)
@@ -116,7 +116,6 @@ mono_mb_free (MonoMethodBuilder *mb)
  * Create a MonoMethod from this method builder.
  * Returns: the newly created method.
  *
- * LOCKING: Takes the loader lock.
  */
 MonoMethod *
 mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, int max_stack)
@@ -134,7 +133,6 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
 
        image = mb->method->klass->image;
 
-       mono_loader_lock (); /*FIXME I think this lock can go.*/
 #ifndef DISABLE_JIT
        if (mb->dynamic) {
                method = mb->method;
@@ -245,7 +243,6 @@ mono_mb_create_method (MonoMethodBuilder *mb, MonoMethodSignature *signature, in
        }
 #endif
 
-       mono_loader_unlock ();
        return method;
 }
 
index 929c3fbb2037a75a398384f243a269334773cf52..2891c2eb46b6297d7962f159d01df5d6a858437b 100644 (file)
 
 static guint32 debugger_lock_level = 0;
 static CRITICAL_SECTION debugger_lock_mutex;
-static gboolean mono_debugger_use_debugger = FALSE;
-static MonoObject *last_exception = NULL;
-volatile gint32 _mono_debugger_interruption_request = 0;
-
-void (*mono_debugger_event_handler) (MonoDebuggerEvent event, guint64 data, guint64 arg) = NULL;
 
 typedef struct
 {
@@ -42,24 +37,6 @@ typedef struct
        MonoDebugMethodAddressList *address_list;
 } MethodBreakpointInfo;
 
-typedef struct {
-       MonoImage *image;
-       guint64 index;
-       guint32 token;
-       gchar *name_space;
-       gchar *name;
-} ClassInitCallback;
-
-typedef struct {
-       guint32 id;
-       guint32 shadow_path_len;
-       gchar *shadow_path;
-       MonoDomain *domain;
-       MonoAppDomainSetup *setup;
-} AppDomainSetupInfo;
-
-static GPtrArray *class_init_callbacks = NULL;
-
 static int initialized = 0;
 
 void
@@ -79,64 +56,12 @@ mono_debugger_unlock (void)
 }
 
 void
-mono_debugger_initialize (gboolean use_debugger)
+mono_debugger_initialize ()
 {
-       MONO_GC_REGISTER_ROOT_SINGLE (last_exception);
-       
-       g_assert (!mono_debugger_use_debugger);
-
        InitializeCriticalSection (&debugger_lock_mutex);
-       mono_debugger_use_debugger = use_debugger;
        initialized = 1;
 }
 
-void
-mono_debugger_event (MonoDebuggerEvent event, guint64 data, guint64 arg)
-{
-       if (mono_debugger_event_handler)
-               (* mono_debugger_event_handler) (event, data, arg);
-}
-
-void
-mono_debugger_event_create_appdomain (MonoDomain *domain, gchar *shadow_path)
-{
-       AppDomainSetupInfo info;
-
-       info.id = mono_domain_get_id (domain);
-       info.shadow_path_len = shadow_path ? strlen (shadow_path) : 0;
-       info.shadow_path = shadow_path;
-
-       info.domain = domain;
-       info.setup = domain->setup;
-
-       mono_debugger_event (MONO_DEBUGGER_EVENT_CREATE_APPDOMAIN, (guint64) (gsize) &info, 0);
-}
-
-void
-mono_debugger_event_unload_appdomain (MonoDomain *domain)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_UNLOAD_APPDOMAIN,
-                            (guint64) (gsize) domain, (guint64) mono_domain_get_id (domain));
-}
-
-void
-mono_debugger_cleanup (void)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_FINALIZE_MANAGED_CODE, 0, 0);
-       mono_debugger_event_handler = NULL;
-}
-
-void
-mono_debugger_check_interruption (void)
-{
-       if (!_mono_debugger_interruption_request)
-               return;
-
-       mono_debugger_lock ();
-       mono_debugger_event (MONO_DEBUGGER_EVENT_INTERRUPTION_REQUEST, 0, 0);
-       mono_debugger_unlock ();
-}
-
 /*
  * Debugger breakpoint interface.
  *
@@ -188,138 +113,3 @@ mono_debugger_remove_method_breakpoint (guint64 index)
 
        return 0;
 }
-
-void
-mono_debugger_check_breakpoints (MonoMethod *method, MonoDebugMethodAddress *debug_info)
-{
-       int i;
-
-       if (method->is_inflated)
-               method = ((MonoMethodInflated *) method)->declaring;
-
-       if (method_breakpoints) {
-               for (i = 0; i < method_breakpoints->len; i++) {
-                       MethodBreakpointInfo *info = g_ptr_array_index (method_breakpoints, i);
-
-                       if (method != info->method)
-                               continue;
-
-                       mono_debugger_event (MONO_DEBUGGER_EVENT_JIT_BREAKPOINT,
-                                            (guint64) (gsize) debug_info, info->index);
-               }
-       }
-
-       if (class_init_callbacks) {
-               for (i = 0; i < class_init_callbacks->len; i++) {
-                       ClassInitCallback *info = g_ptr_array_index (class_init_callbacks, i);
-
-                       if ((method->token != info->token) || (method->klass->image != info->image))
-                               continue;
-
-                       mono_debugger_event (MONO_DEBUGGER_EVENT_JIT_BREAKPOINT,
-                                            (guint64) (gsize) debug_info, info->index);
-               }
-       }
-}
-
-MonoClass *
-mono_debugger_register_class_init_callback (MonoImage *image, const gchar *full_name,
-                                           guint32 method_token, guint32 index)
-{
-       ClassInitCallback *info;
-       MonoClass *klass;
-       gchar *name_space, *name, *pos;
-
-       name = g_strdup (full_name);
-
-       pos = strrchr (name, '.');
-       if (pos) {
-               name_space = name;
-               *pos = 0;
-               name = pos + 1;
-       } else {
-               name_space = NULL;
-       }
-
-       mono_loader_lock ();
-
-       klass = mono_class_from_name (image, name_space ? name_space : "", name);
-
-       info = g_new0 (ClassInitCallback, 1);
-       info->image = image;
-       info->index = index;
-       info->token = method_token;
-       info->name_space = name_space;
-       info->name = name;
-
-       if (!class_init_callbacks)
-               class_init_callbacks = g_ptr_array_new ();
-
-       g_ptr_array_add (class_init_callbacks, info);
-       mono_loader_unlock ();
-       return klass;
-}
-
-void
-mono_debugger_remove_class_init_callback (int index)
-{
-       int i;
-
-       if (!class_init_callbacks)
-               return;
-
-       for (i = 0; i < class_init_callbacks->len; i++) {
-               ClassInitCallback *info = g_ptr_array_index (class_init_callbacks, i);
-
-               if (info->index != index)
-                       continue;
-
-               g_ptr_array_remove (class_init_callbacks, info);
-               if (info->name_space)
-                       g_free (info->name_space);
-               else
-                       g_free (info->name);
-               g_free (info);
-       }
-}
-
-void
-mono_debugger_class_initialized (MonoClass *klass)
-{
-       int i;
-
-       if (!class_init_callbacks)
-               return;
-
- again:
-       for (i = 0; i < class_init_callbacks->len; i++) {
-               ClassInitCallback *info = g_ptr_array_index (class_init_callbacks, i);
-
-               if (info->name_space && strcmp (info->name_space, klass->name_space))
-                       continue;
-               if (strcmp (info->name, klass->name))
-                       continue;
-
-               mono_debugger_event (MONO_DEBUGGER_EVENT_CLASS_INITIALIZED,
-                                    (guint64) (gsize) klass, info->index);
-
-               if (info->token) {
-                       int j;
-
-                       for (j = 0; j < klass->method.count; j++) {
-                               if (klass->methods [j]->token != info->token)
-                                       continue;
-
-                               mono_debugger_insert_method_breakpoint (klass->methods [j], info->index);
-                       }
-               }
-
-               g_ptr_array_remove (class_init_callbacks, info);
-               if (info->name_space)
-                       g_free (info->name_space);
-               else
-                       g_free (info->name);
-               g_free (info);
-               goto again;
-       }
-}
index 838b7ef4fa7b4cf9ad3e62256818462fed67f7f0..b8d13b6eec20ed2ced812ec530cd9369879ebcd3 100644 (file)
@@ -7,85 +7,23 @@
 #ifndef __MONO_DEBUG_DEBUGGER_H__
 #define __MONO_DEBUG_DEBUGGER_H__
 
-#include <glib.h>
 #include <mono/metadata/debug-helpers.h>
 #include <mono/metadata/debug-mono-symfile.h>
-#include <mono/utils/mono-codeman.h>
-#include <mono/io-layer/io-layer.h>
+#include <mono/utils/mono-compiler.h>
 
-typedef enum {
-       MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE     = 1,
-       MONO_DEBUGGER_EVENT_INITIALIZE_CORLIB,
-       MONO_DEBUGGER_EVENT_JIT_BREAKPOINT,
-       MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER,
-       MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK,
-       MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK,
-       MONO_DEBUGGER_EVENT_WRAPPER_MAIN,
-       MONO_DEBUGGER_EVENT_MAIN_EXITED,
-       MONO_DEBUGGER_EVENT_UNHANDLED_EXCEPTION,
-       MONO_DEBUGGER_EVENT_THROW_EXCEPTION,
-       MONO_DEBUGGER_EVENT_HANDLE_EXCEPTION,
-       MONO_DEBUGGER_EVENT_THREAD_CREATED,
-       MONO_DEBUGGER_EVENT_THREAD_CLEANUP,
-       MONO_DEBUGGER_EVENT_GC_THREAD_CREATED,
-       MONO_DEBUGGER_EVENT_GC_THREAD_EXITED,
-       MONO_DEBUGGER_EVENT_REACHED_MAIN,
-       MONO_DEBUGGER_EVENT_FINALIZE_MANAGED_CODE,
-       MONO_DEBUGGER_EVENT_LOAD_MODULE,
-       MONO_DEBUGGER_EVENT_UNLOAD_MODULE,
-       MONO_DEBUGGER_EVENT_DOMAIN_CREATE,
-       MONO_DEBUGGER_EVENT_DOMAIN_UNLOAD,
-       MONO_DEBUGGER_EVENT_CLASS_INITIALIZED,
-       MONO_DEBUGGER_EVENT_INTERRUPTION_REQUEST,
-       MONO_DEBUGGER_EVENT_CREATE_APPDOMAIN,
-       MONO_DEBUGGER_EVENT_UNLOAD_APPDOMAIN,
 
-       /* Obsolete, only for backwards compatibility with older debugger versions */
-       MONO_DEBUGGER_EVENT_OLD_TRAMPOLINE              = 256,
+void            mono_debugger_initialize                    (void) MONO_INTERNAL;
 
-       MONO_DEBUGGER_EVENT_TRAMPOLINE                  = 512
-} MonoDebuggerEvent;
+void            mono_debugger_lock                          (void) MONO_INTERNAL;
+void            mono_debugger_unlock                        (void) MONO_INTERNAL;
 
-extern volatile gint32 _mono_debugger_interruption_request;
+gchar *
+mono_debugger_check_runtime_version (const char *filename) MONO_INTERNAL;
 
-extern void (*mono_debugger_event_handler) (MonoDebuggerEvent event, guint64 data, guint64 arg);
+MonoDebugMethodAddressList *
+mono_debugger_insert_method_breakpoint (MonoMethod *method, guint64 idx) MONO_INTERNAL;
 
-MONO_API void            mono_debugger_initialize                    (gboolean use_debugger);
-MONO_API void            mono_debugger_cleanup                       (void);
-
-MONO_API void            mono_debugger_lock                          (void);
-MONO_API void            mono_debugger_unlock                        (void);
-MONO_API void            mono_debugger_event                         (MonoDebuggerEvent event, guint64 data, guint64 arg);
-
-MONO_API gchar *
-mono_debugger_check_runtime_version (const char *filename);
-
-MONO_API void
-mono_debugger_class_initialized (MonoClass *klass);
-
-MONO_API void
-mono_debugger_check_interruption (void);
-
-MONO_API void
-mono_debugger_event_create_appdomain (MonoDomain *domain, gchar *shadow_path);
-
-MONO_API void
-mono_debugger_event_unload_appdomain (MonoDomain *domain);
-
-MONO_API MonoDebugMethodAddressList *
-mono_debugger_insert_method_breakpoint (MonoMethod *method, guint64 idx);
-
-MONO_API int
-mono_debugger_remove_method_breakpoint (guint64 index);
-
-MONO_API void
-mono_debugger_check_breakpoints (MonoMethod *method, MonoDebugMethodAddress *debug_info);
-
-MONO_API MonoClass *
-mono_debugger_register_class_init_callback (MonoImage *image, const gchar *full_name,
-                                           guint32 token, guint32 index);
-
-MONO_API void
-mono_debugger_remove_class_init_callback (int index);
+int
+mono_debugger_remove_method_breakpoint (guint64 index) MONO_INTERNAL;
 
 #endif /* __MONO_DEBUG_DEBUGGER_H__ */
index 6eff0ecbda320d6a165b4be0582e800fa2fdc057..df012ee827295ec7893b021d5b653aee6959fa52 100644 (file)
@@ -106,10 +106,9 @@ typedef struct {
        guint32 size;
 } MonoDebugDelegateTrampolineEntry;
 
-MonoSymbolTable *mono_symbol_table = NULL;
-MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
-gint32 mono_debug_debugger_version = 5;
-gint32 _mono_debug_using_mono_debugger = 0;
+static MonoSymbolTable *mono_symbol_table = NULL;
+static MonoDebugFormat mono_debug_format = MONO_DEBUG_FORMAT_NONE;
+static gint32 mono_debug_debugger_version = 5;
 
 static gboolean mono_debug_initialized = FALSE;
 static GHashTable *mono_debug_handles = NULL;
@@ -129,7 +128,6 @@ static MonoDebugHandle     *open_symfile_from_bundle   (MonoImage *image);
 void _mono_debug_init_corlib (MonoDomain *domain);
 
 extern void (*mono_debugger_class_init_func) (MonoClass *klass);
-extern void (*mono_debugger_class_loaded_methods_func) (MonoClass *klass);
 
 static MonoDebugDataTable *
 create_data_table (MonoDomain *domain)
@@ -228,9 +226,9 @@ void
 mono_debug_init (MonoDebugFormat format)
 {
        g_assert (!mono_debug_initialized);
+       if (format == MONO_DEBUG_FORMAT_DEBUGGER)
+               g_error ("The mdb debugger is no longer supported.");
 
-       if (_mono_debug_using_mono_debugger)
-               format = MONO_DEBUG_FORMAT_DEBUGGER;
 
        mono_debug_initialized = TRUE;
        mono_debug_format = format;
@@ -241,7 +239,7 @@ mono_debug_init (MonoDebugFormat format)
         */
        mono_gc_base_init ();
 
-       mono_debugger_initialize (_mono_debug_using_mono_debugger);
+       mono_debugger_initialize ();
 
        mono_debugger_lock ();
 
@@ -256,8 +254,8 @@ mono_debug_init (MonoDebugFormat format)
        data_table_hash = g_hash_table_new_full (
                NULL, NULL, NULL, (GDestroyNotify) free_data_table);
 
+       /* FIXME this is a disgusting hack. Kill it */
        mono_debugger_class_init_func = mono_debug_add_type;
-       mono_debugger_class_loaded_methods_func = mono_debugger_class_initialized;
        mono_install_assembly_load_hook (mono_debug_add_assembly, NULL);
 
        mono_symbol_table->global_data_table = create_data_table (NULL);
@@ -267,6 +265,7 @@ mono_debug_init (MonoDebugFormat format)
 
 /*
  * INTERNAL USE ONLY !
+ * FIXME this can have a decent name and exist in an internal header
  */
 void
 _mono_debug_init_corlib (MonoDomain *domain)
@@ -275,8 +274,6 @@ _mono_debug_init_corlib (MonoDomain *domain)
                return;
 
        mono_symbol_table->corlib = mono_debug_open_image (mono_defaults.corlib, NULL, 0);
-       mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_CORLIB,
-                            (guint64) (gsize) mono_symbol_table->corlib, 0);
 }
 
 void
@@ -288,13 +285,6 @@ mono_debug_open_image_from_memory (MonoImage *image, const guint8 *raw_contents,
        mono_debug_open_image (image, raw_contents, size);
 }
 
-
-gboolean
-mono_debug_using_mono_debugger (void)
-{
-       return _mono_debug_using_mono_debugger;
-}
-
 void
 mono_debug_cleanup (void)
 {
@@ -328,9 +318,6 @@ mono_debug_domain_create (MonoDomain *domain)
 
        table = create_data_table (domain);
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_DOMAIN_CREATE, (guint64) (gsize) table,
-                            mono_domain_get_id (domain));
-
        mono_debugger_unlock ();
 }
 
@@ -352,9 +339,6 @@ mono_debug_domain_unload (MonoDomain *domain)
                return;
        }
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_DOMAIN_UNLOAD, (guint64) (gsize) table,
-                            mono_domain_get_id (domain));
-
        g_hash_table_remove (data_table_hash, domain);
 
        mono_debugger_unlock ();
@@ -385,9 +369,6 @@ mono_debug_close_image (MonoImage *image)
                return;
        }
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_UNLOAD_MODULE, (guint64) (gsize) handle,
-                            handle->index);
-
        mono_debug_list_remove (&mono_symbol_table->symbol_files, handle);
        g_hash_table_remove (mono_debug_handles, image);
 
@@ -420,16 +401,12 @@ mono_debug_open_image (MonoImage *image, const guint8 *raw_contents, int size)
        handle->type_table = create_data_table (NULL);
 
        handle->symfile = mono_debug_open_mono_symbols (
-               handle, raw_contents, size, _mono_debug_using_mono_debugger);
+               handle, raw_contents, size, FALSE);
 
        mono_debug_list_add (&mono_symbol_table->symbol_files, handle);
 
        g_hash_table_insert (mono_debug_handles, image, handle);
 
-       if (mono_symbol_table->corlib)
-               mono_debugger_event (MONO_DEBUGGER_EVENT_LOAD_MODULE,
-                                    (guint64) (gsize) handle, 0);
-
        mono_debugger_unlock ();
 
        return handle;
@@ -1301,3 +1278,14 @@ open_symfile_from_bundle (MonoImage *image)
 
        return NULL;
 }
+
+/**
+ * mono_debug_enabled:
+ *
+ * Returns true is debug information is enabled. This doesn't relate if a debugger is present or not.
+ */
+mono_bool
+mono_debug_enabled (void)
+{
+       return mono_debug_format != MONO_DEBUG_FORMAT_NONE;
+}
index 5f8b0258143de4a76e0526234dd27f7d334f410a..2106a6f3e5e884456c0bed773f68005118266527 100644 (file)
@@ -36,6 +36,7 @@ typedef struct _MonoDebugList                 MonoDebugList;
 typedef enum {
        MONO_DEBUG_FORMAT_NONE,
        MONO_DEBUG_FORMAT_MONO,
+       /* Deprecated, the mdb debugger is not longer supported. */
        MONO_DEBUG_FORMAT_DEBUGGER
 } MonoDebugFormat;
 
@@ -104,6 +105,8 @@ struct _MonoDebugSourceLocation {
        uint32_t il_offset;
 };
 
+MONO_API mono_bool mono_debug_enabled (void);
+
 /*
  * These bits of the MonoDebugLocalInfo's "index" field are flags specifying
  * where the variable is actually stored.
@@ -146,11 +149,6 @@ struct _MonoDebugVarInfo {
 #define MONO_DEBUGGER_MINOR_VERSION                    6
 #define MONO_DEBUGGER_MAGIC                            0x7aff65af4253d427ULL
 
-extern MonoSymbolTable *mono_symbol_table;
-extern MonoDebugFormat mono_debug_format;
-extern int32_t mono_debug_debugger_version;
-extern int32_t _mono_debug_using_mono_debugger;
-
 MONO_API void mono_debug_list_add (MonoDebugList **list, const void* data);
 MONO_API void mono_debug_list_remove (MonoDebugList **list, const void* data);
 
@@ -163,8 +161,6 @@ MONO_API void mono_debug_close_image (MonoImage *image);
 MONO_API void mono_debug_domain_unload (MonoDomain *domain);
 MONO_API void mono_debug_domain_create (MonoDomain *domain);
 
-MONO_API mono_bool mono_debug_using_mono_debugger (void);
-
 MONO_API MonoDebugMethodAddress *
 mono_debug_add_method (MonoMethod *method, MonoDebugMethodJitInfo *jit, MonoDomain *domain);
 
index e222697cdc20c65de5c7db2e860e85030b22470e..2c6ea2b68429083a131526041831ea1292f7593b 100644 (file)
@@ -2013,7 +2013,7 @@ mono_class_create_runtime_vtable (MonoDomain *domain, MonoClass *class, gboolean
                                        bitmap = default_bitmap;
                                } else if (mono_type_is_struct (field->type)) {
                                        fclass = mono_class_from_mono_type (field->type);
-                                       bitmap = compute_class_bitmap (fclass, default_bitmap, sizeof (default_bitmap) * 8, - (sizeof (MonoObject) / sizeof (gpointer)), &max_set, FALSE);
+                                       bitmap = compute_class_bitmap (fclass, default_bitmap, sizeof (default_bitmap) * 8, - (int)(sizeof (MonoObject) / sizeof (gpointer)), &max_set, FALSE);
                                        numbits = max_set + 1;
                                } else {
                                        default_bitmap [0] = 0;
@@ -4046,8 +4046,6 @@ mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
        }
        mono_thread_init_apartment_state ();
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_REACHED_MAIN, 0, 0);
-
        /* FIXME: check signature of method */
        if (mono_method_signature (method)->ret->type == MONO_TYPE_I4) {
                MonoObject *res;
@@ -4073,8 +4071,6 @@ mono_runtime_exec_main (MonoMethod *method, MonoArray *args, MonoObject **exc)
                }
        }
 
-       mono_debugger_event (MONO_DEBUGGER_EVENT_MAIN_EXITED, (guint64) (gsize) rval, 0);
-
        return rval;
 }
 
index 4605e587f782b9b1823761934cfbd978800c6730..eddd5dc570f8fb0d819d253181d7aabf62d2686c 100644 (file)
@@ -7228,9 +7228,9 @@ static int
 _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                             MonoTypeNameParse *info)
 {
-       char *start, *p, *w, *temp, *last_point, *startn;
+       char *start, *p, *w, *last_point, *startn;
        int in_modifiers = 0;
-       int isbyref = 0, rank, arity = 0, i;
+       int isbyref = 0, rank = 0;
 
        start = p = w = name;
 
@@ -7277,14 +7277,6 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                case ']':
                        in_modifiers = 1;
                        break;
-               case '`':
-                       ++p;
-                       i = strtol (p, &temp, 10);
-                       arity += i;
-                       if (p == temp)
-                               return 0;
-                       p = temp-1;
-                       break;
                default:
                        break;
                }
@@ -7318,10 +7310,32 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                        *p++ = 0;
                        break;
                case '[':
-                       if (arity != 0) {
-                               *p++ = 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
+                               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) /* generic args after array spec*/ //XXX test
+                                       return 0;
                                info->type_arguments = g_ptr_array_new ();
-                               for (i = 0; i < arity; i++) {
+                               while (*p) {
                                        MonoTypeNameParse *subinfo = g_new0 (MonoTypeNameParse, 1);
                                        gboolean fqname = FALSE;
 
@@ -7364,36 +7378,15 @@ _mono_reflection_parse_type (char *name, char **endptr, gboolean is_recursed,
                                        } else if (fqname && (*p == ']')) {
                                                *p++ = 0;
                                        }
-
-                                       if (i + 1 < arity) {
-                                               if (*p != ',')
-                                                       return 0;
-                                       } else {
-                                               if (*p != ']')
-                                                       return 0;
+                                       if (*p == ']') {
+                                               *p++ = 0;
+                                               break;
+                                       } else if (!*p) {
+                                               return 0;
                                        }
                                        *p++ = 0;
                                }
-
-                               arity = 0;
-                               break;
-                       }
-                       rank = 1;
-                       *p++ = 0;
-                       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));
                        break;
                case ']':
                        if (is_recursed)
@@ -9847,12 +9840,16 @@ mono_reflection_setup_internal_class (MonoReflectionTypeBuilder *tb)
 
                /* Put into cache so mono_class_get () will find it.
                Skip nested types as those should not be available on the global scope. */
-               if (!tb->nesting_type) {
+               if (!tb->nesting_type)
                        mono_image_add_to_name_cache (klass->image, klass->name_space, klass->name, tb->table_idx);
-               } else {
-                       klass->image->reflection_info_unregister_classes =
-                               g_slist_prepend (klass->image->reflection_info_unregister_classes, klass);
-               }
+
+               /*
+               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);
        }
@@ -10578,9 +10575,9 @@ mono_reflection_bind_generic_method_parameters (MonoReflectionMethod *rmethod, M
                 * This table maps metadata structures representing inflated methods/fields
                 * to the reflection objects representing their generic definitions.
                 */
-               mono_loader_lock ();
+               mono_image_lock ((MonoImage*)image);
                mono_g_hash_table_insert (image->generic_def_objects, imethod, rmethod);
-               mono_loader_unlock ();
+               mono_image_unlock ((MonoImage*)image);
        }
 
        if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
@@ -10624,9 +10621,9 @@ inflate_mono_method (MonoClass *klass, MonoMethod *method, MonoObject *obj)
        if (method->is_generic && method->klass->image->dynamic) {
                MonoDynamicImage *image = (MonoDynamicImage*)method->klass->image;
 
-               mono_loader_lock ();
+               mono_image_lock ((MonoImage*)image);
                mono_g_hash_table_insert (image->generic_def_objects, imethod, obj);
-               mono_loader_unlock ();
+               mono_image_unlock ((MonoImage*)image);
        }
        return (MonoMethod *) imethod;
 }
@@ -11465,9 +11462,7 @@ mono_reflection_initialize_generic_parameter (MonoReflectionGenericParam *gparam
        gparam->type.type = &pklass->byval_arg;
 
        mono_class_set_ref_info (pklass, gparam);
-       mono_image_lock (image);
-       image->reflection_info_unregister_classes = g_slist_prepend (image->reflection_info_unregister_classes, pklass);
-       mono_image_unlock (image);
+       mono_image_append_class_to_reflection_info_set (pklass);
 }
 
 MonoArray *
index c208638850d9b3b330cc5c9f9db35c6765b5e5e4..8376aafac65db009aa7e000cb4f8661187cd788d 100644 (file)
@@ -1060,11 +1060,21 @@ mono_gc_get_managed_allocator_by_type (int atype)
        if (!mono_runtime_has_tls_get ())
                return NULL;
 
-       mono_loader_lock ();
        res = alloc_method_cache [atype];
-       if (!res)
-               res = alloc_method_cache [atype] = create_allocator (atype);
-       mono_loader_unlock ();
+       if (res)
+               return res;
+
+       res = create_allocator (atype);
+       LOCK_GC;
+       if (alloc_method_cache [atype]) {
+               mono_free_method (res);
+               res = alloc_method_cache [atype];
+       } else {
+               mono_memory_barrier ();
+               alloc_method_cache [atype] = res;
+       }
+       UNLOCK_GC;
+
        return res;
 #else
        return NULL;
index e400d7cc6c8b101e2c73fe93e9c166a292111e05..d0687b2bcaa0247e43892e863a7fec132444695a 100755 (executable)
@@ -89,7 +89,7 @@
 #define ARCH_COPY_SIGCTX_REGS(a,ctx) do {      \
        int __i;        \
        for (__i = 0; __i < 32; ++__i)  \
-               ((a)[__i]) = UCONTEXT_REG_Rn((ctx), __i);       \
+               ((a)[__i]) = (gpointer) UCONTEXT_REG_Rn((ctx), __i);    \
        } while (0)
 
 #elif defined(TARGET_ARM)
index 391fcee27b1cb4b07ae7040010015e6ee7d5c5ed..774baa63bba30fed831cd95b3d645e54b965ace1 100644 (file)
@@ -636,7 +636,7 @@ sgen_bridge_processing_finish (int generation)
 
        /* sort array according to decreasing finishing time */
 
-       qsort (all_entries, hash_table.num_entries, sizeof (HashEntry*), compare_hash_entries);
+       sgen_qsort (all_entries, hash_table.num_entries, sizeof (HashEntry*), compare_hash_entries);
 
        SGEN_TV_GETTIME (btv);
        step_3 = SGEN_TV_ELAPSED (atv, btv);
@@ -816,6 +816,28 @@ sgen_bridge_processing_finish (int generation)
        bridge_processing_in_progress = FALSE;
 }
 
+void
+sgen_bridge_describe_pointer (MonoObject *obj)
+{
+       HashEntry *entry;
+       int i;
+
+       for (i = 0; i < registered_bridges.size; ++i) {
+               if (obj == DYN_ARRAY_PTR_REF (&registered_bridges, i)) {
+                       printf ("Pointer is a registered bridge object.\n");
+                       break;
+               }
+       }
+
+       entry = sgen_hash_table_lookup (&hash_table, obj);
+       if (!entry)
+               return;
+
+       printf ("Bridge hash table entry %p:\n", entry);
+       printf ("  is bridge: %d\n", (int)entry->is_bridge);
+       printf ("  is visited: %d\n", (int)entry->is_visited);
+}
+
 static const char *bridge_class;
 
 static gboolean
index 45c6f2093a8283b09b439abc391e9b57379eb67d..a04e1a7c1f560aa67041e1fd8b73fe16bd1d4b62 100644 (file)
@@ -77,6 +77,7 @@ describe_pointer (char *ptr, gboolean need_setup)
                if (!start)
                        return;
                ptr = start;
+               vtable = (MonoVTable*)LOAD_VTABLE (ptr);
        } else {
                if (sgen_ptr_is_in_los (ptr, &start)) {
                        if (ptr == start)
@@ -85,6 +86,7 @@ describe_pointer (char *ptr, gboolean need_setup)
                                printf ("Pointer is at offset 0x%x of object %p in LOS space.\n", (int)(ptr - start), start);
                        ptr = start;
                        mono_sgen_los_describe_pointer (ptr);
+                       vtable = (MonoVTable*)LOAD_VTABLE (ptr);
                } else if (major_collector.ptr_is_in_non_pinned_space (ptr, &start)) {
                        if (ptr == start)
                                printf ("Pointer is the start of object %p in oldspace.\n", start);
@@ -94,9 +96,11 @@ describe_pointer (char *ptr, gboolean need_setup)
                                printf ("Pointer inside oldspace.\n");
                        if (start)
                                ptr = start;
-                       major_collector.describe_pointer (ptr);
+                       vtable = major_collector.describe_pointer (ptr);
                } else if (major_collector.obj_is_from_pinned_alloc (ptr)) {
+                       // FIXME: Handle pointers to the inside of objects
                        printf ("Pointer is inside a pinned chunk.\n");
+                       vtable = (MonoVTable*)LOAD_VTABLE (ptr);
                } else {
                        printf ("Pointer unknown.\n");
                        return;
@@ -112,17 +116,14 @@ describe_pointer (char *ptr, gboolean need_setup)
                goto restart;
        }
 
-       // FIXME: Handle pointers to the inside of objects
-       vtable = (MonoVTable*)LOAD_VTABLE (ptr);
-
        printf ("VTable: %p\n", vtable);
        if (vtable == NULL) {
                printf ("VTable is invalid (empty).\n");
-               return;
+               goto bridge;
        }
        if (sgen_ptr_in_nursery (vtable)) {
                printf ("VTable is invalid (points inside nursery).\n");
-               return;
+               goto bridge;
        }
        printf ("Class: %s\n", vtable->klass->name);
 
@@ -133,7 +134,10 @@ describe_pointer (char *ptr, gboolean need_setup)
        printf ("Descriptor type: %d (%s)\n", type, descriptor_types [type]);
 
        size = sgen_safe_object_get_size ((MonoObject*)ptr);
-       printf ("Size: %td\n", size);
+       printf ("Size: %d\n", (int)size);
+
+ bridge:
+       sgen_bridge_describe_pointer ((MonoObject*)ptr);
 }
 
 void
index 573f3c6486e02cd3c3d3c180577156dc104d11a7..f07ad4a6ba00b214189b2b51e470daea9ad21ac7 100644 (file)
@@ -137,6 +137,7 @@ sgen_gc_descr_has_references (mword desc)
 
 #define SGEN_VTABLE_HAS_REFERENCES(vt) (sgen_gc_descr_has_references ((mword)((MonoVTable*)(vt))->gc_descr))
 #define SGEN_CLASS_HAS_REFERENCES(c)   (sgen_gc_descr_has_references ((mword)(c)->gc_descr))
+#define SGEN_OBJECT_HAS_REFERENCES(o)  (SGEN_VTABLE_HAS_REFERENCES (SGEN_LOAD_VTABLE ((o))))
 
 /* helper macros to scan and traverse objects, macros because we resue them in many functions */
 #define OBJ_RUN_LEN_SIZE(size,desc,obj) do { \
index 283d61bdb51779cf9b7498bfa56a6e13da72632c..45edc7be4ab6081197b55b0e88c2e7907e0ea9bb 100644 (file)
@@ -401,6 +401,7 @@ sgen_safe_name (void* obj)
  * ######################################################################
  */
 LOCK_DECLARE (gc_mutex);
+gboolean sgen_try_free_some_memory;
 
 #define SCAN_START_SIZE        SGEN_SCAN_START_SIZE
 
@@ -2919,8 +2920,8 @@ major_copy_or_mark_from_roots (int *old_next_pin_slot, gboolean finish_up_concur
                                continue;
                        }
                        sgen_los_pin_object (bigobj->data);
-                       /* FIXME: only enqueue if object has references */
-                       GRAY_OBJECT_ENQUEUE (WORKERS_DISTRIBUTE_GRAY_QUEUE, bigobj->data);
+                       if (SGEN_OBJECT_HAS_REFERENCES (bigobj->data))
+                               GRAY_OBJECT_ENQUEUE (WORKERS_DISTRIBUTE_GRAY_QUEUE, bigobj->data);
                        if (G_UNLIKELY (do_pin_stats))
                                sgen_pin_stats_register_object ((char*) bigobj->data, safe_object_get_size ((MonoObject*) bigobj->data));
                        SGEN_LOG (6, "Marked large object %p (%s) size: %lu from roots", bigobj->data, safe_name (bigobj->data), (unsigned long)sgen_los_object_size (bigobj));
@@ -3105,6 +3106,13 @@ major_start_collection (gboolean concurrent, int *old_next_pin_slot)
 
 static void
 wait_for_workers_to_finish (void)
+{
+       while (!sgen_workers_all_done ())
+               g_usleep (200);
+}
+
+static void
+join_workers (void)
 {
        if (concurrent_collection_in_progress || major_collector.is_parallel) {
                gray_queue_redirect (&gray_queue);
@@ -3128,13 +3136,13 @@ major_finish_collection (const char *reason, int old_next_pin_slot, gboolean sca
        TV_GETTIME (btv);
 
        if (concurrent_collection_in_progress || major_collector.is_parallel)
-               wait_for_workers_to_finish ();
+               join_workers ();
 
        if (concurrent_collection_in_progress) {
                current_object_ops = major_collector.major_concurrent_ops;
 
                major_copy_or_mark_from_roots (NULL, TRUE, scan_mod_union);
-               wait_for_workers_to_finish ();
+               join_workers ();
 
                g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
 
@@ -3341,19 +3349,30 @@ major_update_or_finish_concurrent_collection (gboolean force_finish)
 
        g_assert (sgen_gray_object_queue_is_empty (&gray_queue));
 
-       major_collector.update_cardtable_mod_union ();
-       sgen_los_update_cardtable_mod_union ();
-
        if (!force_finish && !sgen_workers_all_done ()) {
+               major_collector.update_cardtable_mod_union ();
+               sgen_los_update_cardtable_mod_union ();
+
                MONO_GC_CONCURRENT_UPDATE_END (GENERATION_OLD, major_collector.get_and_reset_num_major_objects_marked ());
                return FALSE;
        }
 
-       if (mod_union_consistency_check)
-               sgen_check_mod_union_consistency ();
+       /*
+        * The major collector can add global remsets which are processed in the finishing
+        * nursery collection, below.  That implies that the workers must have finished
+        * marking before the nursery collection is allowed to run, otherwise we might miss
+        * some remsets.
+        */
+       wait_for_workers_to_finish ();
+
+       major_collector.update_cardtable_mod_union ();
+       sgen_los_update_cardtable_mod_union ();
 
        collect_nursery (&unpin_queue, TRUE);
 
+       if (mod_union_consistency_check)
+               sgen_check_mod_union_consistency ();
+
        current_collection_generation = GENERATION_OLD;
        major_finish_collection ("finishing", -1, TRUE);
 
@@ -4091,6 +4110,7 @@ sgen_thread_register (SgenThreadInfo* info, void *addr)
 
        binary_protocol_thread_register ((gpointer)mono_thread_info_get_tid (info));
 
+       // FIXME: Unift with mono_thread_get_stack_bounds ()
        /* try to get it with attributes first */
 #if (defined(HAVE_PTHREAD_GETATTR_NP) || defined(HAVE_PTHREAD_ATTR_GET_NP)) && defined(HAVE_PTHREAD_ATTR_GETSTACK)
   {
@@ -4115,8 +4135,14 @@ sgen_thread_register (SgenThreadInfo* info, void *addr)
      pthread_attr_destroy (&attr);
   }
 #elif defined(HAVE_PTHREAD_GET_STACKSIZE_NP) && defined(HAVE_PTHREAD_GET_STACKADDR_NP)
-                info->stack_end = (char*)pthread_get_stackaddr_np (pthread_self ());
-                info->stack_start_limit = (char*)info->stack_end - pthread_get_stacksize_np (pthread_self ());
+       {
+               size_t stsize = 0;
+               guint8 *staddr = NULL;
+
+               mono_thread_get_stack_bounds (&staddr, &stsize);
+               info->stack_start_limit = staddr;
+               info->stack_end = staddr + stsize;
+       }
 #else
        {
                /* FIXME: we assume the stack grows down */
@@ -4139,7 +4165,7 @@ sgen_thread_register (SgenThreadInfo* info, void *addr)
 }
 
 static void
-sgen_thread_unregister (SgenThreadInfo *p)
+sgen_thread_detach (SgenThreadInfo *p)
 {
        /* If a delegate is passed to native code and invoked on a thread we dont
         * know about, the jit will register it with mono_jit_thread_attach, but
@@ -4149,7 +4175,11 @@ sgen_thread_unregister (SgenThreadInfo *p)
         */
        if (mono_domain_get ())
                mono_thread_detach (mono_thread_current ());
+}
 
+static void
+sgen_thread_unregister (SgenThreadInfo *p)
+{
        binary_protocol_thread_unregister ((gpointer)mono_thread_info_get_tid (p));
        SGEN_LOG (3, "unregister thread %p (%p)", p, (gpointer)mono_thread_info_get_tid (p));
 
@@ -4840,6 +4870,7 @@ mono_gc_base_init (void)
        gc_debug_file = stderr;
 
        cb.thread_register = sgen_thread_register;
+       cb.thread_detach = sgen_thread_detach;
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
        cb.mono_method_is_critical = (gpointer)is_critical_method;
@@ -5481,7 +5512,7 @@ mono_gc_get_write_barrier (void)
        res = mono_mb_create_method (mb, sig, 16);
        mono_mb_free (mb);
 
-       mono_loader_lock ();
+       LOCK_GC;
        if (write_barrier_method) {
                /* Already created */
                mono_free_method (res);
@@ -5490,7 +5521,7 @@ mono_gc_get_write_barrier (void)
                mono_memory_barrier ();
                write_barrier_method = res;
        }
-       mono_loader_unlock ();
+       UNLOCK_GC;
 
        return write_barrier_method;
 }
@@ -5567,7 +5598,12 @@ sgen_gc_lock (void)
 void
 sgen_gc_unlock (void)
 {
-       UNLOCK_GC;
+       gboolean try_free = sgen_try_free_some_memory;
+       sgen_try_free_some_memory = FALSE;
+       mono_mutex_unlock (&gc_mutex);
+       MONO_GC_UNLOCKED ();
+       if (try_free)
+               mono_thread_hazardous_try_free_some ();
 }
 
 void
index 18948819cdb81fadf1eed25a86c273926ec16e17..15afdbcd03a2cd0f150b30b519127ada45bf40da 100644 (file)
@@ -158,10 +158,7 @@ struct _GCMemSection {
                MONO_GC_LOCKED ();                              \
        } while (0)
 #define TRYLOCK_GC (mono_mutex_trylock (&gc_mutex) == 0)
-#define UNLOCK_GC do {                                         \
-               mono_mutex_unlock (&gc_mutex);                  \
-               MONO_GC_UNLOCKED ();                            \
-       } while (0)
+#define UNLOCK_GC do { sgen_gc_unlock (); } while (0)
 
 extern LOCK_DECLARE (sgen_interruption_mutex);
 
@@ -279,19 +276,19 @@ extern int sgen_nursery_bits MONO_INTERNAL;
 extern char *sgen_nursery_start MONO_INTERNAL;
 extern char *sgen_nursery_end MONO_INTERNAL;
 
-static MONO_ALWAYS_INLINE gboolean
+static inline MONO_ALWAYS_INLINE gboolean
 sgen_ptr_in_nursery (void *p)
 {
        return SGEN_PTR_IN_NURSERY ((p), DEFAULT_NURSERY_BITS, sgen_nursery_start, sgen_nursery_end);
 }
 
-static MONO_ALWAYS_INLINE char*
+static inline MONO_ALWAYS_INLINE char*
 sgen_get_nursery_start (void)
 {
        return sgen_nursery_start;
 }
 
-static MONO_ALWAYS_INLINE char*
+static inline MONO_ALWAYS_INLINE char*
 sgen_get_nursery_end (void)
 {
        return sgen_nursery_end;
@@ -676,7 +673,7 @@ struct _SgenMajorCollector {
        void (*init_worker_thread) (void *data);
        void (*reset_worker_data) (void *data);
        gboolean (*is_valid_object) (char *object);
-       gboolean (*describe_pointer) (char *pointer);
+       MonoVTable* (*describe_pointer) (char *pointer);
        guint8* (*get_cardtable_mod_union_for_object) (char *object);
        long long (*get_and_reset_num_major_objects_marked) (void);
 };
@@ -795,6 +792,7 @@ gboolean sgen_is_bridge_object (MonoObject *obj) MONO_INTERNAL;
 gboolean sgen_is_bridge_class (MonoClass *class) MONO_INTERNAL;
 void sgen_mark_bridge_object (MonoObject *obj) MONO_INTERNAL;
 void sgen_bridge_register_finalized_object (MonoObject *object) MONO_INTERNAL;
+void sgen_bridge_describe_pointer (MonoObject *object) MONO_INTERNAL;
 
 void sgen_scan_togglerefs (char *start, char *end, ScanCopyContext ctx) MONO_INTERNAL;
 void sgen_process_togglerefs (void) MONO_INTERNAL;
@@ -978,6 +976,7 @@ extern int degraded_mode;
 extern int default_nursery_size;
 extern guint32 tlab_size;
 extern NurseryClearPolicy nursery_clear_policy;
+extern gboolean sgen_try_free_some_memory;
 
 extern LOCK_DECLARE (gc_mutex);
 
@@ -1049,6 +1048,10 @@ sgen_dummy_use (gpointer v) {
 gboolean sgen_parse_environment_string_extract_number (const char *str, glong *out) MONO_INTERNAL;
 void sgen_env_var_error (const char *env_var, const char *fallback, const char *description_format, ...) MONO_INTERNAL;
 
+/* Utilities */
+
+void sgen_qsort (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*)) MONO_INTERNAL;
+
 #endif /* HAVE_SGEN_GC */
 
 #endif /* __MONO_SGENGC_H__ */
index 5d51db7d8671de70ed44d642d4065b57a8c640f3..58f825903e25dd7bb0ea7e1aeef3a41dad177670 100644 (file)
@@ -510,10 +510,10 @@ mono_sgen_los_describe_pointer (char *ptr)
                vtable = (MonoVTable*)SGEN_LOAD_VTABLE (obj->data);
 
                if (obj->data == ptr) {
-                       SGEN_LOG (0, "%s (size %td pin %d)\n", los_kind, size, pinned ? 1 : 0);
+                       SGEN_LOG (0, "%s (size %d pin %d)\n", los_kind, (int)size, pinned ? 1 : 0);
                } else {
-                       SGEN_LOG (0, "%s (interior-ptr offset %td size %td pin %d)",
-                                       los_kind, ptr - obj->data, size, pinned ? 1 : 0);
+                       SGEN_LOG (0, "%s (interior-ptr offset %td size %d pin %d)",
+                                         los_kind, ptr - obj->data, (int)size, pinned ? 1 : 0);
                }
 
                return TRUE;
index 98b4b7ac1d8220f03e42fa1519c9cb9704366ad8..1ef999b862cf6f08d16304d71516541da2f7d3db 100755 (executable)
@@ -564,7 +564,13 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references)
        info->pinned = pinned;
        info->has_references = has_references;
        info->has_pinned = pinned;
-       info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD); /*FIXME WHY??? */
+       /*
+        * Blocks that are to-space are not evacuated from.  During an major collection
+        * blocks are allocated for two reasons: evacuating objects from the nursery and
+        * evacuating them from major blocks marked for evacuation.  In both cases we don't
+        * want further evacuation.
+        */
+       info->is_to_space = (sgen_get_current_collection_generation () == GENERATION_OLD);
        info->swept = 1;
 #ifndef FIXED_HEAP
        info->block = ms_get_empty_block ();
@@ -947,7 +953,7 @@ major_is_valid_object (char *object)
 }
 
 
-static gboolean
+static MonoVTable*
 major_describe_pointer (char *ptr)
 {
        MSBlockInfo *block;
@@ -989,10 +995,10 @@ major_describe_pointer (char *ptr)
 
                SGEN_LOG (0, " marked %d)\n", marked ? 1 : 0);
 
-               return TRUE;
+               return vtable;
        } END_FOREACH_BLOCK;
 
-       return FALSE;
+       return NULL;
 }
 
 static void
@@ -1185,6 +1191,7 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
                                MS_CALC_MARK_BIT (word, bit, obj);
                                SGEN_ASSERT (9, !MS_MARK_BIT (block, word, bit), "object %p already marked", obj);
                                MS_PAR_SET_MARK_BIT (was_marked, block, word, bit);
+                               binary_protocol_mark (obj, vt, sgen_safe_object_get_size ((MonoObject*)obj));
                        }
                } else {
                        /*
@@ -1297,8 +1304,8 @@ major_copy_or_mark_object_concurrent (void **ptr, void *obj, SgenGrayQueue *queu
 #endif
 
                        sgen_los_pin_object (obj);
-                       /* FIXME: only enqueue if object has references */
-                       GRAY_OBJECT_ENQUEUE (queue, obj);
+                       if (SGEN_OBJECT_HAS_REFERENCES (obj))
+                               GRAY_OBJECT_ENQUEUE (queue, obj);
                        INC_NUM_MAJOR_OBJECTS_MARKED ();
                }
        }
@@ -1436,8 +1443,8 @@ major_copy_or_mark_object (void **ptr, void *obj, SgenGrayQueue *queue)
 #endif
 
                        sgen_los_pin_object (obj);
-                       /* FIXME: only enqueue if object has references */
-                       GRAY_OBJECT_ENQUEUE (queue, obj);
+                       if (SGEN_OBJECT_HAS_REFERENCES (obj))
+                               GRAY_OBJECT_ENQUEUE (queue, obj);
                }
        }
 }
@@ -1538,6 +1545,7 @@ static void
 sweep_block (MSBlockInfo *block, gboolean during_major_collection)
 {
        int count;
+       void *reversed = NULL;
 
        if (!during_major_collection)
                g_assert (!sgen_concurrent_collection_in_progress ());
@@ -1563,10 +1571,15 @@ sweep_block (MSBlockInfo *block, gboolean during_major_collection)
        /* reset mark bits */
        memset (block->mark_words, 0, sizeof (mword) * MS_NUM_MARK_WORDS);
 
-       /*
-        * FIXME: reverse free list so that it's in address
-        * order
-        */
+       /* Reverse free list so that it's in address order */
+       reversed = NULL;
+       while (block->free_list) {
+               void *next = *(void**)block->free_list;
+               *(void**)block->free_list = reversed;
+               reversed = block->free_list;
+               block->free_list = next;
+       }
+       block->free_list = reversed;
 
        block->swept = 1;
 }
@@ -1914,7 +1927,7 @@ major_have_computer_minor_collection_allowance (void)
                        empty_block_arr [i++] = block;
                SGEN_ASSERT (0, i == num_empty_blocks, "empty block count wrong");
 
-               qsort (empty_block_arr, num_empty_blocks, sizeof (void*), compare_pointers);
+               sgen_qsort (empty_block_arr, num_empty_blocks, sizeof (void*), compare_pointers);
 
                /*
                 * We iterate over the free blocks, trying to find MS_BLOCK_ALLOC_NUM
index 96cb905011585634774180a7a0c3c4529010ced3..eb44627eee03f516223bb762b59f6e3ef741e002 100644 (file)
@@ -139,11 +139,11 @@ sgen_memgov_try_calculate_minor_collection_allowance (gboolean overwrite)
        if (debug_print_allowance) {
                mword old_major = last_collection_old_num_major_sections * major_collector.section_size;
 
-               SGEN_LOG (1, "Before collection: %td bytes (%td major, %td LOS)",
-                               old_major + last_collection_old_los_memory_usage, old_major, last_collection_old_los_memory_usage);
-               SGEN_LOG (1, "After collection: %td bytes (%td major, %td LOS)",
-                               new_heap_size, new_major, last_collection_los_memory_usage);
-               SGEN_LOG (1, "Allowance: %td bytes", minor_collection_allowance);
+               SGEN_LOG (1, "Before collection: %ld bytes (%ld major, %ld LOS)",
+                                 (long)(old_major + last_collection_old_los_memory_usage), (long)old_major, (long)last_collection_old_los_memory_usage);
+               SGEN_LOG (1, "After collection: %ld bytes (%ld major, %ld LOS)",
+                                 (long)new_heap_size, (long)new_major, (long)last_collection_los_memory_usage);
+               SGEN_LOG (1, "Allowance: %ld bytes", (long)minor_collection_allowance);
        }
 
        if (major_collector.have_computed_minor_collection_allowance)
index d16b2b778a6438932f2a4060eb6ebb5ab23b4782..0d90a79806325c36d6c64f52df3b8063df4d7cd5 100644 (file)
@@ -202,7 +202,7 @@ void
 dump_alloc_records (void)
 {
        int i;
-       qsort (alloc_records, next_record, sizeof (AllocRecord), comp_alloc_record);
+       sgen_qsort (alloc_records, next_record, sizeof (AllocRecord), comp_alloc_record);
 
        printf ("------------------------------------DUMP RECORDS----------------------------\n");
        for (i = 0; i < next_record; ++i) {
@@ -220,7 +220,7 @@ verify_alloc_records (void)
        int max_hole = 0;
        AllocRecord *prev = NULL;
 
-       qsort (alloc_records, next_record, sizeof (AllocRecord), comp_alloc_record);
+       sgen_qsort (alloc_records, next_record, sizeof (AllocRecord), comp_alloc_record);
        printf ("------------------------------------DUMP RECORDS- %d %d---------------------------\n", next_record, alloc_count);
        for (i = 0; i < next_record; ++i) {
                AllocRecord *rec = alloc_records + i;
index 41d068b1e51512f87037b70cf0ea3057b9b4499b..2a902bdd4f06096197366f98bb421d5348f288a8 100644 (file)
@@ -92,7 +92,7 @@ sgen_suspend_thread (SgenThreadInfo *info)
        if (mono_gc_get_gc_callbacks ()->thread_suspend_func)
                mono_gc_get_gc_callbacks ()->thread_suspend_func (info->runtime_data, &ctx, NULL);
 
-       SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)info->info.native_handle, info->stopped_ip, info->stack_start);
+       SGEN_LOG (2, "thread %p stopped at %p stack_start=%p", (void*)(gsize)info->info.native_handle, info->stopped_ip, info->stack_start);
 
        binary_protocol_thread_suspend ((gpointer)mono_thread_info_get_tid (info), info->stopped_ip);
 
index cf3ba9d5519b2ea49ad62448d61008283048654c..36769f35cb2d7aca67fef29ccf08623703d5ad21 100755 (executable)
@@ -57,11 +57,29 @@ sgen_suspend_thread (SgenThreadInfo *info)
 
        CloseHandle (handle);
 
-       info->stopped_ip = (gpointer)context.Eip;
-       info->stack_start = (char*)context.Esp - REDZONE_SIZE;
-
 #ifdef USE_MONO_CTX
        memset (&info->ctx, 0, sizeof (MonoContext));
+#ifdef TARGET_AMD64
+       info->ctx.rip = context.Rip;
+       info->ctx.rax = context.Rax;
+       info->ctx.rcx = context.Rcx;
+       info->ctx.rdx = context.Rdx;
+       info->ctx.rbx = context.Rbx;
+       info->ctx.rsp = context.Rsp;
+       info->ctx.rbp = context.Rbp;
+       info->ctx.rsi = context.Rsi;
+       info->ctx.rdi = context.Rdi;
+       info->ctx.r8 = context.R8;
+       info->ctx.r9 = context.R9;
+       info->ctx.r10 = context.R10;
+       info->ctx.r11 = context.R11;
+       info->ctx.r12 = context.R12;
+       info->ctx.r13 = context.R13;
+       info->ctx.r14 = context.R14;
+       info->ctx.r15 = context.R15;
+       info->stopped_ip = info->ctx.rip;
+       info->stack_start = (char*)info->ctx.rsp - REDZONE_SIZE;
+#else
        info->ctx.edi = context.Edi;
        info->ctx.esi = context.Esi;
        info->ctx.ebx = context.Ebx;
@@ -70,6 +88,10 @@ sgen_suspend_thread (SgenThreadInfo *info)
        info->ctx.eax = context.Eax;
        info->ctx.ebp = context.Ebp;
        info->ctx.esp = context.Esp;
+       info->stopped_ip = (gpointer)context.Eip;
+       info->stack_start = (char*)context.Esp - REDZONE_SIZE;
+#endif
+
 #else
        info->regs [0] = context.Edi;
        info->regs [1] = context.Esi;
@@ -79,6 +101,8 @@ sgen_suspend_thread (SgenThreadInfo *info)
        info->regs [5] = context.Eax;
        info->regs [6] = context.Ebp;
        info->regs [7] = context.Esp;
+       info->stopped_ip = (gpointer)context.Eip;
+       info->stack_start = (char*)context.Esp - REDZONE_SIZE;
 #endif
 
        /* Notify the JIT */
index 60feed2d372b96a3ccf7e1a6087e0d53b3e78868..c41df40339f927a4f140231ec7317e9f020a468c 100644 (file)
@@ -27,6 +27,7 @@
 #include "sgen-protocol.h"
 #include "sgen-memory-governor.h"
 #include "utils/mono-mmap.h"
+#include "utils/mono-threads.h"
 
 #ifdef SGEN_BINARY_PROTOCOL
 
@@ -180,6 +181,9 @@ protocol_entry (unsigned char type, gpointer data, int size)
        if (!binary_protocol_file)
                return;
 
+       if (sgen_is_worker_thread (mono_native_thread_id_get ()))
+               type |= 0x80;
+
        lock_recursive ();
 
  retry:
diff --git a/mono/metadata/sgen-qsort.c b/mono/metadata/sgen-qsort.c
new file mode 100644 (file)
index 0000000..4b57884
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * sgen-qsort.c: Quicksort.
+ *
+ * Copyright (C) 2013 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_SGEN_GC
+
+#include "metadata/sgen-gc.h"
+
+#define ELEM(i)                (((unsigned char*)base) + ((i) * width))
+#define SWAP(i,j)      do {                                    \
+               size_t __i = (i), __j = (j);                    \
+               if (__i != __j) {                               \
+                       memcpy (swap_tmp, ELEM (__i), width);   \
+                       memcpy (ELEM (__i), ELEM (__j), width); \
+                       memcpy (ELEM (__j), swap_tmp, width);   \
+               }                                               \
+       } while (0)
+
+static size_t
+partition (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*), unsigned char *pivot_tmp, unsigned char *swap_tmp)
+{
+       size_t pivot_idx = nel >> 1;
+       size_t s, i;
+
+       memcpy (pivot_tmp, ELEM (pivot_idx), width);
+       SWAP (pivot_idx, nel - 1);
+       s = 0;
+       for (i = 0; i < nel - 1; ++i) {
+               if (compar (ELEM (i), pivot_tmp) <= 0) {
+                       SWAP (i, s);
+                       ++s;
+               }
+       }
+       SWAP (s, nel - 1);
+       return s;
+}
+
+static void
+qsort_rec (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*), unsigned char *pivot_tmp, unsigned char *swap_tmp)
+{
+       size_t pivot_idx;
+
+       if (nel <= 1)
+               return;
+
+       pivot_idx = partition (base, nel, width, compar, pivot_tmp, swap_tmp);
+       qsort_rec (base, pivot_idx, width, compar, pivot_tmp, swap_tmp);
+       if (pivot_idx < nel)
+               qsort_rec (ELEM (pivot_idx + 1), nel - pivot_idx - 1, width, compar, pivot_tmp, swap_tmp);
+}
+
+void
+sgen_qsort (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*))
+{
+       unsigned char pivot_tmp [width];
+       unsigned char swap_tmp [width];
+
+       qsort_rec (base, nel, width, compar, pivot_tmp, swap_tmp);
+}
+
+#endif
index 0f52505544c9184fe56b7574180933df1e8b95e1..54dc218b5848891e22c00f495f5b6de8a3093926 100755 (executable)
@@ -277,7 +277,7 @@ sgen_restart_world (int generation, GGTimingInfo *timing)
         */
        release_gc_locks ();
 
-       mono_thread_hazardous_try_free_some ();
+       sgen_try_free_some_memory = TRUE;
 
        sgen_bridge_processing_finish (generation);
 
index 6509d091a9401bc753bab6b2dd1b5cfcb591dc39..145633f943585e969c37d9507460cfad1d255c52 100644 (file)
@@ -2234,12 +2234,15 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                                if(address) {
                                        mreq.imr_address = ipaddress_to_struct_in_addr (address);
                                }
+
+                               field = mono_class_get_field_from_name(obj_val->vtable->klass, "iface_index");
+                               mreq.imr_ifindex = *(gint32 *)(((char *)obj_val)+field->offset);
 #else
                                if(address) {
                                        mreq.imr_interface = ipaddress_to_struct_in_addr (address);
                                }
 #endif /* HAVE_STRUCT_IP_MREQN */
-                       
+
                                ret = _wapi_setsockopt (sock, system_level,
                                                        system_name, &mreq,
                                                        sizeof (mreq));
@@ -2278,6 +2281,23 @@ void ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal(SOCKET sock, g
                        linger.l_linger = 0;
                        ret = _wapi_setsockopt (sock, system_level, system_name, &linger, sizeof (linger));
                        break;
+               case SocketOptionName_MulticastInterface:
+#ifndef HOST_WIN32
+#ifdef HAVE_STRUCT_IP_MREQN
+                       int_val = GUINT32_FROM_BE (int_val);
+                       if ((int_val & 0xff000000) == 0) {
+                               /* int_val is interface index */
+                               struct ip_mreqn mreq = {{0}};
+                               mreq.imr_ifindex = int_val;
+                               ret = _wapi_setsockopt (sock, system_level, system_name, (char *) &mreq, sizeof (mreq));
+                               break;
+                       }
+                       int_val = GUINT32_TO_BE (int_val);
+#endif /* HAVE_STRUCT_IP_MREQN */
+#endif /* HOST_WIN32 */
+                       /* int_val is in_addr */
+                       ret = _wapi_setsockopt (sock, system_level, system_name, (char *) &int_val, sizeof (int_val));
+                       break;
                case SocketOptionName_DontFragment:
 #ifdef HAVE_IP_MTU_DISCOVER
                        /* Fiddle with the value slightly if we're
diff --git a/mono/metadata/test-gc-memfuncs.c b/mono/metadata/test-gc-memfuncs.c
new file mode 100644 (file)
index 0000000..385b4e3
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ * test-sgen-qsort.c: Unit test for our own bzero/memmove.
+ *
+ * Copyright (C) 2013 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+
+#include "metadata/gc-internal.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+
+#define POOL_SIZE      2048
+#define START_OFFSET   128
+
+#define BZERO_OFFSETS  64
+#define BZERO_SIZES    256
+
+#define MEMMOVE_SRC_OFFSETS            32
+#define MEMMOVE_DEST_OFFSETS           32
+#define MEMMOVE_SIZES                  256
+#define MEMMOVE_NONOVERLAP_START       1024
+
+int
+main (void)
+{
+       unsigned char *random_mem = malloc (POOL_SIZE);
+       unsigned char *reference = malloc (POOL_SIZE);
+       unsigned char *playground = malloc (POOL_SIZE);
+       long *long_random_mem;
+       int i, offset, size, src_offset, dest_offset;
+
+       srandom (time (NULL));
+
+       /* init random memory */
+       long_random_mem = (long*)random_mem;
+       for (i = 0; i < POOL_SIZE / sizeof (long); ++i)
+               long_random_mem [i] = random ();
+
+       /* test bzero */
+       for (offset = 0; offset <= BZERO_OFFSETS; ++offset) {
+               for (size = 0; size <= BZERO_SIZES; ++size) {
+                       memcpy (reference, random_mem, POOL_SIZE);
+                       memcpy (playground, random_mem, POOL_SIZE);
+
+                       bzero (reference + START_OFFSET + offset, size);
+                       mono_gc_bzero (playground + START_OFFSET + offset, size);
+
+                       assert (!memcmp (reference, playground, POOL_SIZE));
+               }
+       }
+
+       /* test memmove */
+       for (src_offset = -MEMMOVE_SRC_OFFSETS; src_offset <= MEMMOVE_SRC_OFFSETS; ++src_offset) {
+               for (dest_offset = -MEMMOVE_DEST_OFFSETS; dest_offset <= MEMMOVE_DEST_OFFSETS; ++dest_offset) {
+                       for (size = 0; size <= MEMMOVE_SIZES; ++size) {
+                               /* overlapping */
+                               memcpy (reference, random_mem, POOL_SIZE);
+                               memcpy (playground, random_mem, POOL_SIZE);
+
+                               memmove (reference + START_OFFSET + dest_offset, reference + START_OFFSET + src_offset, size);
+                               mono_gc_memmove (playground + START_OFFSET + dest_offset, playground + START_OFFSET + src_offset, size);
+
+                               assert (!memcmp (reference, playground, POOL_SIZE));
+
+                               /* non-overlapping with dest < src */
+                               memcpy (reference, random_mem, POOL_SIZE);
+                               memcpy (playground, random_mem, POOL_SIZE);
+
+                               memmove (reference + START_OFFSET + dest_offset, reference + MEMMOVE_NONOVERLAP_START + src_offset, size);
+                               mono_gc_memmove (playground + START_OFFSET + dest_offset, playground + MEMMOVE_NONOVERLAP_START + src_offset, size);
+
+                               assert (!memcmp (reference, playground, POOL_SIZE));
+
+                               /* non-overlapping with dest > src */
+                               memcpy (reference, random_mem, POOL_SIZE);
+                               memcpy (playground, random_mem, POOL_SIZE);
+
+                               memmove (reference + MEMMOVE_NONOVERLAP_START + dest_offset, reference + START_OFFSET + src_offset, size);
+                               mono_gc_memmove (playground + MEMMOVE_NONOVERLAP_START + dest_offset, playground + START_OFFSET + src_offset, size);
+
+                               assert (!memcmp (reference, playground, POOL_SIZE));
+                       }
+               }
+       }
+
+       return 0;
+}
diff --git a/mono/metadata/test-sgen-qsort.c b/mono/metadata/test-sgen-qsort.c
new file mode 100644 (file)
index 0000000..4a75ea2
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+ * test-sgen-qsort.c: Unit test for quicksort.
+ *
+ * Copyright (C) 2013 Xamarin Inc
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License 2.0 as published by the Free Software Foundation;
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License 2.0 along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "config.h"
+
+#include "metadata/sgen-gc.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include <assert.h>
+
+static int
+compare_ints (const void *pa, const void *pb)
+{
+       int a = *(const int*)pa;
+       int b = *(const int*)pb;
+       if (a < b)
+               return -1;
+       if (a == b)
+               return 0;
+       return 1;
+}
+
+typedef struct {
+       int key;
+       int val;
+} teststruct_t;
+
+static int
+compare_teststructs (const void *pa, const void *pb)
+{
+       int a = ((const teststruct_t*)pa)->key;
+       int b = ((const teststruct_t*)pb)->key;
+       if (a < b)
+               return -1;
+       if (a == b)
+               return 0;
+       return 1;
+}
+
+static void
+compare_sorts (void *base, size_t nel, size_t width, int (*compar) (const void*, const void*))
+{
+       size_t len = nel * width;
+       void *b1 = malloc (len);
+       void *b2 = malloc (len);
+
+       memcpy (b1, base, len);
+       memcpy (b2, base, len);
+
+       qsort (b1, nel, width, compar);
+       sgen_qsort (b2, nel, width, compar);
+
+       assert (!memcmp (b1, b2, len));
+
+       free (b1);
+       free (b2);
+}
+
+int
+main (void)
+{
+       int i;
+       for (i = 0; i < 4000; ++i) {
+               int a [i];
+               int j;
+
+               for (j = 0; j < i; ++j)
+                       a [j] = i - j - 1;
+               compare_sorts (a, i, sizeof (int), compare_ints);
+       }
+
+       srandom (time (NULL));
+       for (i = 0; i < 2000; ++i) {
+               teststruct_t a [200];
+               int j;
+               for (j = 0; j < 200; ++j) {
+                       a [j].key = random ();
+                       a [j].val = random ();
+               }
+
+               compare_sorts (a, 200, sizeof (teststruct_t), compare_teststructs);
+       }
+
+       return 0;
+}
index 81f8b5c7b0f507e6c9aba705e96023a77b11fe0f..cb247800e39889d51401bed6322e68a91f1bb22e 100755 (executable)
@@ -811,9 +811,8 @@ mono_thread_create (MonoDomain *domain, gpointer func, gpointer arg)
        mono_thread_create_internal (domain, func, arg, FALSE, FALSE, 0);
 }
 
-#if defined(HOST_WIN32) && defined(__GNUC__)
+#if defined(HOST_WIN32) && HAVE_DECL___READFSDWORD==0
 static __inline__ __attribute__((always_inline))
-/* This is not defined by gcc */
 unsigned long long
 __readfsdword (unsigned long offset)
 {
@@ -850,6 +849,17 @@ mono_thread_get_stack_bounds (guint8 **staddr, size_t *stsize)
        *staddr = (guint8*)pthread_get_stackaddr_np (pthread_self());
        *stsize = pthread_get_stacksize_np (pthread_self());
 
+
+#ifdef TARGET_OSX
+       /*
+        * Mavericks reports stack sizes as 512kb:
+        * http://permalink.gmane.org/gmane.comp.java.openjdk.hotspot.devel/11590
+        * https://bugs.openjdk.java.net/browse/JDK-8020753
+        */
+       if (*stsize == 512 * 1024)
+               *stsize = 2048 * mono_pagesize ();
+#endif
+
        /* staddr points to the start of the stack, not the end */
        *staddr -= *stsize;
 
@@ -1790,6 +1800,16 @@ gint32 ves_icall_System_Threading_Interlocked_Increment_Int (gint32 *location)
 
 gint64 ves_icall_System_Threading_Interlocked_Increment_Long (gint64 *location)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)location & 0x7)) {
+               gint64 ret;
+               mono_interlocked_lock ();
+               (*location)++;
+               ret = *location;
+               mono_interlocked_unlock ();
+               return ret;
+       }
+#endif
        return InterlockedIncrement64 (location);
 }
 
@@ -1800,6 +1820,16 @@ gint32 ves_icall_System_Threading_Interlocked_Decrement_Int (gint32 *location)
 
 gint64 ves_icall_System_Threading_Interlocked_Decrement_Long (gint64 * location)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)location & 0x7)) {
+               gint64 ret;
+               mono_interlocked_lock ();
+               (*location)--;
+               ret = *location;
+               mono_interlocked_unlock ();
+               return ret;
+       }
+#endif
        return InterlockedDecrement64 (location);
 }
 
@@ -1834,6 +1864,16 @@ gfloat ves_icall_System_Threading_Interlocked_Exchange_Single (gfloat *location,
 gint64 
 ves_icall_System_Threading_Interlocked_Exchange_Long (gint64 *location, gint64 value)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)location & 0x7)) {
+               gint64 ret;
+               mono_interlocked_lock ();
+               ret = *location;
+               *location = value;
+               mono_interlocked_unlock ();
+               return ret;
+       }
+#endif
        return InterlockedExchange64 (location, value);
 }
 
@@ -1905,7 +1945,7 @@ gint64
 ves_icall_System_Threading_Interlocked_CompareExchange_Long (gint64 *location, gint64 value, gint64 comparand)
 {
 #if SIZEOF_VOID_P == 4
-       if ((size_t)location & 0x7) {
+       if (G_UNLIKELY ((size_t)location & 0x7)) {
                gint64 old;
                mono_interlocked_lock ();
                old = *location;
@@ -1945,12 +1985,31 @@ ves_icall_System_Threading_Interlocked_Add_Int (gint32 *location, gint32 value)
 gint64 
 ves_icall_System_Threading_Interlocked_Add_Long (gint64 *location, gint64 value)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)location & 0x7)) {
+               gint64 ret;
+               mono_interlocked_lock ();
+               *location += value;
+               ret = *location;
+               mono_interlocked_unlock ();
+               return ret;
+       }
+#endif
        return InterlockedAdd64 (location, value);
 }
 
 gint64 
 ves_icall_System_Threading_Interlocked_Read_Long (gint64 *location)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)location & 0x7)) {
+               gint64 ret;
+               mono_interlocked_lock ();
+               ret = *location;
+               mono_interlocked_unlock ();
+               return ret;
+       }
+#endif
        return InterlockedRead64 (location);
 }
 
@@ -2030,8 +2089,6 @@ void mono_thread_current_check_pending_interrupt ()
        MonoInternalThread *thread = mono_thread_internal_current ();
        gboolean throw = FALSE;
 
-       mono_debugger_check_interruption ();
-
        ensure_synch_cs_set (thread);
        
        EnterCriticalSection (thread->synch_cs);
@@ -2466,6 +2523,15 @@ ves_icall_System_Threading_Volatile_Read4 (void *ptr)
 gint64
 ves_icall_System_Threading_Volatile_Read8 (void *ptr)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)ptr & 0x7)) {
+               gint64 val;
+               mono_interlocked_lock ();
+               val = *(gint64*)ptr;
+               mono_interlocked_unlock ();
+               return val;
+       }
+#endif
        return InterlockedRead64 (ptr);
 }
 
@@ -2480,6 +2546,16 @@ ves_icall_System_Threading_Volatile_ReadDouble (void *ptr)
 {
        LongDoubleUnion u;
 
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)ptr & 0x7)) {
+               double val;
+               mono_interlocked_lock ();
+               val = *(double*)ptr;
+               mono_interlocked_unlock ();
+               return val;
+       }
+#endif
+
        u.ival = InterlockedRead64 (ptr);
 
        return u.fval;
@@ -2570,6 +2646,15 @@ ves_icall_System_Threading_Volatile_Write4 (void *ptr, gint32 value)
 void
 ves_icall_System_Threading_Volatile_Write8 (void *ptr, gint64 value)
 {
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)ptr & 0x7)) {
+               mono_interlocked_lock ();
+               *(gint64*)ptr = value;
+               mono_interlocked_unlock ();
+               return;
+       }
+#endif
+
        InterlockedWrite64 (ptr, value);
 }
 
@@ -2584,6 +2669,15 @@ ves_icall_System_Threading_Volatile_WriteDouble (void *ptr, double value)
 {
        LongDoubleUnion u;
 
+#if SIZEOF_VOID_P == 4
+       if (G_UNLIKELY ((size_t)ptr & 0x7)) {
+               mono_interlocked_lock ();
+               *(double*)ptr = value;
+               mono_interlocked_unlock ();
+               return;
+       }
+#endif
+
        u.fval = value;
 
        InterlockedWrite64 (ptr, u.ival);
@@ -4312,8 +4406,6 @@ static void mono_thread_interruption_checkpoint_request (gboolean bypass_abort_p
        if (thread == NULL)
                return;
 
-       mono_debugger_check_interruption ();
-
        if (thread->interruption_requested && (bypass_abort_protection || !is_running_protected_wrapper ())) {
                MonoException* exc = mono_thread_execute_interruption (thread);
                if (exc) mono_raise_exception (exc);
index 6d694bc2957dfc692be3108bf3c3aeb5b2c53528..41c6df3c8e3af8b6466440d73ef529fd102e8c66 100644 (file)
@@ -2,6 +2,7 @@
 /Makefile.in
 /Makefile.am
 /*.o
+/*.g.c
 /*.so
 /*.exe
 /*.dll
index 1aaf8ed95fa03bcc844bef4e1552d3c66f48d700..8be85bc538898e693ef880940239249f9e678f99 100755 (executable)
@@ -162,7 +162,7 @@ libmono_llvm_la_LIBADD = $(LLVM_LIBS) $(LLVM_LDFLAGS)
 if PLATFORM_DARWIN
 libmono_llvm_la_LDFLAGS=-Wl,-undefined -Wl,suppress -Wl,-flat_namespace
 else
-libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmono-$(API_VER).la $(libs)
+libmono_llvm_la_LIBADD += $(top_builddir)/mono/mini/libmonoboehm-$(API_VER).la $(libs)
 endif
 endif
 
@@ -389,7 +389,6 @@ common_sources = \
        local-propagation.c     \
        driver.c                \
        debug-mini.c            \
-       debug-mini.h            \
        linear-scan.c           \
        aot-compiler.c          \
        aot-runtime.c           \
@@ -417,11 +416,10 @@ common_sources = \
        mini-gc.c               \
        debugger-agent.h        \
        debugger-agent.c        \
-       debug-debugger.c        \
-       debug-debugger.h        \
        xdebug.c                        \
        mini-llvm.h                     \
-       mini-llvm-cpp.h
+       mini-llvm-cpp.h \
+       alias-analysis.c
 
 test_sources =                         \
        basic-calls.cs          \
@@ -450,26 +448,13 @@ regtests += nacl.exe
 endif
 
 if X86
-if MONO_DEBUGGER_SUPPORTED
-if PLATFORM_DARWIN
-mdb_x86 = mdb-debug-info32-darwin.s
-else
-mdb_x86 = mdb-debug-info32.s
-endif
-else
-mdb_x86 = 
-endif
-arch_sources = $(x86_sources) $(mdb_x86)
+arch_sources = $(x86_sources)
 arch_built=cpu-x86.h
 arch_define=__i386__
 endif
 
 if AMD64
-if MONO_DEBUGGER_SUPPORTED
-arch_sources = $(amd64_sources) mdb-debug-info64.s
-else
 arch_sources = $(amd64_sources)
-endif
 arch_built=cpu-amd64.h
 arch_define=__x86_64__
 endif
index 8a9349d293d1467718f93e1796c44f2b8c005307..843f7c3b77d1943bdaae9e9a4eb8caf4e553aae3 100644 (file)
@@ -989,8 +989,8 @@ remove_abc_from_inst (MonoInst *ins, MonoVariableRelationsEvaluationArea *area)
                if (REPORT_ABC_REMOVAL) {
                        printf ("ARRAY-ACCESS: removed bounds check on array %d with index %d\n",
                                        array_variable, index_variable);
-                       NULLIFY_INS (ins);
                }
+               NULLIFY_INS (ins);
        } else {
                if (TRACE_ABC_REMOVAL) {
                        if (index_context->ranges.zero.lower >= 0) {
diff --git a/mono/mini/alias-analysis.c b/mono/mini/alias-analysis.c
new file mode 100644 (file)
index 0000000..ef16442
--- /dev/null
@@ -0,0 +1,335 @@
+/*
+ * alias-analysis.c: Implement simple alias analysis for local variables.
+ *
+ * Author:
+ *   Rodrigo Kumpera (kumpera@gmail.com)
+ *
+ * (C) 2013 Xamarin
+ */
+
+#include <config.h>
+#include <stdio.h>
+
+#include "mini.h"
+#include "ir-emit.h"
+#include "glib.h"
+
+static gboolean
+is_int_stack_size (int type)
+{
+#if SIZEOF_VOID_P == 4
+       return type == STACK_I4 || type == STACK_MP;
+#else
+       return type == STACK_I4;
+#endif
+}
+
+static gboolean
+is_long_stack_size (int type)
+{
+#if SIZEOF_VOID_P == 8
+       return type == STACK_I8 || type == STACK_MP;
+#else
+       return type == STACK_I8;
+#endif
+}
+
+
+static gboolean
+lower_load (MonoCompile *cfg, MonoInst *load, MonoInst *ldaddr)
+{
+       MonoInst *var = ldaddr->inst_p0;
+       MonoType *type = &var->klass->byval_arg;
+       int replaced_op = mono_type_to_load_membase (cfg, type);
+
+       if (load->opcode == OP_LOADV_MEMBASE && load->klass != var->klass) {
+               if (cfg->verbose_level > 2)
+                       printf ("Incompatible load_vtype classes %s x %s\n", load->klass->name, var->klass->name);
+               return FALSE;
+       }
+
+       if (replaced_op != load->opcode) {
+               if (cfg->verbose_level > 2) 
+                       printf ("Incompatible load type: expected %s but got %s\n", 
+                               mono_inst_name (replaced_op),
+                               mono_inst_name (load->opcode));
+               return FALSE;
+       } else {
+               if (cfg->verbose_level > 2) { printf ("mem2reg replacing: "); mono_print_ins (load); }
+       }
+
+       load->opcode = mono_type_to_regmove (cfg, type);
+       type_to_eval_stack_type (cfg, type, load);
+       load->sreg1 = var->dreg;
+       mono_jit_stats.loads_eliminated++;
+       return TRUE;
+}
+
+static gboolean
+lower_store (MonoCompile *cfg, MonoInst *store, MonoInst *ldaddr)
+{
+       MonoInst *var = ldaddr->inst_p0;
+       MonoType *type = &var->klass->byval_arg;
+       int replaced_op = mono_type_to_store_membase (cfg, type);
+
+       if (store->opcode == OP_STOREV_MEMBASE && store->klass != var->klass) {
+               if (cfg->verbose_level > 2)
+                       printf ("Incompatible store_vtype classes %s x %s\n", store->klass->name, store->klass->name);
+               return FALSE;
+       }
+
+
+       if (replaced_op != store->opcode) {
+               if (cfg->verbose_level > 2) 
+                       printf ("Incompatible store_reg type: expected %s but got %s\n", 
+                               mono_inst_name (replaced_op),
+                               mono_inst_name (store->opcode));
+               return FALSE;
+       } else {
+               if (cfg->verbose_level > 2) { printf ("mem2reg replacing: "); mono_print_ins (store); }
+       }
+
+       store->opcode = mono_type_to_regmove (cfg, type);
+       type_to_eval_stack_type (cfg, type, store);
+       store->dreg = var->dreg;
+       mono_jit_stats.stores_eliminated++;
+       return TRUE;
+}
+
+static gboolean
+lower_store_imm (MonoCompile *cfg, MonoInst *store, MonoInst *ldaddr)
+{
+       MonoInst *var = ldaddr->inst_p0;
+       MonoType *type = &var->klass->byval_arg;
+       int store_op = mono_type_to_store_membase (cfg, type);
+       if (store_op == OP_STOREV_MEMBASE || store_op == OP_STOREX_MEMBASE)
+               return FALSE;
+
+       switch (store->opcode) {
+#if SIZEOF_VOID_P == 4
+       case OP_STORE_MEMBASE_IMM:
+#endif
+       case OP_STOREI4_MEMBASE_IMM:
+               if (!is_int_stack_size (var->type)) {
+                       if (cfg->verbose_level > 2) printf ("Incompatible variable of size != 4\n");
+                       return FALSE;
+               }
+               if (cfg->verbose_level > 2) { printf ("mem2reg replacing: "); mono_print_ins (store); }
+               store->opcode = OP_ICONST;
+               store->type = STACK_I4;
+               store->dreg = var->dreg;
+               store->inst_c0 = store->inst_imm;
+               break;
+
+#if SIZEOF_VOID_P == 8
+       case OP_STORE_MEMBASE_IMM:
+#endif    
+       case OP_STOREI8_MEMBASE_IMM:
+               if (!is_long_stack_size (var->type)) {
+                       if (cfg->verbose_level > 2) printf ("Incompatible variable of size != 8\n");
+                       return FALSE;
+               }
+               if (cfg->verbose_level > 2) { printf ("mem2reg replacing: "); mono_print_ins (store); }
+               store->opcode = OP_I8CONST;
+               store->type = STACK_I8;
+               store->dreg = var->dreg;
+               store->inst_l = store->inst_imm;
+               break;
+       default:
+               return FALSE;
+       }
+       mono_jit_stats.stores_eliminated++;     
+       return TRUE;
+}
+
+static gboolean
+lower_memory_access (MonoCompile *cfg)
+{
+       MonoBasicBlock *bb;
+       MonoInst *ins, *tmp;
+       gboolean needs_dce = FALSE;
+       GHashTable *addr_loads = g_hash_table_new (NULL, NULL);
+       //FIXME optimize
+       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+               g_hash_table_remove_all (addr_loads);
+
+               for (ins = bb->code; ins; ins = ins->next) {
+                       switch (ins->opcode) {
+                       case OP_LDADDR:
+                               g_hash_table_insert (addr_loads, GINT_TO_POINTER (ins->dreg), ins);
+                               if (cfg->verbose_level > 2) { printf ("New address: "); mono_print_ins (ins); }
+                               break;
+                       case OP_MOVE:
+                               tmp = (MonoInst*)g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->sreg1));
+                               /*
+                               Forward propagate known aliases
+                               ldaddr R10 <- R8
+                               mov R11 <- R10
+                               */
+                               if (tmp) {
+                                       g_hash_table_insert (addr_loads, GINT_TO_POINTER (ins->dreg), tmp);
+                                       if (cfg->verbose_level > 2) { printf ("New alias: "); mono_print_ins (ins); }
+                               } else {
+                                       /*
+                                       Source value is not a know address, kill the variable.
+                                       */
+                                       if (g_hash_table_remove (addr_loads, GINT_TO_POINTER (ins->dreg))) {
+                                               if (cfg->verbose_level > 2) { printf ("Killed alias: "); mono_print_ins (ins); }
+                                       }
+                               }
+                               break;
+
+                       case OP_LOADV_MEMBASE:
+                       case OP_LOAD_MEMBASE:
+                       case OP_LOADU1_MEMBASE:
+                       case OP_LOADI2_MEMBASE:
+                       case OP_LOADU2_MEMBASE:
+                       case OP_LOADI4_MEMBASE:
+                       case OP_LOADU4_MEMBASE:
+                       case OP_LOADI1_MEMBASE:
+                       case OP_LOADI8_MEMBASE:
+                       case OP_LOADR4_MEMBASE:
+                       case OP_LOADR8_MEMBASE:
+                               if (ins->inst_offset != 0)
+                                       continue;
+                               tmp = g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->sreg1));
+                               if (tmp) {
+                                       if (cfg->verbose_level > 2) { printf ("Found candidate load:"); mono_print_ins (ins); }
+                                       needs_dce |= lower_load (cfg, ins, tmp);
+                               }
+                               break;
+
+                       case OP_STORE_MEMBASE_REG:
+                       case OP_STOREI1_MEMBASE_REG:
+                       case OP_STOREI2_MEMBASE_REG:
+                       case OP_STOREI4_MEMBASE_REG:
+                       case OP_STOREI8_MEMBASE_REG:
+                       case OP_STORER4_MEMBASE_REG:
+                       case OP_STORER8_MEMBASE_REG:
+                       case OP_STOREV_MEMBASE:
+                               if (ins->inst_offset != 0)
+                                       continue;
+                               tmp = g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->dreg));
+                               if (tmp) {
+                                       if (cfg->verbose_level > 2) { printf ("Found candidate store:"); mono_print_ins (ins); }
+                                       needs_dce |= lower_store (cfg, ins, tmp);
+                               }
+                               break;
+
+                       case OP_STORE_MEMBASE_IMM:
+                       case OP_STOREI4_MEMBASE_IMM:
+                       case OP_STOREI8_MEMBASE_IMM:
+                               if (ins->inst_offset != 0)
+                                       continue;
+                               tmp = g_hash_table_lookup (addr_loads, GINT_TO_POINTER (ins->dreg));
+                               if (tmp) {
+                                       if (cfg->verbose_level > 2) { printf ("Found candidate store-imm:"); mono_print_ins (ins); }
+                                       needs_dce |= lower_store_imm (cfg, ins, tmp);
+                               }
+                               break;
+                       }
+               }
+       }
+       g_hash_table_destroy (addr_loads);
+       return needs_dce;
+}
+
+static gboolean
+recompute_aliased_variables (MonoCompile *cfg)
+{
+       int i;
+       MonoBasicBlock *bb;
+       MonoInst *ins;
+       int kills = 0;
+       int adds = 0;
+
+       for (i = 0; i < cfg->num_varinfo; i++) {
+               MonoInst *var = cfg->varinfo [i];
+               if (var->flags & MONO_INST_INDIRECT) {
+                       if (cfg->verbose_level > 2) {
+                               printf ("Killing :"); mono_print_ins (var);
+                       }
+                       ++kills;
+               }
+               var->flags &= ~MONO_INST_INDIRECT;
+       }
+
+       if (!kills)
+               return FALSE;
+
+       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+               for (ins = bb->code; ins; ins = ins->next) {
+                       if (ins->opcode == OP_LDADDR) {
+                               MonoInst *var;
+
+                               if (cfg->verbose_level > 2) { printf ("Found op :"); mono_print_ins (ins); }
+
+                               var = (MonoInst*)ins->inst_p0;
+                               if (!(var->flags & MONO_INST_INDIRECT)) {
+                                       if (cfg->verbose_level) { printf ("Restoring :"); mono_print_ins (var); }
+                                       ++adds;
+                               }
+                               var->flags |= MONO_INST_INDIRECT;
+                       }
+               }
+       }
+       
+       mono_jit_stats.alias_found += kills;
+       mono_jit_stats.alias_removed += kills - adds;
+       if (kills > adds) {
+               if (cfg->verbose_level > 2) {
+                       printf ("Method: %s\n", mono_method_full_name (cfg->method, 1));
+                       printf ("Kills %d Adds %d\n", kills, adds);
+               }
+               return TRUE;
+       }
+       return FALSE;
+}
+
+/*
+FIXME:
+       Don't DCE on the whole CFG, only the BBs that have changed.
+
+TODO:
+       SRVT of small types can fix cases of mismatch for fields of a different type than the component.
+       Handle aliasing of byrefs in call conventions.
+*/
+void
+mono_local_alias_analysis (MonoCompile *cfg)
+{
+       if (!cfg->has_indirection)
+               return;
+
+       if (cfg->verbose_level > 2)
+               mono_print_code (cfg, "BEFORE ALIAS_ANALYSIS");
+
+       /*
+       Remove indirection and memory access of known variables.
+       */
+       if (!lower_memory_access (cfg))
+               goto done;
+
+       /*
+       By replacing indirect access with direct operations, some LDADDR ops become dead. Kill them.
+       */
+       if (cfg->opt & MONO_OPT_DEADCE)
+               mono_local_deadce (cfg);
+
+       /*
+       Some variables no longer need to be flagged as indirect, find them.
+       */
+       if (!recompute_aliased_variables (cfg))
+               goto done;
+
+       /*
+       A lot of simplification just took place, we recompute local variables and do DCE to
+       really profit from the previous gains
+       */
+       mono_handle_global_vregs (cfg);
+       if (cfg->opt & MONO_OPT_DEADCE)
+               mono_local_deadce (cfg);
+
+done:
+       if (cfg->verbose_level > 2)
+               mono_print_code (cfg, "AFTER ALIAS_ANALYSIS");
+}
index 849ed2de49c314907a3fa4e2ba98e8a4e3d42a59..7f0ec1ccea17fb85c8094dad8e3bf77ff66f79f2 100755 (executable)
@@ -165,7 +165,7 @@ typedef struct MonoAotCompile {
        GHashTable *method_depth;
        MonoCompile **cfgs;
        int cfgs_size;
-       GHashTable *patch_to_plt_entry;
+       GHashTable **patch_to_plt_entry;
        GHashTable *plt_offset_to_entry;
        GHashTable *patch_to_got_offset;
        GHashTable **patch_to_got_offset_by_type;
@@ -188,10 +188,12 @@ typedef struct MonoAotCompile {
        guint32 final_got_size;
        /* Number of GOT entries reserved for trampolines */
        guint32 num_trampoline_got_entries;
+       guint32 tramp_page_size;
 
        guint32 num_trampolines [MONO_AOT_TRAMP_NUM];
        guint32 trampoline_got_offset_base [MONO_AOT_TRAMP_NUM];
        guint32 trampoline_size [MONO_AOT_TRAMP_NUM];
+       guint32 tramp_page_code_offsets [MONO_AOT_TRAMP_NUM];
 
        MonoAotOptions aot_opts;
        guint32 nmethods;
@@ -207,6 +209,7 @@ typedef struct MonoAotCompile {
        MonoImageWriter *w;
        MonoDwarfWriter *dwarf;
        FILE *fp;
+       char *tmpbasename;
        char *tmpfname;
        GSList *cie_program;
        GHashTable *unwind_info_offsets;
@@ -215,6 +218,7 @@ typedef struct MonoAotCompile {
        char *got_symbol_base;
        char *got_symbol;
        char *plt_symbol;
+       char *methods_symbol;
        GHashTable *method_label_hash;
        const char *temp_prefix;
        const char *user_symbol_prefix;
@@ -635,11 +639,6 @@ arch_init (MonoAotCompile *acfg)
        acfg->llvm_label_prefix = "";
        acfg->user_symbol_prefix = "";
 
-#if defined(TARGET_AMD64) && defined(TARGET_MACH)
-       /* osx contains an old as which doesn't support avx opcodes */
-       g_string_append (acfg->llc_args, "-mattr=-avx");
-#endif
-
 #if defined(TARGET_AMD64)
        g_string_append (acfg->llc_args, " -march=x86-64");
 #endif
@@ -686,7 +685,7 @@ arch_init (MonoAotCompile *acfg)
  * calling code.
  */
 static void
-arch_emit_direct_call (MonoAotCompile *acfg, const char *target, gboolean external, int *call_size)
+arch_emit_direct_call (MonoAotCompile *acfg, const char *target, gboolean external, MonoJumpInfo *ji, int *call_size)
 {
 #if defined(TARGET_X86) || defined(TARGET_AMD64)
        /* Need to make sure this is exactly 5 bytes long */
@@ -1034,6 +1033,8 @@ arch_emit_specific_trampoline_pages (MonoAotCompile *acfg)
        if (!acfg->aot_opts.use_trampolines_page)
                return;
 
+       acfg->tramp_page_size = mono_pagesize ();
+
        sprintf (symbol, "%sspecific_trampolines_page", acfg->user_symbol_prefix);
        emit_alignment (acfg, mono_pagesize ());
        emit_global (acfg, symbol, TRUE);
@@ -2905,7 +2906,9 @@ get_plt_entry (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
        if (!is_plt_patch (patch_info))
                return NULL;
 
-       res = g_hash_table_lookup (acfg->patch_to_plt_entry, patch_info);
+       if (!acfg->patch_to_plt_entry [patch_info->type])
+               acfg->patch_to_plt_entry [patch_info->type] = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
+       res = g_hash_table_lookup (acfg->patch_to_plt_entry [patch_info->type], patch_info);
 
        // FIXME: This breaks the calculation of final_got_size         
        if (!acfg->llvm && patch_info->type == MONO_PATCH_INFO_METHOD && (patch_info->data.method->iflags & METHOD_IMPL_ATTRIBUTE_SYNCHRONIZED)) {
@@ -2935,7 +2938,7 @@ get_plt_entry (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
                else
                        res->llvm_symbol = g_strdup_printf ("%s_llvm", res->symbol);
 
-               g_hash_table_insert (acfg->patch_to_plt_entry, new_ji, res);
+               g_hash_table_insert (acfg->patch_to_plt_entry [new_ji->type], new_ji, res);
 
                g_hash_table_insert (acfg->plt_offset_to_entry, GUINT_TO_POINTER (res->plt_offset), res);
 
@@ -3405,7 +3408,7 @@ add_wrappers (MonoAotCompile *acfg)
 #endif
 
                /* JIT icall wrappers */
-               /* FIXME: locking */
+               /* FIXME: locking - this is "safe" as full-AOT threads don't mutate the icall hash*/
                g_hash_table_foreach (mono_get_jit_icall_info (), add_jit_icall_wrapper, acfg);
        }
 
@@ -4646,7 +4649,7 @@ emit_and_reloc_code (MonoAotCompile *acfg, MonoMethod *method, guint8 *code, gui
                                if (direct_call) {
                                        int call_size;
 
-                                       arch_emit_direct_call (acfg, direct_call_target, external_call, &call_size);
+                                       arch_emit_direct_call (acfg, direct_call_target, external_call, patch_info, &call_size);
                                        i += call_size - 1;
                                } else {
                                        int code_size;
@@ -4860,6 +4863,7 @@ encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info, guint8 *buf, guint
        case MONO_PATCH_INFO_METHOD_JUMP:
        case MONO_PATCH_INFO_ICALL_ADDR:
        case MONO_PATCH_INFO_METHOD_RGCTX:
+       case MONO_PATCH_INFO_METHOD_CODE_SLOT:
                encode_method_ref (acfg, patch_info->data.method, p, &p);
                break;
        case MONO_PATCH_INFO_INTERNAL_METHOD:
@@ -5187,12 +5191,10 @@ emit_exception_debug_info (MonoAotCompile *acfg, MonoCompile *cfg)
 
        seq_points = cfg->seq_point_info;
 
-       buf_size = header->num_clauses * 256 + debug_info_size + 2048 + (seq_points ? (seq_points->len * 64) : 0) + cfg->gc_map_size;
+       buf_size = header->num_clauses * 256 + debug_info_size + 2048 + (seq_points ? (seq_points->len * 128) : 0) + cfg->gc_map_size;
        p = buf = g_malloc (buf_size);
 
-#ifdef MONO_ARCH_HAVE_XP_UNWIND
        use_unwind_ops = cfg->unwind_ops != NULL;
-#endif
 
        flags = (jinfo->has_generic_jit_info ? 1 : 0) | (use_unwind_ops ? 2 : 0) | (header->num_clauses ? 4 : 0) | (seq_points ? 8 : 0) | (cfg->compile_llvm ? 16 : 0) | (jinfo->has_try_block_holes ? 32 : 0) | (cfg->gc_map ? 64 : 0) | (jinfo->has_arch_eh_info ? 128 : 0);
 
@@ -5734,6 +5736,8 @@ emit_trampoline_full (MonoAotCompile *acfg, int got_offset, MonoTrampInfo *info,
        MonoJumpInfo *ji;
        GSList *unwind_ops;
 
+       g_assert (info);
+
        name = info->name;
        code = info->code;
        code_size = info->code_size;
@@ -6048,6 +6052,7 @@ emit_trampolines (MonoAotCompile *acfg)
                        }
 
                        emit_label (acfg, end_symbol);
+                       emit_int32 (acfg, 0);
                }
 
                arch_emit_specific_trampoline_pages (acfg);
@@ -6353,7 +6358,8 @@ can_encode_patch (MonoAotCompile *acfg, MonoJumpInfo *patch_info)
 {
        switch (patch_info->type) {
        case MONO_PATCH_INFO_METHOD:
-       case MONO_PATCH_INFO_METHODCONST: {
+       case MONO_PATCH_INFO_METHODCONST:
+       case MONO_PATCH_INFO_METHOD_CODE_SLOT: {
                MonoMethod *method = patch_info->data.method;
 
                return can_encode_method (acfg, method);
@@ -6909,7 +6915,7 @@ emit_llvm_file (MonoAotCompile *acfg)
        }
 
 
-       tempbc = g_strdup_printf ("%s.bc", acfg->tmpfname);
+       tempbc = g_strdup_printf ("%s.bc", acfg->tmpbasename);
        mono_llvm_emit_aot_module (tempbc, acfg->final_got_size);
        g_free (tempbc);
 
@@ -6925,12 +6931,14 @@ emit_llvm_file (MonoAotCompile *acfg)
         * - 'prune-eh' and 'functionattrs' depend on 'basiccg'.
         * The opt list below was produced by taking the output of:
         * llvm-as < /dev/null | opt -O2 -disable-output -debug-pass=Arguments
-        * then removing tailcallelim + the global opts, and adding a second gvn.
+        * then removing tailcallelim + the global opts.
+        * strip-dead-prototypes deletes unused intrinsics definitions.
         */
        opts = g_strdup ("-instcombine -simplifycfg");
-       opts = g_strdup ("-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -simplifycfg -preverify -domtree -verify");
+       //opts = g_strdup ("-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -simplifycfg -preverify -domtree -verify");
+       opts = g_strdup ("-targetlibinfo -no-aa -basicaa -notti -instcombine -simplifycfg -sroa -domtree -early-cse -lazy-value-info -correlated-propagation -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -indvars -loop-idiom -loop-deletion -loop-unroll -memdep -gvn -memdep -memcpyopt -sccp -instcombine -lazy-value-info -correlated-propagation -domtree -memdep -dse -adce -simplifycfg -instcombine -strip-dead-prototypes -preverify -domtree -verify");
 #if 1
-       command = g_strdup_printf ("%sopt -f %s -o \"%s.opt.bc\" \"%s.bc\"", acfg->aot_opts.llvm_path, opts, acfg->tmpfname, acfg->tmpfname);
+       command = g_strdup_printf ("%sopt -f %s -o \"%s.opt.bc\" \"%s.bc\"", acfg->aot_opts.llvm_path, opts, acfg->tmpbasename, acfg->tmpbasename);
        printf ("Executing opt: %s\n", command);
        if (system (command) != 0) {
                exit (1);
@@ -6958,7 +6966,7 @@ emit_llvm_file (MonoAotCompile *acfg)
 #endif
        unlink (acfg->tmpfname);
 
-       command = g_strdup_printf ("%sllc %s -disable-gnu-eh-frame -enable-mono-eh-frame -o \"%s\" \"%s.opt.bc\"", acfg->aot_opts.llvm_path, acfg->llc_args->str, acfg->tmpfname, acfg->tmpfname);
+       command = g_strdup_printf ("%sllc %s -disable-gnu-eh-frame -enable-mono-eh-frame -o \"%s\" \"%s.opt.bc\"", acfg->aot_opts.llvm_path, acfg->llc_args->str, acfg->tmpfname, acfg->tmpbasename);
 
        printf ("Executing llc: %s\n", command);
 
@@ -6973,7 +6981,6 @@ emit_code (MonoAotCompile *acfg)
 {
        int oindex, i, prev_index;
        char symbol [256];
-       char end_symbol [256];
 
 #if defined(TARGET_POWERPC64)
        sprintf (symbol, ".Lgot_addr");
@@ -6988,21 +6995,20 @@ emit_code (MonoAotCompile *acfg)
         * code_offsets array. It is also used to compute the memory ranges occupied by
         * AOT code, so it must be equal to the address of the first emitted method.
         */
-       sprintf (symbol, "methods");
        emit_section_change (acfg, ".text", 0);
        emit_alignment (acfg, 8);
        if (acfg->llvm) {
                for (i = 0; i < acfg->nmethods; ++i) {
                        if (acfg->cfgs [i] && acfg->cfgs [i]->compile_llvm) {
-                               fprintf (acfg->fp, "\n.set methods, %s\n", acfg->cfgs [i]->asm_symbol);
+                               acfg->methods_symbol = g_strdup (acfg->cfgs [i]->asm_symbol);
                                break;
                        }
                }
-               if (i == acfg->nmethods)
-                       /* No LLVM compiled methods */
-                       emit_label (acfg, symbol);
-       } else {
+       }
+       if (!acfg->methods_symbol) {
+               sprintf (symbol, "methods");
                emit_label (acfg, symbol);
+               acfg->methods_symbol = g_strdup (symbol);
        }
 
        /* 
@@ -7129,10 +7135,9 @@ emit_code (MonoAotCompile *acfg)
 
                acfg->stats.offsets_size += acfg->nmethods * 4;
 
-               sprintf (end_symbol, "methods");
                for (i = 0; i < acfg->nmethods; ++i) {
                        if (acfg->cfgs [i]) {
-                               emit_symbol_diff (acfg, acfg->cfgs [i]->asm_symbol, end_symbol, 0);
+                               emit_symbol_diff (acfg, acfg->cfgs [i]->asm_symbol, acfg->methods_symbol, 0);
                        } else {
                                emit_int32 (acfg, 0xffffffff);
                        }
@@ -7146,10 +7151,9 @@ emit_code (MonoAotCompile *acfg)
 
        acfg->stats.offsets_size += acfg->nmethods * 4;
 
-       sprintf (end_symbol, "methods");
        for (i = 0; i < acfg->nmethods; ++i) {
                if (acfg->cfgs [i]) {
-                       emit_symbol_diff (acfg, acfg->cfgs [i]->asm_symbol, end_symbol, 0);
+                       emit_symbol_diff (acfg, acfg->cfgs [i]->asm_symbol, acfg->methods_symbol, 0);
                } else {
                        emit_int32 (acfg, 0xffffffff);
                }
@@ -7166,7 +7170,6 @@ emit_code (MonoAotCompile *acfg)
        emit_alignment (acfg, 8);
        emit_label (acfg, symbol);
 
-       sprintf (end_symbol, "methods");
        prev_index = -1;
        for (i = 0; i < acfg->nmethods; ++i) {
                MonoCompile *cfg;
@@ -7191,7 +7194,7 @@ emit_code (MonoAotCompile *acfg)
                                else
                                        fprintf (acfg->fp, "\n\tbl %s\n", symbol);
                        } else {
-                               emit_symbol_diff (acfg, symbol, end_symbol, 0);
+                               emit_symbol_diff (acfg, symbol, acfg->methods_symbol, 0);
                        }
                        /* Make sure the table is sorted by index */
                        g_assert (index > prev_index);
@@ -7200,6 +7203,7 @@ emit_code (MonoAotCompile *acfg)
        }
        sprintf (symbol, "unbox_trampolines_end");
        emit_label (acfg, symbol);
+       emit_int32 (acfg, 0);
 }
 
 static void
@@ -8029,7 +8033,7 @@ emit_file_info (MonoAotCompile *acfg)
         * various problems (i.e. arm/thumb).
         */
        emit_pointer (acfg, acfg->got_symbol);
-       emit_pointer (acfg, "methods");
+       emit_pointer (acfg, acfg->methods_symbol);
        if (acfg->llvm) {
                /*
                 * Emit a reference to the mono_eh_frame table created by our modified LLVM compiler.
@@ -8122,6 +8126,9 @@ emit_file_info (MonoAotCompile *acfg)
        emit_int32 (acfg, __alignof__ (gint64));
 #endif
        emit_int32 (acfg, MONO_TRAMPOLINE_NUM);
+       emit_int32 (acfg, acfg->tramp_page_size);
+       for (i = 0; i < MONO_AOT_TRAMP_NUM; ++i)
+               emit_int32 (acfg, acfg->tramp_page_code_offsets [i]);
 
        if (acfg->aot_opts.static_link) {
                char *p;
@@ -8392,6 +8399,8 @@ compile_asm (MonoAotCompile *acfg)
 #else
 #define AS_NAME "nacl-as"
 #endif
+#elif defined(TARGET_OSX)
+#define AS_NAME "clang -c -x assembler"
 #else
 #define AS_NAME "as"
 #endif
@@ -8400,7 +8409,17 @@ compile_asm (MonoAotCompile *acfg)
 #define LD_OPTIONS ""
 #endif
 
-#define EH_LD_OPTIONS ""
+#if defined(sparc)
+#define LD_NAME "ld -shared -G"
+#elif defined(__ppc__) && defined(TARGET_MACH)
+#define LD_NAME "gcc -dynamiclib"
+#elif defined(TARGET_AMD64) && defined(TARGET_MACH)
+#define LD_NAME "clang --shared"
+#elif defined(HOST_WIN32)
+#define LD_NAME "gcc -shared --dll"
+#elif defined(TARGET_X86) && defined(TARGET_MACH) && !defined(__native_client_codegen__)
+#define LD_NAME "clang -m32 -dynamiclib"
+#endif
 
        if (acfg->aot_opts.asm_only) {
                printf ("Output file: '%s'.\n", acfg->tmpfname);
@@ -8441,18 +8460,10 @@ compile_asm (MonoAotCompile *acfg)
 
        tmp_outfile_name = g_strdup_printf ("%s.tmp", outfile_name);
 
-#if defined(sparc)
-       command = g_strdup_printf ("ld -shared -G -o %s %s.o", tmp_outfile_name, acfg->tmpfname);
-#elif defined(__ppc__) && defined(TARGET_MACH)
-       command = g_strdup_printf ("gcc -dynamiclib -o %s %s.o", tmp_outfile_name, acfg->tmpfname);
-#elif defined(TARGET_AMD64) && defined(TARGET_MACH)
-       command = g_strdup_printf ("gcc --shared -o %s %s.o", tmp_outfile_name, acfg->tmpfname);
-#elif defined(HOST_WIN32)
-       command = g_strdup_printf ("gcc -shared --dll -o %s %s.o", tmp_outfile_name, acfg->tmpfname);
-#elif defined(TARGET_X86) && defined(TARGET_MACH) && !defined(__native_client_codegen__)
-       command = g_strdup_printf ("gcc -m32 -dynamiclib -o %s %s.o", tmp_outfile_name, acfg->tmpfname);
+#ifdef LD_NAME
+       command = g_strdup_printf ("%s -o %s %s.o", LD_NAME, tmp_outfile_name, acfg->tmpfname);
 #else
-       command = g_strdup_printf ("%sld %s %s -shared -o %s %s.o", tool_prefix, EH_LD_OPTIONS, LD_OPTIONS, tmp_outfile_name, acfg->tmpfname);
+       command = g_strdup_printf ("%sld %s -shared -o %s %s.o", tool_prefix, LD_OPTIONS, tmp_outfile_name, acfg->tmpfname);
 #endif
        printf ("Executing the native linker: %s\n", command);
        if (system (command) != 0) {
@@ -8490,7 +8501,7 @@ compile_asm (MonoAotCompile *acfg)
 
 #if defined(TARGET_MACH)
        command = g_strdup_printf ("dsymutil %s", outfile_name);
-       printf ("Generating debug symbols: %s\n", command);
+       printf ("Executing dsymutil: %s\n", command);
        if (system (command) != 0) {
                return 1;
        }
@@ -8523,7 +8534,7 @@ acfg_create (MonoAssembly *ass, guint32 opts)
        acfg->method_indexes = g_hash_table_new (NULL, NULL);
        acfg->method_depth = g_hash_table_new (NULL, NULL);
        acfg->plt_offset_to_entry = g_hash_table_new (NULL, NULL);
-       acfg->patch_to_plt_entry = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
+       acfg->patch_to_plt_entry = g_new0 (GHashTable*, MONO_PATCH_INFO_NUM);
        acfg->patch_to_got_offset = g_hash_table_new (mono_patch_info_hash, mono_patch_info_equal);
        acfg->patch_to_got_offset_by_type = g_new0 (GHashTable*, MONO_PATCH_INFO_NUM);
        for (i = 0; i < MONO_PATCH_INFO_NUM; ++i)
@@ -8575,7 +8586,11 @@ acfg_free (MonoAotCompile *acfg)
        g_hash_table_destroy (acfg->method_indexes);
        g_hash_table_destroy (acfg->method_depth);
        g_hash_table_destroy (acfg->plt_offset_to_entry);
-       g_hash_table_destroy (acfg->patch_to_plt_entry);
+       for (i = 0; i < MONO_PATCH_INFO_NUM; ++i) {
+               if (acfg->patch_to_plt_entry [i])
+                       g_hash_table_destroy (acfg->patch_to_plt_entry [i]);
+       }
+       g_free (acfg->patch_to_plt_entry);
        g_hash_table_destroy (acfg->patch_to_got_offset);
        g_hash_table_destroy (acfg->method_to_cfg);
        g_hash_table_destroy (acfg->token_info_hash);
@@ -8624,7 +8639,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        acfg->aot_opts.nrgctx_fetch_trampolines = 128;
        acfg->aot_opts.ngsharedvt_arg_trampolines = 128;
        acfg->aot_opts.llvm_path = g_strdup ("");
-#if MONOTOUCH
+#ifdef MONOTOUCH
        acfg->aot_opts.use_trampolines_page = TRUE;
 #endif
 
@@ -8656,7 +8671,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
                opt->mdb_optimizations = TRUE;
                opt->gen_seq_points = TRUE;
 
-               if (mono_debug_format == MONO_DEBUG_FORMAT_NONE) {
+               if (!mono_debug_enabled ()) {
                        fprintf (stderr, "The soft-debug AOT option requires the --debug option.\n");
                        return 1;
                }
@@ -8772,12 +8787,16 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
 #ifdef ENABLE_LLVM
        if (acfg->llvm) {
                if (acfg->aot_opts.asm_only) {
-                       if (acfg->aot_opts.outfile)
+                       if (acfg->aot_opts.outfile) {
                                acfg->tmpfname = g_strdup_printf ("%s", acfg->aot_opts.outfile);
-                       else
-                               acfg->tmpfname = g_strdup_printf ("%s.s", acfg->image->name);
+                               acfg->tmpbasename = g_strdup (acfg->tmpfname);
+                       } else {
+                               acfg->tmpbasename = g_strdup_printf ("%s", acfg->image->name);
+                               acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
+                       }
                } else {
-                       acfg->tmpfname = g_strdup ("temp.s");
+                       acfg->tmpbasename = g_strdup_printf ("%s", "temp");
+                       acfg->tmpfname = g_strdup_printf ("%s.s", acfg->tmpbasename);
                }
 
                emit_llvm_file (acfg);
@@ -8856,7 +8875,7 @@ mono_compile_assembly (MonoAssembly *ass, guint32 opts, const char *aot_options)
        }
 
        if (!acfg->aot_opts.nodebug || acfg->aot_opts.dwarf_debug) {
-               if (acfg->aot_opts.dwarf_debug && mono_debug_format == MONO_DEBUG_FORMAT_NONE) {
+               if (acfg->aot_opts.dwarf_debug && !mono_debug_enabled ()) {
                        fprintf (stderr, "The dwarf AOT option requires the --debug option.\n");
                        return 1;
                }
index bff826bf63b7459ffb9223d4a83fd19811caa36b..8843b4c6119576941e9f4502c775895b91bf84be 100644 (file)
@@ -104,9 +104,7 @@ typedef struct MonoAotModule {
        guint8 *plt_end;
        guint8 *blob;
        gint32 *code_offsets;
-#ifdef MONOTOUCH
        gpointer *method_addresses;
-#endif
        /* This contains <offset, index> pairs sorted by offset */
        /* This is needed because LLVM emitted methods can be in any order */
        gint32 *sorted_code_offsets;
@@ -1599,7 +1597,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                        sofile = mono_dl_open (aot_name, MONO_DL_LAZY, &err);
 
                        if (!sofile) {
-                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT failed to load AOT module %s: %s\n", aot_name, err);
+                               mono_trace (G_LOG_LEVEL_INFO, MONO_TRACE_AOT, "AOT module '%s' not found: %s\n", aot_name, err);
                                g_free (err);
                        }
                }
@@ -1730,9 +1728,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
        }
 
        amodule->code_offsets = info->code_offsets;
-#ifdef MONOTOUCH
        amodule->method_addresses = info->method_addresses;
-#endif
        amodule->code = info->methods;
 #ifdef TARGET_ARM
        /* Mask out thumb interop bit */
@@ -1766,7 +1762,7 @@ load_aot_module (MonoAssembly *assembly, gpointer user_data)
                amodule->code_offsets = g_malloc0 (amodule->info.nmethods * sizeof (gint32));
                for (i = 0; i < amodule->info.nmethods; ++i) {
                        /* method_addresses () contains a table of branches, since the ios linker can update those correctly */
-                       void *addr = get_arm_bl_target ((guint32*)(amodule->method_addresses + i));
+                       void *addr = get_arm_bl_target ((guint32*)amodule->method_addresses + i);
 
                        if (addr == amodule->method_addresses)
                                amodule->code_offsets [i] = 0xffffffff;
@@ -2922,7 +2918,7 @@ mono_aot_find_jit_info (MonoDomain *domain, MonoImage *image, gpointer addr)
                                len = old_table[0].method_index;
                        else
                                len = 1;
-                       new_table = alloc0_jit_info_data (domain, (len * 1) * sizeof (JitInfoMap), async);
+                       new_table = alloc0_jit_info_data (domain, (len + 1) * sizeof (JitInfoMap), async);
                        if (old_table)
                                memcpy (new_table, old_table, len * sizeof (JitInfoMap));
                        new_table [0].method_index = len + 1;
@@ -2952,7 +2948,8 @@ decode_patch (MonoAotModule *aot_module, MonoMemPool *mp, MonoJumpInfo *ji, guin
        case MONO_PATCH_INFO_METHOD:
        case MONO_PATCH_INFO_METHOD_JUMP:
        case MONO_PATCH_INFO_ICALL_ADDR:
-       case MONO_PATCH_INFO_METHOD_RGCTX: {
+       case MONO_PATCH_INFO_METHOD_RGCTX:
+       case MONO_PATCH_INFO_METHOD_CODE_SLOT: {
                MethodRef ref;
                gboolean res;
 
@@ -4279,14 +4276,16 @@ get_new_trampoline_from_page (int tramp_type)
        vm_address_t addr, taddr;
        kern_return_t ret;
        vm_prot_t prot, max_prot;
-       int psize;
+       int psize, specific_trampoline_size;
        unsigned char *code;
 
+       specific_trampoline_size = 2 * sizeof (gpointer);
+
        mono_aot_page_lock ();
        page = trampoline_pages [tramp_type];
        if (page && page->trampolines < page->trampolines_end) {
                code = page->trampolines;
-               page->trampolines += 8;
+               page->trampolines += specific_trampoline_size;
                mono_aot_page_unlock ();
                return code;
        }
@@ -4299,6 +4298,8 @@ get_new_trampoline_from_page (int tramp_type)
        amodule = image->aot_module;
        g_assert (amodule);
 
+       g_assert (amodule->info.tramp_page_size == psize);
+
        if (tramp_type == MONO_AOT_TRAMP_SPECIFIC)
                tpage = load_function (amodule, "specific_trampolines_page");
        else if (tramp_type == MONO_AOT_TRAMP_STATIC_RGCTX)
@@ -4342,7 +4343,7 @@ get_new_trampoline_from_page (int tramp_type)
                /* some other thread already allocated, so use that to avoid wasting memory */
                if (page && page->trampolines < page->trampolines_end) {
                        code = page->trampolines;
-                       page->trampolines += 8;
+                       page->trampolines += specific_trampoline_size;
                        mono_aot_page_unlock ();
                        vm_deallocate (mach_task_self (), addr, psize);
                        vm_deallocate (mach_task_self (), taddr, psize);
@@ -4454,7 +4455,7 @@ get_numerous_trampoline (MonoAotTrampoline tramp_type, int n_got_slots, MonoAotM
        *out_amodule = amodule;
 
 #ifdef MONOTOUCH
-#define        MONOTOUCH_TRAMPOLINES_ERROR ". See http://docs.xamarin.com/ios/troubleshooting for instruction on how to fix this condition"
+#define        MONOTOUCH_TRAMPOLINES_ERROR ". See http://docs.xamarin.com/ios/troubleshooting for instructions on how to fix this condition."
 #else
 #define        MONOTOUCH_TRAMPOLINES_ERROR ""
 #endif
index f38d05319b2492b431dc551529aeadee3af821f7..55df1662c34358f3bf3fc345dec84b404e7e8a16 100644 (file)
@@ -791,6 +791,21 @@ class Tests
                        return 5;
                return 0;
        }
+
+       static int llvm_ldlen_licm (int[] arr) {
+               int sum = 0;
+               // The ldlen should be moved out of the loop
+               for (int i = 0; i < arr.Length; ++i)
+                       sum += arr [i];
+               return sum;
+       }
+
+       public static int test_10_llvm_ldlen_licm () {
+               int[] arr = new int [10];
+               for (int i = 0; i < 10; ++i)
+                       arr [i] = 1;
+               return llvm_ldlen_licm (arr);
+       }
 }
 
 
index 11e3e2725b181f350d220009244a4f37b72986ec..e85918292c723e4effa596481b6c07485d105c8d 100644 (file)
@@ -630,9 +630,6 @@ class Tests
                return f == PositiveInfinity ? 0 : 1;
        }
 
-       /* 
-          Disabled until they can be fixed to run on amd64
-
        static double VALUE = 0.19975845134874831D;
 
        public static int test_0_float_conversion_reduces_double_precision () {
@@ -664,6 +661,14 @@ class Tests
                        return 1;
                return 0;
        }
-       */
+
+       public static int test_0_int8_to_float_convertion ()
+    {
+               double d = (double)(float)(long)INT_VAL;
+
+               if (d != 323315616)
+                       return 1;
+               return 0;
+       }
 }
 
index 6fdf39699bed4bf229d2e15f24304fcf0b5b2432..329f70a52a9a1faa3e74690334cf5dbfcfaacbcf 100644 (file)
@@ -62,7 +62,6 @@
 #
 
 break: len:2
-jmp: len:120
 tailcall: len:120 clob:c
 br: len:6
 label: len:0
@@ -87,7 +86,7 @@ long_conv_to_i1: dest:i src1:i len:4
 long_conv_to_i2: dest:i src1:i len:4
 long_conv_to_i4: dest:i src1:i len:3
 long_conv_to_i8: dest:i src1:i len:3
-long_conv_to_r4: dest:f src1:i len:9
+long_conv_to_r4: dest:f src1:i len:15
 long_conv_to_r8: dest:f src1:i len:9
 long_conv_to_u4: dest:i src1:i len:3
 long_conv_to_u8: dest:i src1:i len:3
@@ -247,6 +246,9 @@ float_cgt: dest:i src1:f src2:f len:35
 float_cgt_un: dest:i src1:f src2:f len:48
 float_clt: dest:i src1:f src2:f len:35
 float_clt_un: dest:i src1:f src2:f len:42
+float_cneq: dest:i src1:f src2:f len:42
+float_cge: dest:i src1:f src2:f len:35
+float_cle: dest:i src1:f src2:f len:35
 float_ceq_membase: dest:i src1:f src2:b len:35
 float_cgt_membase: dest:i src1:f src2:b len:35
 float_cgt_un_membase: dest:i src1:f src2:b len:48
@@ -292,7 +294,9 @@ amd64_set_xmmreg_r4: dest:f src1:f len:14 clob:m
 amd64_set_xmmreg_r8: dest:f src1:f len:14 clob:m
 amd64_save_sp_to_lmf: len:16
 tls_get: dest:i len:16
-tls_get_reg: dest:i src1:i len:20
+tls_get_reg: dest:i src1:i len:32
+tls_set: src1:i len:16
+tls_set_reg: src1:i src2:i len:32
 atomic_add_i4: src1:b src2:i dest:i len:32
 atomic_add_new_i4: src1:b src2:i dest:i len:32
 atomic_exchange_i4: src1:b src2:i dest:a len:32
@@ -364,13 +368,20 @@ int_max_un: dest:i src1:i src2:i len:16 clob:1
 
 int_neg: dest:i src1:i clob:1 len:4
 int_not: dest:i src1:i clob:1 len:4
-int_conv_to_r4: dest:f src1:i len:9
+int_conv_to_r4: dest:f src1:i len:15
 int_conv_to_r8: dest:f src1:i len:9
 int_ceq: dest:c len:8
 int_cgt: dest:c len:8
 int_cgt_un: dest:c len:8
 int_clt: dest:c len:8
 int_clt_un: dest:c len:8
+
+int_cneq: dest:c len:8
+int_cge: dest:c len:8
+int_cle: dest:c len:8
+int_cge_un: dest:c len:8
+int_cle_un: dest:c len:8
+
 int_beq: len:8
 int_bne_un: len:8
 int_blt: len:8
@@ -493,7 +504,7 @@ amd64_or_membase_reg: src1:b src2:i len:13
 amd64_xor_membase_reg: src1:b src2:i len:13
 amd64_mul_membase_reg: src1:b src2:i len:15
 
-float_conv_to_r4: dest:f src1:f
+float_conv_to_r4: dest:f src1:f len:17
 
 vcall2: len:64 clob:c
 vcall2_reg: src1:i len:64 clob:c
index 41c1b5840c2fbac384d03e8b5360888cb1ae1571..0fd87c8973fe25fbe5fb5339bb198131affb60db 100644 (file)
@@ -61,7 +61,6 @@ br: len:16
 switch: src1:i len:40
 seq_point: len:24
 
-callvirt: dest:v clob:c len:20
 int_conv_to_r_un: dest:f src1:i len:32
 throw: src1:i len:24
 rethrow: src1:i len:24
index d7d70f7aa5e19fd99d0e8f842fb513ec2b1ff796..93d4404195536434c55648b73791b689b9af3f32 100644 (file)
@@ -63,7 +63,6 @@
 # See the code in mini-x86.c for more details on how the specifiers are used.
 #
 break: len:1
-jmp: len:32 clob:c
 call: dest:a clob:c len:17
 tailcall: len:120 clob:c
 br: len:5
@@ -242,6 +241,9 @@ float_cgt: dest:y src1:f src2:f len:25
 float_cgt_un: dest:y src1:f src2:f len:37
 float_clt: dest:y src1:f src2:f len:25
 float_clt_un: dest:y src1:f src2:f len:32
+float_cneq: dest:y src1:f src2:f len:25
+float_cge: dest:y src1:f src2:f len:37
+float_cle: dest:y src1:f src2:f len:37
 float_conv_to_u: dest:i src1:f len:36
 call_handler: len:11 clob:c
 aot_const: dest:i len:5
@@ -301,6 +303,8 @@ sext_i1: dest:i src1:y len:3
 sext_i2: dest:i src1:y len:3
 tls_get: dest:i len:20
 tls_get_reg: dest:i src1:i len:20
+tls_set: src1:i len:20
+tls_set_reg: src1:i src2:i len:20
 atomic_add_i4: src1:b src2:i dest:i len:16
 atomic_add_new_i4: src1:b src2:i dest:i len:16
 atomic_exchange_i4: src1:b src2:i dest:a len:24
@@ -348,6 +352,12 @@ int_cgt_un: dest:y len:6
 int_clt: dest:y len:6
 int_clt_un: dest:y len:6
 
+int_cneq: dest:y len:6
+int_cge: dest:y len:6
+int_cle: dest:y len:6
+int_cge_un: dest:y len:6
+int_cle_un: dest:y len:6
+
 cond_exc_ieq: len:6
 cond_exc_ine_un: len:6
 cond_exc_ilt: len:6
diff --git a/mono/mini/debug-debugger.c b/mono/mini/debug-debugger.c
deleted file mode 100644 (file)
index a103595..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-/*
- * debug-debugger.c: Hard debugger support (mdb)
- *
- * Author:
- *
- * Copyright 2006-2010 Novell, Inc.
- */
-#if MONO_DEBUGGER_SUPPORTED
-
-#include <config.h>
-#include <mono/io-layer/io-layer.h>
-#include <mono/metadata/threads.h>
-#include <mono/metadata/assembly.h>
-#include <mono/metadata/mono-debug.h>
-#include <mono/metadata/mono-config.h>
-#define _IN_THE_MONO_DEBUGGER
-#include "debug-debugger.h"
-#include "debug-mini.h"
-#include <libgc/include/libgc-mono-debugger.h>
-#include "mini.h"
-#include <unistd.h>
-#include <locale.h>
-#include <string.h>
-
-/*
- * This file is only compiled on platforms where the debugger is supported - see the conditional
- * definition of `debugger_sources' in Makefile.am.
- *
- * configure.in checks whether we're using the included libgc and disables the debugger if not.
- */
-
-#if !defined(USE_INCLUDED_LIBGC)
-#error "Inconsistency detected: #defined MONO_DEBUGGER_SUPPORTED without USE_INCLUDED_GC - fix configure.in!"
-#endif
-
-static guint64 debugger_compile_method (guint64 method_arg);
-static guint64 debugger_get_virtual_method (guint64 class_arg, guint64 method_arg);
-static guint64 debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg);
-static guint64 debugger_class_get_static_field_data (guint64 klass);
-
-static guint64 debugger_run_finally (guint64 argument1, guint64 argument2);
-static void debugger_initialize (void);
-static guint64 debugger_init_code_buffer (void);
-
-static void debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg);
-
-static guint64 debugger_create_string (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2,
-                                      G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument);
-static gint64 debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy,
-                                    G_GNUC_UNUSED guint64 dummy2, gchar *full_name);
-static guint64 debugger_insert_method_breakpoint (guint64 method_argument, guint64 index);
-static guint64 debugger_insert_source_breakpoint (guint64 image_argument, guint64 token,
-                                                 guint64 index, const gchar *class_name);
-static void debugger_remove_breakpoint (guint64 index, G_GNUC_UNUSED guint64 dummy);
-static guint64 debugger_register_class_init_callback (guint64 image_argument, guint64 token,
-                                                     guint64 index, const gchar *class_name);
-static void debugger_remove_class_init_callback (guint64 index, G_GNUC_UNUSED guint64 dummy);
-static guint64 debugger_get_method_signature (guint64 argument1, G_GNUC_UNUSED guint64 argument2);
-
-static guint64 debugger_abort_runtime_invoke (G_GNUC_UNUSED guint64 dummy1, G_GNUC_UNUSED guint64 dummy2);
-
-#define EXECUTABLE_CODE_BUFFER_SIZE 4096
-static guint8 *debugger_executable_code_buffer = NULL;
-
-static GCThreadFunctions debugger_thread_vtable;
-
-static guint32 debugger_thread_abort_signal = 0;
-
-static MonoDebuggerMetadataInfo debugger_metadata_info = {
-       sizeof (MonoDebuggerMetadataInfo),
-       sizeof (MonoDefaults),
-       &mono_defaults,
-       MONO_SIZEOF_TYPE,
-       sizeof (MonoArrayType),
-       sizeof (MonoClass),
-       sizeof (MonoInternalThread),
-       G_STRUCT_OFFSET (MonoInternalThread, tid),
-       G_STRUCT_OFFSET (MonoInternalThread, stack_ptr),
-       G_STRUCT_OFFSET (MonoInternalThread, end_stack),
-       G_STRUCT_OFFSET (MonoClass, image),
-       G_STRUCT_OFFSET (MonoClass, instance_size),
-       G_STRUCT_OFFSET (MonoClass, parent),
-       G_STRUCT_OFFSET (MonoClass, type_token),
-       G_STRUCT_OFFSET (MonoClass, fields),
-       G_STRUCT_OFFSET (MonoClass, methods),
-       G_STRUCT_OFFSET (MonoClass, method.count),
-       G_STRUCT_OFFSET (MonoClass, this_arg),
-       G_STRUCT_OFFSET (MonoClass, byval_arg),
-       G_STRUCT_OFFSET (MonoClass, generic_class),
-       G_STRUCT_OFFSET (MonoClass, generic_container),
-       G_STRUCT_OFFSET (MonoClass, vtable),
-       sizeof (MonoClassField),
-       G_STRUCT_OFFSET (MonoClassField, type),
-       G_STRUCT_OFFSET (MonoClassField, offset),
-       G_STRUCT_OFFSET (MonoDefaults, corlib),
-       G_STRUCT_OFFSET (MonoDefaults, object_class),
-       G_STRUCT_OFFSET (MonoDefaults, byte_class),
-       G_STRUCT_OFFSET (MonoDefaults, void_class),
-       G_STRUCT_OFFSET (MonoDefaults, boolean_class),
-       G_STRUCT_OFFSET (MonoDefaults, sbyte_class),
-       G_STRUCT_OFFSET (MonoDefaults, int16_class),
-       G_STRUCT_OFFSET (MonoDefaults, uint16_class),
-       G_STRUCT_OFFSET (MonoDefaults, int32_class),
-       G_STRUCT_OFFSET (MonoDefaults, uint32_class),
-       G_STRUCT_OFFSET (MonoDefaults, int_class),
-       G_STRUCT_OFFSET (MonoDefaults, uint_class),
-       G_STRUCT_OFFSET (MonoDefaults, int64_class),
-       G_STRUCT_OFFSET (MonoDefaults, uint64_class),
-       G_STRUCT_OFFSET (MonoDefaults, single_class),
-       G_STRUCT_OFFSET (MonoDefaults, double_class),
-       G_STRUCT_OFFSET (MonoDefaults, char_class),
-       G_STRUCT_OFFSET (MonoDefaults, string_class),
-       G_STRUCT_OFFSET (MonoDefaults, enum_class),
-       G_STRUCT_OFFSET (MonoDefaults, array_class),
-       G_STRUCT_OFFSET (MonoDefaults, delegate_class),
-       G_STRUCT_OFFSET (MonoDefaults, exception_class),
-       G_STRUCT_OFFSET (MonoMethod, klass),
-       G_STRUCT_OFFSET (MonoMethod, token),
-       G_STRUCT_OFFSET (MonoMethod, name) + sizeof (void *),
-       G_STRUCT_OFFSET (MonoMethodInflated, declaring),
-       G_STRUCT_OFFSET (MonoVTable, klass),
-       G_STRUCT_OFFSET (MonoVTable, vtable)
-};
-
-extern void MONO_DEBUGGER__notification_function (guint64 command, guint64 data, guint64 data2);
-
-/*
- * This is a global data symbol which is read by the debugger.
- */
-MonoDebuggerInfo MONO_DEBUGGER__debugger_info = {
-       MONO_DEBUGGER_MAGIC,
-       MONO_DEBUGGER_MAJOR_VERSION,
-       MONO_DEBUGGER_MINOR_VERSION,
-       0, /* runtime_flags */
-       sizeof (MonoDebuggerInfo),
-       sizeof (MonoSymbolTable),
-       MONO_TRAMPOLINE_NUM,
-       mono_trampoline_code,
-       &MONO_DEBUGGER__notification_function,
-       &mono_symbol_table,
-       &debugger_metadata_info,
-       &mono_debug_debugger_version,
-
-       &debugger_compile_method,
-       &debugger_get_virtual_method,
-       &debugger_get_boxed_object,
-       &mono_debugger_runtime_invoke,
-       &debugger_class_get_static_field_data,
-       &debugger_run_finally,
-       &debugger_initialize,
-
-       &debugger_create_string,
-       &debugger_lookup_class,
-
-       &debugger_insert_method_breakpoint,
-       &debugger_insert_source_breakpoint,
-       &debugger_remove_breakpoint,
-
-       &debugger_register_class_init_callback,
-       &debugger_remove_class_init_callback,
-
-       &mono_debugger_thread_table,
-
-       &debugger_executable_code_buffer,
-       mono_breakpoint_info,
-       mono_breakpoint_info_index,
-
-       EXECUTABLE_CODE_BUFFER_SIZE,
-       MONO_BREAKPOINT_ARRAY_SIZE,
-
-       debugger_get_method_signature,
-       debugger_init_code_buffer,
-
-       &gc_thread_vtable,
-       &debugger_thread_vtable,
-
-       &mono_debugger_event_handler,
-       debugger_event_handler,
-
-       &_mono_debug_using_mono_debugger,
-       (gint32*)&_mono_debugger_interruption_request,
-
-       &debugger_abort_runtime_invoke,
-
-       &debugger_thread_abort_signal
-};
-
-static guint64
-debugger_abort_runtime_invoke (G_GNUC_UNUSED guint64 dummy1, G_GNUC_UNUSED guint64 dummy2)
-{
-       return mono_debugger_abort_runtime_invoke ();
-}
-
-static guint64
-debugger_compile_method (guint64 method_arg)
-{
-       MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg);
-       gpointer addr;
-
-       mono_debugger_lock ();
-       addr = mono_compile_method (method);
-       mono_debugger_unlock ();
-
-       return (guint64) (gsize) addr;
-}
-
-static guint64
-debugger_get_virtual_method (guint64 object_arg, guint64 method_arg)
-{
-       MonoObject *object = (MonoObject *) GUINT_TO_POINTER ((gsize) object_arg);
-       MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg);
-
-       if (mono_class_is_valuetype (mono_method_get_class (method)))
-               return method_arg;
-
-       return (guint64) (gsize) mono_object_get_virtual_method (object, method);
-}
-
-static guint64
-debugger_get_boxed_object (guint64 klass_arg, guint64 val_arg)
-{
-       static MonoObject *last_boxed_object = NULL;
-       MonoClass *klass = (MonoClass *) GUINT_TO_POINTER ((gsize) klass_arg);
-       gpointer val = (gpointer) GUINT_TO_POINTER ((gsize) val_arg);
-       MonoObject *boxed;
-
-       if (!mono_class_is_valuetype (klass))
-               return val_arg;
-
-       boxed = mono_value_box (mono_domain_get (), klass, val);
-       last_boxed_object = boxed; // Protect the object from being garbage collected
-
-       return (guint64) (gsize) boxed;
-}
-
-static guint64
-debugger_create_string (G_GNUC_UNUSED guint64 dummy, G_GNUC_UNUSED guint64 dummy2,
-                       G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument)
-{
-       return (guint64) (gsize) mono_string_new_wrapper (string_argument);
-}
-
-static gint64
-debugger_lookup_class (guint64 image_argument, G_GNUC_UNUSED guint64 dummy,
-                      G_GNUC_UNUSED guint64 dummy2, gchar *full_name)
-{
-       MonoImage *image = (MonoImage *) GUINT_TO_POINTER ((gsize) image_argument);
-       gchar *name_space, *name, *pos;
-       MonoClass *klass;
-
-       pos = strrchr (full_name, '.');
-       if (pos) {
-               name_space = full_name;
-               *pos = 0;
-               name = pos + 1;
-       } else {
-               name = full_name;
-               name_space = NULL;
-       }
-
-       klass = mono_class_from_name (image, name_space ? name_space : "", name);
-       if (!klass)
-               return -1;
-
-       mono_class_init (klass);
-       mono_class_setup_methods (klass);
-       return (gint64) (gssize) klass;
-}
-
-static guint64
-debugger_run_finally (guint64 context_argument, G_GNUC_UNUSED guint64 dummy)
-{
-       mono_debugger_run_finally (GUINT_TO_POINTER ((gsize)context_argument));
-       return 0;
-}
-
-static guint64
-debugger_class_get_static_field_data (guint64 value)
-{
-       MonoClass *klass = GUINT_TO_POINTER ((gsize) value);
-       MonoVTable *vtable = mono_class_vtable (mono_domain_get (), klass);
-       return (guint64) (gsize) mono_vtable_get_static_field_data (vtable);
-}
-
-static guint64
-debugger_insert_method_breakpoint (guint64 method_argument, guint64 index)
-{
-       MonoMethod *method = GUINT_TO_POINTER ((gsize) method_argument);
-       MonoDebugMethodAddressList *info;
-
-       mono_debugger_lock ();
-
-       if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
-               const char *name = method->name;
-               MonoMethod *nm = NULL;
-
-               if (method->klass->parent == mono_defaults.multicastdelegate_class) {
-                       if (*name == 'I' && (strcmp (name, "Invoke") == 0))
-                               nm = mono_marshal_get_delegate_invoke (method, NULL);
-                       else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0))
-                               nm = mono_marshal_get_delegate_begin_invoke (method);
-                       else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0))
-                               nm = mono_marshal_get_delegate_end_invoke (method);
-               }
-
-               if (!nm) {
-                       mono_debugger_unlock ();
-                       return 0;
-               }
-
-               method = nm;
-       }
-
-       info = mono_debugger_insert_method_breakpoint (method, index);
-
-       mono_debugger_unlock ();
-       return (guint64) (gsize) info;
-}
-
-static guint64
-debugger_insert_source_breakpoint (guint64 image_argument, guint64 token, guint64 index,
-                                  const gchar *class_name)
-{
-       MonoImage *image = GUINT_TO_POINTER ((gsize) image_argument);
-       MonoDebugMethodAddressList *info;
-       MonoClass *klass;
-       int i;
-
-       mono_debugger_lock ();
-
-       klass = mono_debugger_register_class_init_callback (image, class_name, token, index);
-       if (!klass || !klass->inited || !klass->methods) {
-               mono_debugger_unlock ();
-               return 0;
-       }
-
-       for (i = 0; i < klass->method.count; i++) {
-               MonoMethod *method = klass->methods [i];
-
-               if (method->token != token)
-                       continue;
-
-               if (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) {
-                       const char *name = method->name;
-                       MonoMethod *nm = NULL;
-
-                       if (method->klass->parent == mono_defaults.multicastdelegate_class) {
-                               if (*name == 'I' && (strcmp (name, "Invoke") == 0))
-                                       nm = mono_marshal_get_delegate_invoke (method, NULL);
-                               else if (*name == 'B' && (strcmp (name, "BeginInvoke") == 0))
-                                       nm = mono_marshal_get_delegate_begin_invoke (method);
-                               else if (*name == 'E' && (strcmp (name, "EndInvoke") == 0))
-                                       nm = mono_marshal_get_delegate_end_invoke (method);
-                       }
-
-                       if (!nm) {
-                               mono_debugger_unlock ();
-                               return 0;
-                       }
-
-                       method = nm;
-               }
-
-               info = mono_debug_lookup_method_addresses (method);
-               mono_debugger_unlock ();
-               return (guint64) (gsize) info;
-       }
-
-       mono_debugger_unlock ();
-       return 0;
-}
-
-static void
-debugger_remove_breakpoint (guint64 index, G_GNUC_UNUSED guint64 dummy)
-{
-       mono_debugger_lock ();
-       mono_debugger_remove_method_breakpoint (index);
-       mono_debugger_remove_class_init_callback (index);
-       mono_debugger_unlock ();
-}
-
-static guint64
-debugger_register_class_init_callback (guint64 image_argument, guint64 token, guint64 index,
-                                      const gchar *class_name)
-{
-       MonoImage *image = GUINT_TO_POINTER ((gsize) image_argument);
-       MonoClass *klass;
-
-       mono_debugger_lock ();
-       klass = mono_debugger_register_class_init_callback (image, class_name, token, index);
-       mono_debugger_unlock ();
-       return (guint64) (gsize) klass;
-}
-
-static void
-debugger_remove_class_init_callback (guint64 index, G_GNUC_UNUSED guint64 dummy)
-{
-       mono_debugger_lock ();
-       mono_debugger_remove_class_init_callback (index);
-       mono_debugger_unlock ();
-}
-
-static guint64
-debugger_get_method_signature (guint64 method_arg, G_GNUC_UNUSED guint64 dummy)
-{
-       MonoMethod *method = (MonoMethod *) GUINT_TO_POINTER ((gsize) method_arg);
-       MonoMethodSignature *sig;
-
-       sig = mono_method_signature (method);
-       return (guint64) (gsize) sig;
-}
-
-static void
-debugger_event_handler (MonoDebuggerEvent event, guint64 data, guint64 arg)
-{
-       MONO_DEBUGGER__notification_function (event, data, arg);
-}
-
-static void
-debugger_gc_thread_created (pthread_t thread, void *stack_ptr)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_GC_THREAD_CREATED,
-                            (guint64) (gsize) stack_ptr, thread);
-}
-
-static void
-debugger_gc_thread_exited (pthread_t thread, void *stack_ptr)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_GC_THREAD_EXITED,
-                            (guint64) (gsize) stack_ptr, thread);
-}
-
-static void
-debugger_gc_stop_world (void)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_ACQUIRE_GLOBAL_THREAD_LOCK, 0, 0);
-}
-
-static void
-debugger_gc_start_world (void)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_RELEASE_GLOBAL_THREAD_LOCK, 0, 0);
-}
-
-static GCThreadFunctions debugger_thread_vtable = {
-       NULL,
-
-       debugger_gc_thread_created,
-       debugger_gc_thread_exited,
-
-       debugger_gc_stop_world,
-       debugger_gc_start_world
-};
-
-static void
-debugger_init_threads (void)
-{
-       gc_thread_vtable = &debugger_thread_vtable;
-}
-
-#if 0
-
-static void
-debugger_finalize_threads (void)
-{
-       gc_thread_vtable = NULL;
-}
-
-#endif
-
-static guint64
-debugger_init_code_buffer (void)
-{
-       if (!debugger_executable_code_buffer)
-               debugger_executable_code_buffer = mono_global_codeman_reserve (EXECUTABLE_CODE_BUFFER_SIZE);
-       return (guint64) (gsize) debugger_executable_code_buffer;
-}
-
-extern MonoDebuggerInfo *MONO_DEBUGGER__debugger_info_ptr;
-extern long MONO_DEBUGGER__using_debugger;
-
-static void
-debugger_initialize (void)
-{
-}
-
-/**
- * Check whether we're running inside the debugger.
- *
- * There seems to be a bug in some versions of glibc which causes _dl_debug_state() being called with
- * RT_CONSISTENT before relocations are done.
- *
- * If that happens, the debugger cannot read the `MONO_DEBUGGER__debugger_info' structure at the time
- * the `libmono.so' library is loaded.
- *
- * As a workaround, the `mdb_debug_info' now also contains a global variable called
- * `MONO_DEBUGGER__using_debugger' which may we set to 1 by the debugger to tell us that we're running
- * inside the debugger.
- *
- * mini_init() checks this and calls mini_debugger_init() if necessary.
- *
- */
-
-gboolean
-mini_debug_running_inside_mdb (void)
-{
-       return MONO_DEBUGGER__using_debugger || mono_debug_using_mono_debugger ();
-}
-
-void
-mini_debugger_init (void)
-{
-       if (mono_debugger_event_handler) {
-               g_warning (G_STRLOC ": duplicate call to mono_debugger_init()!");
-               return;
-       }
-
-       debugger_executable_code_buffer = mono_global_codeman_reserve (EXECUTABLE_CODE_BUFFER_SIZE);
-       mono_debugger_event_handler = debugger_event_handler;
-
-       debugger_thread_abort_signal = mono_thread_get_abort_signal ();
-
-       /*
-        * Use an indirect call so gcc can't optimize it away.
-        */
-       MONO_DEBUGGER__debugger_info.initialize ();
-
-       debugger_init_threads ();
-
-       /*
-        * Initialize the thread manager.
-        *
-        * NOTE: We only reference the `MONO_DEBUGGER__debugger_info_ptr' here to prevent the
-        * linker from removing the .mdb_debug_info section.
-        */
-
-       mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_THREAD_MANAGER,
-                            (guint64) (gssize) MONO_DEBUGGER__debugger_info_ptr, 0);
-}
-
-void
-mini_debugger_set_attach_ok (void)
-{
-       debugger_thread_abort_signal = mono_thread_get_abort_signal ();
-       MONO_DEBUGGER__debugger_info.runtime_flags |= DEBUGGER_RUNTIME_FLAGS_ATTACH_OK;
-}
-
-typedef struct 
-{
-       MonoDomain *domain;
-       const char *file;
-} DebuggerThreadArgs;
-
-typedef struct
-{
-       MonoDomain *domain;
-       MonoMethod *method;
-       int argc;
-       char **argv;
-} MainThreadArgs;
-
-static guint32
-main_thread_handler (gpointer user_data)
-{
-       MainThreadArgs *main_args = (MainThreadArgs *) user_data;
-
-       return mono_runtime_run_main (main_args->method, main_args->argc, main_args->argv, NULL);
-}
-
-int
-mini_debugger_main (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv)
-{
-       MainThreadArgs main_args;
-       MonoImage *image;
-       MonoMethod *main_method;
-
-       /*
-        * Get and compile the main function.
-        */
-
-       image = mono_assembly_get_image (assembly);
-       main_method = mono_get_method (image, mono_image_get_entry_point (image), NULL);
-
-       /*
-        * Initialize managed code.
-        */
-       mono_debugger_event (MONO_DEBUGGER_EVENT_INITIALIZE_MANAGED_CODE,
-                            (guint64) (gssize) main_method, 0);
-
-       /*
-        * Start the main thread and wait until it's ready.
-        */
-
-       main_args.domain = domain;
-       main_args.method = main_method;
-       main_args.argc = argc;
-       main_args.argv = argv;
-
-#if RUN_IN_SUBTHREAD
-       mono_thread_create (domain, main_thread_handler, &main_args);
-#else
-       main_thread_handler (&main_args);
-#endif
-
-       mono_thread_manage ();
-
-       /*
-        * This will never return.
-        */
-       mono_debugger_event (MONO_DEBUGGER_EVENT_WRAPPER_MAIN, 0, 0);
-
-       return 0;
-}
-#endif /* MONO_DEBUGGER_SUPPORTED */
diff --git a/mono/mini/debug-debugger.h b/mono/mini/debug-debugger.h
deleted file mode 100644 (file)
index b7c5b43..0000000
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * This is a private header file for the debugger.
- */
-
-#ifndef __DEBUG_DEBUGGER_H__
-#define __DEBUG_DEBUGGER_H__
-
-#if !defined _IN_THE_MONO_DEBUGGER
-#error "<debug-debugger.h> is a private header file only intended to be used by the debugger."
-#endif
-
-#include <mono/metadata/class-internals.h>
-#include <mono/metadata/mono-debug-debugger.h>
-#include <libgc/include/libgc-mono-debugger.h>
-#include "debug-mini.h"
-
-typedef struct _MonoDebuggerInfo               MonoDebuggerInfo;
-typedef struct _MonoDebuggerMetadataInfo       MonoDebuggerMetadataInfo;
-
-/*
- * Address of the x86 trampoline code.  This is used by the debugger to check
- * whether a method is a trampoline.
- */
-extern guint8 *mono_trampoline_code [];
-
-typedef enum {
-       DEBUGGER_RUNTIME_FLAGS_NONE             = 0,
-       DEBUGGER_RUNTIME_FLAGS_ATTACH_OK        = 1
-} MonoDebuggerRuntimeFlags;
-
-/*
- * There's a global data symbol called `MONO_DEBUGGER__debugger_info' which
- * contains pointers to global variables and functions which must be accessed
- * by the debugger.
- */
-struct _MonoDebuggerInfo {
-       guint64 magic;
-       guint32 major_version;
-       guint32 minor_version;
-       guint32 runtime_flags;
-       guint32 total_size;
-       guint32 symbol_table_size;
-       guint32 mono_trampoline_num;
-       guint8 **mono_trampoline_code;
-       gpointer notification_function;
-       MonoSymbolTable **symbol_table;
-       MonoDebuggerMetadataInfo *metadata_info;
-       gint32 *debugger_version;
-
-       guint64 (*compile_method) (guint64 method_argument);
-       guint64 (*get_virtual_method) (guint64 object_argument, guint64 method_argument);
-       guint64 (*get_boxed_object_method) (guint64 klass_argument, guint64 val_argument);
-       MonoInvokeFunc runtime_invoke;
-       guint64 (*class_get_static_field_data) (guint64 klass);
-       guint64 (*run_finally) (guint64 argument1, guint64 argument2);
-       void (*initialize) (void);
-
-       guint64 (*create_string) (G_GNUC_UNUSED guint64 dummy1, G_GNUC_UNUSED guint64 dummy2,
-                                 G_GNUC_UNUSED guint64 dummy3, const gchar *string_argument);
-       gint64 (*lookup_class) (guint64 image_argument, G_GNUC_UNUSED guint64 dummy,
-                               G_GNUC_UNUSED guint64 dummy2, gchar *full_name);
-
-       guint64 (*insert_method_breakpoint) (guint64 method_argument, guint64 index);
-       guint64 (*insert_source_breakpoint) (guint64 image_argument, guint64 token,
-                                            guint64 index, const gchar *class_name);
-       void (*remove_breakpoint) (guint64 index, G_GNUC_UNUSED guint64 dummy);
-
-       guint64 (*rgister_class_init_callback) (guint64 image_argument, guint64 token,
-                                               guint64 index, const gchar *class_name);
-       void (*remove_class_init_callback) (guint64 index, G_GNUC_UNUSED guint64 dummy);
-
-       MonoDebuggerThreadInfo **thread_table;
-
-       guint8 **executable_code_buffer;
-       MonoBreakpointInfo *mono_breakpoint_info;
-       gssize *mono_breakpoint_info_index;
-
-       guint32 executable_code_buffer_size;
-       guint32 breakpoint_array_size;
-
-       guint64 (*get_method_signature) (guint64 method_argument, G_GNUC_UNUSED guint64 dummy);
-       guint64 (*init_code_buffer) (void);
-
-       /*
-        * These are only needed when attaching.
-        */
-       GCThreadFunctions **thread_vtable_ptr;
-       GCThreadFunctions *debugger_thread_vtable;
-       void (**event_handler_ptr) (MonoDebuggerEvent event, guint64 data, guint64 arg);
-       void (*debugger_event_handler) (MonoDebuggerEvent event, guint64 data, guint64 arg);
-       gint32 *using_mono_debugger;
-       gint32 *interruption_request;
-
-       guint64 (*abort_runtime_invoke) (G_GNUC_UNUSED guint64 dummy1, G_GNUC_UNUSED guint64 dummy2);
-
-       guint32 *thread_abort_signal;
-};
-
-struct _MonoDebuggerMetadataInfo {
-       int size;
-       int mono_defaults_size;
-       MonoDefaults *mono_defaults;
-       int type_size;
-       int array_type_size;
-       int klass_size;
-       int thread_size;
-       int thread_tid_offset;
-       int thread_stack_ptr_offset;
-       int thread_end_stack_offset;
-       int klass_image_offset;
-       int klass_instance_size_offset;
-       int klass_parent_offset;
-       int klass_token_offset;
-       int klass_field_offset;
-       int klass_methods_offset;
-       int klass_method_count_offset;
-       int klass_this_arg_offset;
-       int klass_byval_arg_offset;
-       int klass_generic_class_offset;
-       int klass_generic_container_offset;
-       int klass_vtable_offset;
-       int field_info_size;
-       int field_info_type_offset;
-       int field_info_offset_offset;
-       int mono_defaults_corlib_offset;
-       int mono_defaults_object_offset;
-       int mono_defaults_byte_offset;
-       int mono_defaults_void_offset;
-       int mono_defaults_boolean_offset;
-       int mono_defaults_sbyte_offset;
-       int mono_defaults_int16_offset;
-       int mono_defaults_uint16_offset;
-       int mono_defaults_int32_offset;
-       int mono_defaults_uint32_offset;
-       int mono_defaults_int_offset;
-       int mono_defaults_uint_offset;
-       int mono_defaults_int64_offset;
-       int mono_defaults_uint64_offset;
-       int mono_defaults_single_offset;
-       int mono_defaults_double_offset;
-       int mono_defaults_char_offset;
-       int mono_defaults_string_offset;
-       int mono_defaults_enum_offset;
-       int mono_defaults_array_offset;
-       int mono_defaults_delegate_offset;
-       int mono_defaults_exception_offset;
-       int mono_method_klass_offset;
-       int mono_method_token_offset;
-       int mono_method_flags_offset;
-       int mono_method_inflated_offset;
-       int mono_vtable_klass_offset;
-       int mono_vtable_vtable_offset;
-};
-
-#endif
index 25f77b22f4da48452e60c6c8cabc463cd930951b..61c055a1daa92226f78b637d2ac9752ff2a81d0d 100644 (file)
 
 #define _IN_THE_MONO_DEBUGGER
 #include <mono/metadata/mono-debug-debugger.h>
-#include "debug-mini.h"
 
 #include <mono/utils/valgrind.h>
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-#include <libgc/include/libgc-mono-debugger.h>
-#endif
-
 typedef struct {
        guint32 index;
        MonoMethodDesc *desc;
@@ -39,64 +34,6 @@ typedef struct
        guint32 breakpoint_id;
 } MiniDebugMethodInfo;
 
-typedef struct {
-       MonoObject *last_exception;
-       guint32 stopped_on_exception : 1;
-       guint32 stopped_on_unhandled : 1;
-} MonoDebuggerExceptionState;
-
-typedef enum {
-       MONO_DEBUGGER_THREAD_FLAGS_NONE         = 0,
-       MONO_DEBUGGER_THREAD_FLAGS_INTERNAL     = 1,
-       MONO_DEBUGGER_THREAD_FLAGS_THREADPOOL   = 2
-} MonoDebuggerThreadFlags;
-
-typedef enum {
-       MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_NONE                = 0,
-       MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_IN_RUNTIME_INVOKE   = 1,
-       MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED     = 2
-} MonoDebuggerInternalThreadFlags;
-
-struct _MonoDebuggerThreadInfo {
-       guint64 tid;
-       guint64 lmf_addr;
-       guint64 end_stack;
-
-       guint64 extended_notifications;
-
-       /* Next pointer. */
-       MonoDebuggerThreadInfo *next;
-
-       /*
-        * The stack bounds are only used when reading a core file.
-        */
-       guint64 stack_start;
-       guint64 signal_stack_start;
-       guint32 stack_size;
-       guint32 signal_stack_size;
-
-       guint32 thread_flags;
-
-       /*
-        * The debugger doesn't access anything beyond this point.
-        */
-       MonoDebuggerExceptionState exception_state;
-
-       guint32 internal_flags;
-
-       MonoJitTlsData *jit_tls;
-       MonoInternalThread *thread;
-};
-
-typedef struct {
-       gpointer stack_pointer;
-       MonoObject *exception_obj;
-       guint32 stop;
-       guint32 stop_unhandled;
-} MonoDebuggerExceptionInfo;
-
-MonoDebuggerThreadInfo *mono_debugger_thread_table = NULL;
-
 static inline void
 record_line_number (MiniDebugMethodInfo *info, guint32 address, guint32 offset)
 {
@@ -114,7 +51,7 @@ mono_debug_init_method (MonoCompile *cfg, MonoBasicBlock *start_block, guint32 b
 {
        MiniDebugMethodInfo *info;
 
-       if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
+       if (!mono_debug_enabled ())
                return;
 
        info = g_new0 (MiniDebugMethodInfo, 1);
@@ -338,8 +275,6 @@ mono_debug_close_method (MonoCompile *cfg)
 
        mono_debug_add_vg_method (method, jit);
 
-       mono_debugger_check_breakpoints (method, debug_info);
-
        mono_debug_free_method_jit_info (jit);
        mono_debug_free_method (cfg);
 }
@@ -655,7 +590,7 @@ mono_debug_add_aot_method (MonoDomain *domain, MonoMethod *method, guint8 *code_
 {
        MonoDebugMethodJitInfo *jit;
 
-       if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
+       if (!mono_debug_enabled ())
                return;
 
        if ((method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) ||
@@ -677,15 +612,6 @@ mono_debug_add_aot_method (MonoDomain *domain, MonoMethod *method, guint8 *code_
        mono_debug_free_method_jit_info (jit);
 }
 
-void
-mono_debug_add_icall_wrapper (MonoMethod *method, MonoJitICallInfo* callinfo)
-{
-       if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
-               return;
-
-       // mono_debug_add_wrapper (method, callinfo->wrapper, callinfo->func);
-}
-
 static void
 print_var_info (MonoDebugVarInfo *info, int idx, const char *name, const char *type)
 {
@@ -765,7 +691,7 @@ mono_debug_print_vars (gpointer ip, gboolean only_arguments)
 
 static GPtrArray *breakpoints = NULL;
 
-int
+static int
 mono_debugger_insert_breakpoint_full (MonoMethodDesc *desc)
 {
        static int last_breakpoint_id = 0;
@@ -783,29 +709,7 @@ mono_debugger_insert_breakpoint_full (MonoMethodDesc *desc)
        return info->index;
 }
 
-int
-mono_debugger_remove_breakpoint (int breakpoint_id)
-{
-       int i;
-
-       if (!breakpoints)
-               return 0;
-
-       for (i = 0; i < breakpoints->len; i++) {
-               MiniDebugBreakpointInfo *info = g_ptr_array_index (breakpoints, i);
-
-               if (info->index != breakpoint_id)
-                       continue;
-
-               mono_method_desc_free (info->desc);
-               g_ptr_array_remove (breakpoints, info);
-               g_free (info);
-               return 1;
-       }
-
-       return 0;
-}
-
+/*FIXME This is part of the public API by accident, remove it from there when possible. */
 int
 mono_debugger_insert_breakpoint (const gchar *method_name, gboolean include_namespace)
 {
@@ -818,6 +722,7 @@ mono_debugger_insert_breakpoint (const gchar *method_name, gboolean include_name
        return mono_debugger_insert_breakpoint_full (desc);
 }
 
+/*FIXME This is part of the public API by accident, remove it from there when possible. */
 int
 mono_debugger_method_has_breakpoint (MonoMethod *method)
 {
@@ -837,441 +742,3 @@ mono_debugger_method_has_breakpoint (MonoMethod *method)
 
        return 0;
 }
-
-void
-mono_debugger_breakpoint_callback (MonoMethod *method, guint32 index)
-{
-       mono_debugger_event (MONO_DEBUGGER_EVENT_JIT_BREAKPOINT, (guint64) (gsize) method, index);
-}
-
-void
-mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData *jit_tls, gpointer func)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       size_t stsize = 0;
-       guint8 *staddr = NULL;
-       MonoDebuggerThreadInfo *info;
-
-       if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
-               return;
-
-       mono_debugger_lock ();
-
-       mono_thread_get_stack_bounds (&staddr, &stsize);
-
-       info = g_new0 (MonoDebuggerThreadInfo, 1);
-       info->tid = tid;
-       info->thread = thread->internal_thread;
-       info->stack_start = (guint64) (gsize) staddr;
-       info->signal_stack_start = (guint64) (gsize) jit_tls->signal_stack;
-       info->stack_size = stsize;
-       info->signal_stack_size = jit_tls->signal_stack_size;
-       info->end_stack = (guint64) (gsize) GC_mono_debugger_get_stack_ptr ();
-       info->lmf_addr = (guint64) (gsize) mono_get_lmf_addr ();
-       info->jit_tls = jit_tls;
-
-       if (func)
-               info->thread_flags = MONO_DEBUGGER_THREAD_FLAGS_INTERNAL;
-       if (thread->internal_thread->threadpool_thread)
-               info->thread_flags |= MONO_DEBUGGER_THREAD_FLAGS_THREADPOOL;
-
-       info->next = mono_debugger_thread_table;
-       mono_debugger_thread_table = info;
-
-       mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_CREATED,
-                            tid, (guint64) (gsize) info);
-
-       mono_debugger_unlock ();
-#endif /* MONO_DEBUGGER_SUPPORTED */
-}
-
-void
-mono_debugger_thread_cleanup (MonoJitTlsData *jit_tls)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       MonoDebuggerThreadInfo **ptr;
-
-       if (mono_debug_format == MONO_DEBUG_FORMAT_NONE)
-               return;
-
-       mono_debugger_lock ();
-
-       for (ptr = &mono_debugger_thread_table; *ptr; ptr = &(*ptr)->next) {
-               MonoDebuggerThreadInfo *info = *ptr;
-
-               if (info->jit_tls != jit_tls)
-                       continue;
-
-               mono_debugger_event (MONO_DEBUGGER_EVENT_THREAD_CLEANUP,
-                                    info->tid, (guint64) (gsize) info);
-
-               *ptr = info->next;
-               g_free (info);
-               break;
-       }
-
-       mono_debugger_unlock ();
-#endif
-}
-
-void
-mono_debugger_extended_notification (MonoDebuggerEvent event, guint64 data, guint64 arg)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       MonoDebuggerThreadInfo **ptr;
-       MonoInternalThread *thread = mono_thread_internal_current ();
-
-       if (!mono_debug_using_mono_debugger ())
-               return;
-
-       mono_debugger_lock ();
-
-       for (ptr = &mono_debugger_thread_table; *ptr; ptr = &(*ptr)->next) {
-               MonoDebuggerThreadInfo *info = *ptr;
-
-               if (info->thread != thread)
-                       continue;
-
-               if ((info->extended_notifications & (int) event) == 0)
-                       continue;
-
-               mono_debugger_event (event, data, arg);
-       }
-
-       mono_debugger_unlock ();
-#endif
-}
-
-void
-mono_debugger_trampoline_compiled (const guint8 *trampoline, MonoMethod *method, const guint8 *code)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       struct {
-               const guint8 * trampoline;
-               MonoMethod *method;
-               const guint8 *code;
-       } info = { trampoline, method, code };
-
-       mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_OLD_TRAMPOLINE,
-                                            (guint64) (gsize) method, (guint64) (gsize) code);
-       mono_debugger_extended_notification (MONO_DEBUGGER_EVENT_TRAMPOLINE,
-                                            (guint64) (gsize) &info, 0);
-#endif
-}
-
-#if MONO_DEBUGGER_SUPPORTED
-static MonoDebuggerThreadInfo *
-find_debugger_thread_info (MonoInternalThread *thread)
-{
-       MonoDebuggerThreadInfo **ptr;
-
-       for (ptr = &mono_debugger_thread_table; *ptr; ptr = &(*ptr)->next) {
-               MonoDebuggerThreadInfo *info = *ptr;
-
-               if (info->thread == thread)
-                       return info;
-       }
-
-       return NULL;
-}
-#endif
-
-MonoDebuggerExceptionAction
-_mono_debugger_throw_exception (gpointer addr, gpointer stack, MonoObject *exc)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       MonoDebuggerExceptionInfo exc_info;
-       MonoDebuggerThreadInfo *thread_info;
-
-       if (!mono_debug_using_mono_debugger ())
-               return MONO_DEBUGGER_EXCEPTION_ACTION_NONE;
-
-       mono_debugger_lock ();
-
-       thread_info = find_debugger_thread_info (mono_thread_internal_current ());
-       if (!thread_info) {
-               mono_debugger_unlock ();
-               return MONO_DEBUGGER_EXCEPTION_ACTION_NONE;
-       }
-
-       if ((thread_info->internal_flags & MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED) != 0) {
-               mono_debugger_unlock ();
-               return MONO_DEBUGGER_EXCEPTION_ACTION_NONE;
-       }
-
-       if (thread_info->exception_state.stopped_on_exception ||
-           thread_info->exception_state.stopped_on_unhandled) {
-               thread_info->exception_state.stopped_on_exception = 0;
-               mono_debugger_unlock ();
-               return MONO_DEBUGGER_EXCEPTION_ACTION_NONE;
-       }
-
-       /* Protect the exception object from being garbage collected. */
-
-       thread_info->exception_state.stopped_on_unhandled = 0;
-       thread_info->exception_state.stopped_on_exception = 1;
-       thread_info->exception_state.last_exception = exc;
-
-       /*
-        * Backwards compatibility:
-        *
-        * Older debugger versions only know `exc_info.stop' and older runtime versions check
-        * `exc_info.stop != 0'.
-        *
-        * The debugger must check for `mono_debug_debugger_version >= 5' before accessing the
-        * `stop_unhandled' field.
-        */
-
-       exc_info.stack_pointer = stack;
-       exc_info.exception_obj = exc;
-       exc_info.stop = 0;
-       exc_info.stop_unhandled = 0;
-
-       mono_debugger_event (MONO_DEBUGGER_EVENT_THROW_EXCEPTION, (guint64) (gsize) &exc_info,
-                            (guint64) (gsize) addr);
-
-       if (!exc_info.stop) {
-               thread_info->exception_state.stopped_on_exception = 0;
-               thread_info->exception_state.last_exception = NULL;
-       } 
-
-       mono_debugger_unlock ();
-
-       if (exc_info.stop)
-               return MONO_DEBUGGER_EXCEPTION_ACTION_STOP;
-       else if (exc_info.stop_unhandled)
-               return MONO_DEBUGGER_EXCEPTION_ACTION_STOP_UNHANDLED;
-#endif
-
-       return MONO_DEBUGGER_EXCEPTION_ACTION_NONE;
-}
-
-gboolean
-_mono_debugger_unhandled_exception (gpointer addr, gpointer stack, MonoObject *exc)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       MonoDebuggerThreadInfo *thread_info;
-
-       if (!mono_debug_using_mono_debugger ())
-               return FALSE;
-
-       if (exc) {
-               const gchar *name = mono_class_get_name (mono_object_get_class (exc));
-               if (!strcmp (name, "ThreadAbortException"))
-                       return FALSE;
-       }
-
-       mono_debugger_lock ();
-
-       thread_info = find_debugger_thread_info (mono_thread_internal_current ());
-       if (!thread_info) {
-               mono_debugger_unlock ();
-               return FALSE;
-       }
-
-       if ((thread_info->internal_flags & MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED) != 0) {
-               mono_debugger_unlock ();
-               return FALSE;
-       }
-
-       if (thread_info->exception_state.stopped_on_unhandled) {
-               thread_info->exception_state.stopped_on_unhandled = 0;
-               mono_debugger_unlock ();
-               return FALSE;
-       }
-
-       thread_info->exception_state.stopped_on_unhandled = 1;
-       thread_info->exception_state.last_exception = exc;
-
-       mono_debugger_event (MONO_DEBUGGER_EVENT_UNHANDLED_EXCEPTION,
-                            (guint64) (gsize) exc, (guint64) (gsize) addr);
-
-       return TRUE;
-#else
-       return FALSE;
-#endif
-}
-
-/*
- * mono_debugger_call_exception_handler:
- *
- * Called from mono_handle_exception_internal() to tell the debugger that we're about
- * to invoke an exception handler.
- *
- * The debugger may choose to set a breakpoint at @addr.  This is used if the user is
- * single-stepping from a `try' into a `catch' block, for instance.
- */
-
-void
-mono_debugger_call_exception_handler (gpointer addr, gpointer stack, MonoObject *exc)
-{
-#ifdef MONO_DEBUGGER_SUPPORTED
-       MonoDebuggerThreadInfo *thread_info;
-       MonoDebuggerExceptionInfo exc_info;
-
-       if (!mono_debug_using_mono_debugger ())
-               return;
-
-       mono_debugger_lock ();
-
-       thread_info = find_debugger_thread_info (mono_thread_internal_current ());
-       if (!thread_info) {
-               mono_debugger_unlock ();
-               return;
-       }
-
-       if ((thread_info->internal_flags & MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED) != 0) {
-               mono_debugger_unlock ();
-               return;
-       }
-
-       // Prevent the object from being finalized.
-       thread_info->exception_state.last_exception = exc;
-
-       exc_info.stack_pointer = stack;
-       exc_info.exception_obj = exc;
-       exc_info.stop = 0;
-       exc_info.stop_unhandled = 0;
-
-       mono_debugger_event (MONO_DEBUGGER_EVENT_HANDLE_EXCEPTION, (guint64) (gsize) &exc_info,
-                            (guint64) (gsize) addr);
-
-       mono_debugger_unlock ();
-#endif
-}
-
-#ifdef MONO_DEBUGGER_SUPPORTED
-
-static gchar *
-get_exception_message (MonoObject *exc)
-{
-       char *message = NULL;
-       MonoString *str; 
-       MonoMethod *method;
-       MonoClass *klass;
-       gint i;
-
-       if (mono_object_isinst (exc, mono_defaults.exception_class)) {
-               klass = exc->vtable->klass;
-               method = NULL;
-               while (klass && method == NULL) {
-                       for (i = 0; i < klass->method.count; ++i) {
-                               method = klass->methods [i];
-                               if (!strcmp ("ToString", method->name) &&
-                                   mono_method_signature (method)->param_count == 0 &&
-                                   method->flags & METHOD_ATTRIBUTE_VIRTUAL &&
-                                   method->flags & METHOD_ATTRIBUTE_PUBLIC) {
-                                       break;
-                               }
-                               method = NULL;
-                       }
-                       
-                       if (method == NULL)
-                               klass = klass->parent;
-               }
-
-               g_assert (method);
-
-               str = (MonoString *) mono_runtime_invoke (method, exc, NULL, NULL);
-               if (str)
-                       message = mono_string_to_utf8 (str);
-       }
-
-       return message;
-}
-
-MonoObject *
-mono_debugger_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc)
-{
-       MonoDebuggerThreadInfo *thread_info;
-       MonoDebuggerExceptionState saved_exception_state;
-       MonoObject *retval;
-       gchar *message;
-
-       mono_debugger_lock ();
-
-       thread_info = find_debugger_thread_info (mono_thread_internal_current ());
-       if (!thread_info) {
-               mono_debugger_unlock ();
-               return NULL;
-       }
-
-       saved_exception_state = thread_info->exception_state;
-
-       thread_info->exception_state.last_exception = NULL;
-       thread_info->exception_state.stopped_on_unhandled = 0;
-       thread_info->exception_state.stopped_on_exception = 0;
-
-       thread_info->internal_flags |= MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_IN_RUNTIME_INVOKE;
-
-       mono_debugger_unlock ();
-
-       if (!strcmp (method->name, ".ctor")) {
-               retval = obj = mono_object_new (mono_domain_get (), method->klass);
-
-               mono_runtime_invoke (method, obj, params, exc);
-       } else
-               retval = mono_runtime_invoke (method, obj, params, exc);
-
-       mono_debugger_lock ();
-
-       thread_info->exception_state = saved_exception_state;
-       thread_info->internal_flags &= ~MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_IN_RUNTIME_INVOKE;
-
-       if ((thread_info->internal_flags & MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED) != 0) {
-               thread_info->internal_flags &= ~MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED;
-               mono_thread_internal_reset_abort (thread_info->thread);
-
-               mono_debugger_unlock ();
-
-               *exc = NULL;
-               return NULL;
-       }
-
-       mono_debugger_unlock ();
-
-       if (!exc || (*exc == NULL))
-               return retval;
-
-       retval = *exc;
-       message = get_exception_message (*exc);
-       if (message) {
-               *exc = (MonoObject *) mono_string_new_wrapper (message);
-               g_free (message);
-       }
-
-       return retval;
-}
-
-gboolean
-mono_debugger_abort_runtime_invoke ()
-{
-       MonoInternalThread *thread = mono_thread_internal_current ();
-       MonoDebuggerThreadInfo *thread_info;
-
-       mono_debugger_lock ();
-
-       thread_info = find_debugger_thread_info (thread);
-       if (!thread_info) {
-               mono_debugger_unlock ();
-               return FALSE;
-       }
-
-       if ((thread_info->internal_flags & MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_IN_RUNTIME_INVOKE) == 0) {
-               mono_debugger_unlock ();
-               return FALSE;
-       }
-
-       if ((thread_info->internal_flags & MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED) != 0) {
-               mono_debugger_unlock ();
-               return TRUE;
-       }
-
-       thread_info->internal_flags |= MONO_DEBUGGER_INTERNAL_THREAD_FLAGS_ABORT_REQUESTED;
-       ves_icall_System_Threading_Thread_Abort (thread_info->thread, NULL);
-
-       mono_debugger_unlock ();
-       return TRUE;
-}
-
-#endif
diff --git a/mono/mini/debug-mini.h b/mono/mini/debug-mini.h
deleted file mode 100644 (file)
index 649c30c..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef __DEBUG_MINI_H__
-#define __DEBUG_MINI_H__
-
-#include <mono/metadata/class-internals.h>
-#include <mono/metadata/mono-debug-debugger.h>
-
-#include "mini.h"
-
-typedef struct _MonoDebuggerThreadInfo MonoDebuggerThreadInfo;
-extern MonoDebuggerThreadInfo *mono_debugger_thread_table;
-
-MONO_API void
-mono_debugger_thread_created (gsize tid, MonoThread *thread, MonoJitTlsData *jit_tls, gpointer func);
-
-MONO_API void
-mono_debugger_thread_cleanup (MonoJitTlsData *jit_tls);
-
-MONO_API void
-mono_debugger_extended_notification (MonoDebuggerEvent event, guint64 data, guint64 arg);
-
-MONO_API void
-mono_debugger_trampoline_compiled (const guint8 *trampoline, MonoMethod *method, const guint8 *code);
-
-MONO_API void
-mono_debugger_call_exception_handler (gpointer addr, gpointer stack, MonoObject *exc);
-
-MONO_API gboolean
-mono_debugger_handle_exception (MonoContext *ctx, MonoObject *obj);
-
-MONO_API MonoObject *
-mono_debugger_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **exc);
-
-MONO_API gboolean
-mono_debugger_abort_runtime_invoke (void);
-
-/*
- * Internal exception API.
- */
-
-typedef enum {
-       MONO_DEBUGGER_EXCEPTION_ACTION_NONE             = 0,
-       MONO_DEBUGGER_EXCEPTION_ACTION_STOP             = 1,
-       MONO_DEBUGGER_EXCEPTION_ACTION_STOP_UNHANDLED   = 2
-} MonoDebuggerExceptionAction;
-
-MonoDebuggerExceptionAction
-_mono_debugger_throw_exception (gpointer addr, gpointer stack, MonoObject *exc);
-
-gboolean
-_mono_debugger_unhandled_exception (gpointer addr, gpointer stack, MonoObject *exc);
-
-/*
- * This is the old breakpoint interface.
- * It isn't used by the debugger anymore, but still when using the `--break' command
- * line argument.
- */
-
-int             mono_debugger_insert_breakpoint_full      (MonoMethodDesc *desc);
-int             mono_debugger_remove_breakpoint           (int breakpoint_id);
-void            mono_debugger_breakpoint_callback         (MonoMethod *method, guint32 idx);
-
-#endif
index 0f9eaa79cb5ee81c0a1143791db24f4b16a8404a..4b509eb31b90b2369b856f7879b20ff3bcd27802 100755 (executable)
@@ -69,6 +69,7 @@ int WSAAPI getnameinfo(const struct sockaddr*,socklen_t,char*,DWORD,
 #include <mono/metadata/mono-debug-debugger.h>
 #include <mono/metadata/debug-mono-symfile.h>
 #include <mono/metadata/gc-internal.h>
+#include <mono/metadata/environment.h>
 #include <mono/metadata/threads-types.h>
 #include <mono/metadata/socket-io.h>
 #include <mono/metadata/assembly.h>
@@ -124,6 +125,7 @@ typedef struct {
        gboolean embedding;
        gboolean defer;
        int keepalive;
+       gboolean setpgid;
 } AgentConfig;
 
 typedef struct
@@ -283,7 +285,7 @@ typedef struct {
 #define HEADER_LENGTH 11
 
 #define MAJOR_VERSION 2
-#define MINOR_VERSION 25
+#define MINOR_VERSION 27
 
 typedef enum {
        CMD_SET_VM = 1,
@@ -367,7 +369,8 @@ typedef enum {
 typedef enum {
        STEP_FILTER_NONE = 0,
        STEP_FILTER_STATIC_CTOR = 1,
-       STEP_FILTER_DEBUGGER_HIDDEN = 2
+       STEP_FILTER_DEBUGGER_HIDDEN = 2,
+       STEP_FILTER_DEBUGGER_STEP_THROUGH = 4
 } StepFilter;
 
 typedef enum {
@@ -557,6 +560,8 @@ typedef struct {
        gboolean global;
        /* The list of breakpoints used to implement step-over */
        GSList *bps;
+       /* The number of frames at the start of a step-over */
+       int nframes;
 } SingleStepReq;
 
 /*
@@ -797,6 +802,7 @@ print_usage (void)
        fprintf (stderr, "  timeout=<n>\t\t\tTimeout for connecting in milliseconds.\n");
        fprintf (stderr, "  server=y/n\t\t\tWhether to listen for a client connection.\n");
        fprintf (stderr, "  keepalive=<n>\t\t\tSend keepalive events every n milliseconds.\n");
+       fprintf (stderr, "  setpgid=y/n\t\t\tWhether to call setpid(0, 0) after startup.\n");
        fprintf (stderr, "  help\t\t\t\tPrint this help.\n");
 }
 
@@ -871,6 +877,8 @@ mono_debugger_agent_parse_options (char *options)
                        agent_config.embedding = atoi (arg + 10) == 1;
                } else if (strncmp (arg, "keepalive=", 10) == 0) {
                        agent_config.keepalive = atoi (arg + 10);
+               } else if (strncmp (arg, "setpgid=", 8) == 0) {
+                       agent_config.setpgid = parse_flag ("setpgid", arg + 8);
                } else {
                        print_usage ();
                        exit (1);
@@ -984,6 +992,11 @@ mono_debugger_agent_init (void)
         */
        mini_get_debug_options ()->load_aot_jit_info_eagerly = TRUE;
 
+#ifdef HAVE_SETPGID
+       if (agent_config.setpgid)
+               setpgid (0, 0);
+#endif
+
        if (!agent_config.onuncaught && !agent_config.onthrow)
                finish_agent_init (TRUE);
 }
@@ -3454,6 +3467,32 @@ create_event_list (EventKind event, GPtrArray *reqs, MonoJitInfo *ji, EventInfo
                                                if (ji->dbg_hidden)
                                                        filtered = TRUE;
                                        }
+                                       if ((mod->data.filter & STEP_FILTER_DEBUGGER_STEP_THROUGH) && ji) {
+                                               MonoCustomAttrInfo *ainfo;
+                                               static MonoClass *klass;
+
+                                               if (!klass) {
+                                                       klass = mono_class_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerStepThroughAttribute");
+                                                       g_assert (klass);
+                                               }
+                                               if (!ji->dbg_step_through_inited) {
+                                                       ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji));
+                                                       if (ainfo) {
+                                                               if (mono_custom_attrs_has_attr (ainfo, klass))
+                                                                       ji->dbg_step_through = TRUE;
+                                                               mono_custom_attrs_free (ainfo);
+                                                       }
+                                                       ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass);
+                                                       if (ainfo) {
+                                                               if (mono_custom_attrs_has_attr (ainfo, klass))
+                                                                       ji->dbg_step_through = TRUE;
+                                                               mono_custom_attrs_free (ainfo);
+                                                       }
+                                                       ji->dbg_step_through_inited = TRUE;
+                                               }
+                                               if (ji->dbg_step_through)
+                                                       filtered = TRUE;
+                                       }
                                }
                        }
 
@@ -3614,6 +3653,8 @@ process_event (EventKind event, gpointer arg, gint32 il_offset, MonoContext *ctx
                        buffer_add_domainid (&buf, mono_get_root_domain ());
                        break;
                case EVENT_KIND_VM_DEATH:
+                       if (CHECK_PROTOCOL_VERSION (2, 27))
+                               buffer_add_int (&buf, mono_environment_exitcode_get ());
                        break;
                case EVENT_KIND_EXCEPTION: {
                        EventInfo *ei = arg;
@@ -4431,7 +4472,7 @@ clear_breakpoints_for_domain (MonoDomain *domain)
  * Return FALSE if single stepping needs to continue.
  */
 static gboolean
-ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp)
+ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp, DebuggerTlsData *tls, MonoContext *ctx)
 {
        MonoDebugMethodInfo *minfo;
        MonoDebugSourceLocation *loc = NULL;
@@ -4446,6 +4487,17 @@ ss_update (SingleStepReq *req, MonoJitInfo *ji, SeqPoint *sp)
                return FALSE;
        }
 
+       if (req->depth == STEP_DEPTH_OVER && hit) {
+               if (!tls->context.valid)
+                       mono_thread_state_init_from_monoctx (&tls->context, ctx);
+               compute_frame_info (tls->thread, tls);
+               if (req->nframes && tls->frame_count && tls->frame_count > req->nframes) {
+                       /* Hit the breakpoint in a recursive call */
+                       DEBUG (1, fprintf (log_file, "[%p] Breakpoint at lower frame while stepping over, continuing single stepping.\n", (gpointer)GetCurrentThreadId ()));
+                       return FALSE;
+               }
+       }
+
        if (req->size != STEP_SIZE_LINE)
                return TRUE;
 
@@ -4564,7 +4616,10 @@ process_breakpoint_inner (DebuggerTlsData *tls)
                SingleStepReq *ss_req = req->info;
                gboolean hit;
 
-               hit = ss_update (ss_req, ji, sp);
+               if (mono_thread_internal_current () != ss_req->thread)
+                       continue;
+
+               hit = ss_update (ss_req, ji, sp, tls, ctx);
                if (hit)
                        g_ptr_array_add (ss_reqs, req);
 
@@ -4781,7 +4836,7 @@ process_single_step_inner (DebuggerTlsData *tls)
                return;
        il_offset = sp->il_offset;
 
-       if (!ss_update (ss_req, ji, sp))
+       if (!ss_update (ss_req, ji, sp, tls, ctx))
                return;
 
        /* Start single stepping again from the current sequence point */
@@ -5028,6 +5083,8 @@ ss_start (SingleStepReq *ss_req, MonoMethod *method, SeqPoint *sp, MonoSeqPointI
                }
 
                if (ss_req->depth == STEP_DEPTH_OVER) {
+                       if (ss_req->nframes == 0)
+                               ss_req->nframes = tls->frame_count;
                        /* Need to stop in catch clauses as well */
                        for (i = 0; i < tls->frame_count; ++i) {
                                StackFrame *frame = tls->frames [i];
@@ -6280,39 +6337,7 @@ do_invoke_method (DebuggerTlsData *tls, Buffer *buf, InvokeData *invoke, guint8
 
                /* Setup our lmf */
                memset (&ext, 0, sizeof (ext));
-#ifdef TARGET_AMD64
-               ext.lmf.previous_lmf = *(lmf_addr);
-               /* Mark that this is a MonoLMFExt */
-               ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
-               ext.lmf.rsp = (gssize)&ext;
-#elif defined(TARGET_X86)
-               ext.lmf.previous_lmf = (gsize)*(lmf_addr);
-               /* Mark that this is a MonoLMFExt */
-               ext.lmf.previous_lmf = (gsize)(gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
-               ext.lmf.ebp = (gssize)&ext;
-#elif defined(TARGET_ARM)
-               ext.lmf.previous_lmf = *(lmf_addr);
-               /* Mark that this is a MonoLMFExt */
-               ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
-               ext.lmf.sp = (gssize)&ext;
-#elif defined(TARGET_POWERPC)
-               ext.lmf.previous_lmf = *(lmf_addr);
-               /* Mark that this is a MonoLMFExt */
-               ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
-               ext.lmf.ebp = (gssize)&ext;
-#elif defined(TARGET_S390X)
-               ext.lmf.previous_lmf = *(lmf_addr);
-               /* Mark that this is a MonoLMFExt */
-               ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
-               ext.lmf.ebp = (gssize)&ext;
-#elif defined(TARGET_MIPS)
-               ext.lmf.previous_lmf = *(lmf_addr);
-               /* Mark that this is a MonoLMFExt */
-               ext.lmf.previous_lmf = (gpointer)(((gssize)ext.lmf.previous_lmf) | 2);
-               ext.lmf.iregs [mips_sp] = (gssize)&ext;
-#else
-               g_assert_not_reached ();
-#endif
+               mono_arch_init_lmf_ext (&ext, *lmf_addr);
 
                ext.debugger_invoke = TRUE;
                memcpy (&ext.ctx, &invoke->ctx, sizeof (MonoContext));
@@ -6648,6 +6673,8 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf)
                        if (!mono_runtime_try_shutdown ())
                                break;
 
+                       mono_environment_exitcode_set (exit_code);
+
                        /* Suspend all managed threads since the runtime is going away */
                        DEBUG(1, fprintf (log_file, "Suspending all threads...\n"));
                        mono_thread_suspend_all_other_threads ();
@@ -6973,6 +7000,9 @@ event_commands (int command, guint8 *p, guint8 *end, Buffer *buf)
                                if (CHECK_PROTOCOL_VERSION (2, 16))
                                        filter = decode_int (p, &p, end);
                                req->modifiers [i].data.filter = filter;
+                               if (!CHECK_PROTOCOL_VERSION (2, 26) && (req->modifiers [i].data.filter & STEP_FILTER_DEBUGGER_HIDDEN))
+                                       /* Treat STEP_THOUGH the same as HIDDEN */
+                                       req->modifiers [i].data.filter |= STEP_FILTER_DEBUGGER_STEP_THROUGH;
                        } else if (mod == MOD_KIND_THREAD_ONLY) {
                                int id = decode_id (p, &p, end);
 
index 1bbdedb4307d9a26c657231173b7417f68be828c..88097b2257897627e388ca8babc88c40cddb2a88 100644 (file)
@@ -1361,6 +1361,71 @@ mono_decompose_vtype_opts (MonoCompile *cfg)
        }
 }
 
+void
+mono_decompose_vtype_opts_llvm (MonoCompile *cfg)
+{
+       MonoBasicBlock *bb, *first_bb;
+
+       /* Decompose only the OP_STOREV_MEMBASE opcodes, which need write barriers */
+
+       cfg->cbb = mono_mempool_alloc0 ((cfg)->mempool, sizeof (MonoBasicBlock));
+       first_bb = cfg->cbb;
+
+       for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
+               MonoInst *ins;
+               MonoInst *prev = NULL;
+               MonoInst *src_var, *src, *dest;
+               gboolean restart;
+               int dreg;
+
+               if (cfg->verbose_level > 2) mono_print_bb (bb, "BEFORE LOWER-VTYPE-OPTS(LLVM) ");
+
+               cfg->cbb->code = cfg->cbb->last_ins = NULL;
+               restart = TRUE;
+
+               while (restart) {
+                       restart = FALSE;
+
+                       for (ins = bb->code; ins; ins = ins->next) {
+                               switch (ins->opcode) {
+                               case OP_STOREV_MEMBASE: {
+                                       src_var = get_vreg_to_inst (cfg, ins->sreg1);
+
+                                       if (!src_var) {
+                                               g_assert (ins->klass);
+                                               src_var = mono_compile_create_var_for_vreg (cfg, &ins->klass->byval_arg, OP_LOCAL, ins->sreg1);
+                                       }
+
+                                       EMIT_NEW_VARLOADA_VREG ((cfg), (src), ins->sreg1, &ins->klass->byval_arg);
+
+                                       dreg = alloc_preg (cfg);
+                                       EMIT_NEW_BIALU_IMM (cfg, dest, OP_ADD_IMM, dreg, ins->inst_destbasereg, ins->inst_offset);
+                                       mini_emit_stobj (cfg, dest, src, src_var->klass, src_var->backend.is_pinvoke);
+                                       break;
+                               }
+                               default:
+                                       break;
+                               }
+
+                               g_assert (cfg->cbb == first_bb);
+
+                               if (cfg->cbb->code || (cfg->cbb != first_bb)) {
+                                       /* Replace the original instruction with the new code sequence */
+
+                                       mono_replace_ins (cfg, bb, ins, &prev, first_bb, cfg->cbb);
+                                       first_bb->code = first_bb->last_ins = NULL;
+                                       first_bb->in_count = first_bb->out_count = 0;
+                                       cfg->cbb = first_bb;
+                               }
+                               else
+                                       prev = ins;
+                       }
+               }
+
+               if (cfg->verbose_level > 2) mono_print_bb (bb, "AFTER LOWER-VTYPE-OPTS(LLVM) ");
+       }
+}
+
 inline static MonoInst *
 mono_get_domainvar (MonoCompile *cfg)
 {
@@ -1413,7 +1478,7 @@ mono_decompose_array_access_opts (MonoCompile *cfg)
                                switch (ins->opcode) {
                                case OP_LDLEN:
                                        NEW_LOAD_MEMBASE_FLAGS (cfg, dest, OP_LOADI4_MEMBASE, ins->dreg, ins->sreg1,
-                                                                                       G_STRUCT_OFFSET (MonoArray, max_length), ins->flags | MONO_INST_CONSTANT_LOAD);
+                                                                                       G_STRUCT_OFFSET (MonoArray, max_length), ins->flags | MONO_INST_INVARIANT_LOAD);
                                        MONO_ADD_INS (cfg->cbb, dest);
                                        break;
                                case OP_BOUNDS_CHECK:
@@ -1452,7 +1517,7 @@ mono_decompose_array_access_opts (MonoCompile *cfg)
                                        break;
                                case OP_STRLEN:
                                        MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS (cfg, OP_LOADI4_MEMBASE, ins->dreg,
-                                                                                                                ins->sreg1, G_STRUCT_OFFSET (MonoString, length), ins->flags | MONO_INST_CONSTANT_LOAD);
+                                                                                                                ins->sreg1, G_STRUCT_OFFSET (MonoString, length), ins->flags | MONO_INST_INVARIANT_LOAD);
                                        break;
                                default:
                                        break;
index 139f96ce68300d92debe69dd192a1e641df99899..bbf6f61740030159458f4ada24f5462e67e2813a 100644 (file)
@@ -137,6 +137,7 @@ extern char *nacl_mono_path;
     MONO_OPT_CMOV |  \
        MONO_OPT_GSHARED |      \
        MONO_OPT_SIMD | \
+       MONO_OPT_ALIAS_ANALYSIS | \
        MONO_OPT_AOT)
 
 #define EXCLUDED_FROM_ALL (MONO_OPT_SHARED | MONO_OPT_PRECOMP | MONO_OPT_UNSAFE | MONO_OPT_GSHAREDVT)
@@ -309,16 +310,19 @@ opt_sets [] = {
        MONO_OPT_BRANCH,
        MONO_OPT_CFOLD,
        MONO_OPT_FCMOV,
+       MONO_OPT_ALIAS_ANALYSIS,
 #ifdef MONO_ARCH_SIMD_INTRINSICS
        MONO_OPT_SIMD,
        MONO_OPT_SSE2,
        MONO_OPT_SIMD | MONO_OPT_SSE2,
 #endif
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_INTRINS,
+       MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_INTRINS | MONO_OPT_ALIAS_ANALYSIS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_CFOLD,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE,
+       MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_ALIAS_ANALYSIS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_TAILC,
        MONO_OPT_BRANCH | MONO_OPT_PEEPHOLE | MONO_OPT_LINEARS | MONO_OPT_COPYPROP | MONO_OPT_CONSPROP | MONO_OPT_DEADCE | MONO_OPT_LOOP | MONO_OPT_INLINE | MONO_OPT_INTRINS | MONO_OPT_SSA,
@@ -1282,9 +1286,6 @@ static const char info[] =
 #ifdef MONO_BIG_ARRAYS
        "bigarrays "
 #endif
-#ifdef MONO_DEBUGGER_SUPPORTED
-       "debugger "
-#endif
 #if defined(MONO_ARCH_SOFT_DEBUG_SUPPORTED) && !defined(DISABLE_SOFT_DEBUG)
        "softdebug "
 #endif
@@ -1853,9 +1854,6 @@ mono_main (int argc, char* argv[])
 #endif
 #endif
 
-       if ((action == DO_EXEC) && mono_debug_using_mono_debugger ())
-               action = DO_DEBUGGER;
-
        if (mono_compile_aot || action == DO_EXEC || action == DO_DEBUGGER) {
                g_set_prgname (argv[i]);
        }
@@ -1884,23 +1882,11 @@ mono_main (int argc, char* argv[])
 
        if (action == DO_DEBUGGER) {
                enable_debugging = TRUE;
-
-#ifdef MONO_DEBUGGER_SUPPORTED
-               mono_debug_init (MONO_DEBUG_FORMAT_DEBUGGER);
-#else
-               g_print ("The Mono Debugger is not supported on this platform.\n");
+               g_print ("The Mono Debugger is no longer supported.\n");
                return 1;
-#endif
        } else if (enable_debugging)
                mono_debug_init (MONO_DEBUG_FORMAT_MONO);
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-       if (enable_debugging) {
-               if ((opt & MONO_OPT_GSHARED) == 0)
-                       mini_debugger_set_attach_ok ();
-       }
-#endif
-
 #ifdef HOST_WIN32
        if (mixed_mode)
                mono_load_coree (argv [i]);
@@ -2059,22 +2045,7 @@ mono_main (int argc, char* argv[])
                mini_cleanup (domain);
                return 0;
        } else if (action == DO_DEBUGGER) {
-#ifdef MONO_DEBUGGER_SUPPORTED
-               const char *error;
-
-               error = mono_check_corlib_version ();
-               if (error) {
-                       fprintf (stderr, "Corlib not in sync with this runtime: %s\n", error);
-                       fprintf (stderr, "Download a newer corlib or a newer runtime at http://www.go-mono.com/daily.\n");
-                       exit (1);
-               }
-
-               mini_debugger_main (domain, assembly, argc - i, argv + i);
-               mini_cleanup (domain);
-               return 0;
-#else
                return 1;
-#endif
        }
        desc = mono_method_desc_new (mname, 0);
        if (!desc) {
index d00b7332e32e14199c9f43b69917f49f7c394042..a4f570c7834fd09131e26ec822682aa66e5f1075 100644 (file)
@@ -465,9 +465,6 @@ static int subprogram_attr [] = {
 
 static int tramp_subprogram_attr [] = {
        DW_AT_name         , DW_FORM_string,
-#ifndef TARGET_IOS
-       DW_AT_description  , DW_FORM_string,
-#endif
     DW_AT_low_pc       , DW_FORM_addr,
     DW_AT_high_pc      , DW_FORM_addr,
 };
@@ -994,7 +991,10 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra
        emit_pointer_value (w, 0);
        emit_pointer_value (w, 0);
        /* offset into .debug_line section */
-       emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0);
+       if (w->emit_line)
+               emit_symbol_diff (w, ".Ldebug_line_start", ".Ldebug_line_section_start", 0);
+       else
+               emit_pointer_value (w, 0);
 
        /* Base types */
        for (i = 0; i < G_N_ELEMENTS (basic_types); ++i) {
@@ -1011,14 +1011,6 @@ mono_dwarf_writer_emit_base_info (MonoDwarfWriter *w, GSList *base_unwind_progra
        emit_section_change (w, ".debug_loc", 0);
        emit_label (w, ".Ldebug_loc_start");
 
-       /* debug_line section */
-       /*
-        * We emit some info even if emit_line is FALSE, as the
-        * apple linker seems to require a .debug_line section.
-        */
-       if (!w->collect_line_info)
-               emit_line_number_info_begin (w);
-
        emit_cie (w);
 }
 
index b1384de0fd2574447fa3ebfd0a929717c65215e3..342920f1afe1a95942687b26ecedf6bdfbcaae6d 100644 (file)
@@ -37,7 +37,6 @@
 #include "mini.h"
 #include "mini-amd64.h"
 #include "tasklets.h"
-#include "debug-mini.h"
 
 #define ALIGN_TO(val,align) (((val) + ((align) - 1)) & ~((align) - 1))
 
@@ -47,13 +46,13 @@ static MonoW32ExceptionHandler ill_handler;
 static MonoW32ExceptionHandler segv_handler;
 
 LPTOP_LEVEL_EXCEPTION_FILTER mono_old_win_toplevel_exception_filter;
-guint64 mono_win_vectored_exception_handle;
+void *mono_win_vectored_exception_handle;
 extern gboolean mono_win_chained_exception_needs_run;
 
 #define W32_SEH_HANDLE_EX(_ex) \
        if (_ex##_handler) _ex##_handler(0, ep, sctx)
 
-LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
+static LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
 {
 #ifndef MONO_CROSS_COMPILE
        if (mono_old_win_toplevel_exception_filter) {
@@ -70,7 +69,7 @@ LONG CALLBACK seh_unhandled_exception_filter(EXCEPTION_POINTERS* ep)
  * Unhandled Exception Filter
  * Top-level per-process exception handler.
  */
-LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
+static LONG CALLBACK seh_vectored_exception_handler(EXCEPTION_POINTERS* ep)
 {
        EXCEPTION_RECORD* er;
        CONTEXT* ctx;
@@ -161,10 +160,10 @@ void win32_seh_init()
 
 void win32_seh_cleanup()
 {
-       if (mono_old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter);
-
        guint32 ret = 0;
 
+       if (mono_old_win_toplevel_exception_filter) SetUnhandledExceptionFilter(mono_old_win_toplevel_exception_filter);
+
        ret = RemoveVectoredExceptionHandler (mono_win_vectored_exception_handle);
        g_assert (ret);
 }
@@ -369,22 +368,6 @@ mono_amd64_throw_exception (guint64 dummy1, guint64 dummy2, guint64 dummy3, guin
                        mono_ex->stack_trace = NULL;
        }
 
-       if (mono_debug_using_mono_debugger ()) {
-               guint8 buf [16];
-
-               mono_breakpoint_clean_code (NULL, (gpointer)rip, 8, buf, sizeof (buf));
-
-               if (buf [3] == 0xe8) {
-                       MonoContext ctx_cp = ctx;
-                       ctx_cp.rip = rip - 5;
-
-                       if (mono_debugger_handle_exception (&ctx_cp, exc)) {
-                               mono_restore_context (&ctx_cp);
-                               g_assert_not_reached ();
-                       }
-               }
-       }
-
        /* adjust eip so that it point into the call instruction */
        ctx.rip -= 1;
 
@@ -617,6 +600,11 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                frame->unwind_info = unwind_info;
                frame->unwind_info_len = unwind_info_len;
+
+               /*
+               printf ("%s %p %p\n", ji->d.method->name, ji->code_start, ip);
+               mono_print_unwind_info (unwind_info, unwind_info_len);
+               */
  
                regs [AMD64_RAX] = new_ctx->rax;
                regs [AMD64_RBX] = new_ctx->rbx;
@@ -659,7 +647,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                if (*lmf && ((*lmf) != jit_tls->first_lmf) && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->rsp)) {
                        /* remove any unused lmf */
-                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~3);
+                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~7);
                }
 
 #ifndef MONO_AMD64_NO_PUSHES
@@ -683,7 +671,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
                        memcpy (new_ctx, &ext->ctx, sizeof (MonoContext));
 
-                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~3);
+                       *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~7);
 
                        frame->type = FRAME_TYPE_DEBUGGER_INVOKE;
 
@@ -724,17 +712,36 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                new_ctx->rbp = (*lmf)->rbp;
                new_ctx->rsp = (*lmf)->rsp;
 
-               new_ctx->rbx = (*lmf)->rbx;
-               new_ctx->r12 = (*lmf)->r12;
-               new_ctx->r13 = (*lmf)->r13;
-               new_ctx->r14 = (*lmf)->r14;
-               new_ctx->r15 = (*lmf)->r15;
+               if (((guint64)(*lmf)->previous_lmf) & 4) {
+                       MonoLMFTramp *ext = (MonoLMFTramp*)(*lmf);
+
+                       /* Trampoline frame */
+                       new_ctx->rbx = ext->regs [AMD64_RBX];
+                       new_ctx->r12 = ext->regs [AMD64_R12];
+                       new_ctx->r13 = ext->regs [AMD64_R13];
+                       new_ctx->r14 = ext->regs [AMD64_R14];
+                       new_ctx->r15 = ext->regs [AMD64_R15];
 #ifdef TARGET_WIN32
-               new_ctx->rdi = (*lmf)->rdi;
-               new_ctx->rsi = (*lmf)->rsi;
+                       new_ctx->rdi = ext->regs [AMD64_RDI];
+                       new_ctx->rsi = ext->regs [AMD64_RSI];
 #endif
+               } else {
+                       /*
+                        * The registers saved in the LMF will be restored using the normal unwind info,
+                        * when the wrapper frame is processed.
+                        */
+                       new_ctx->rbx = 0;
+                       new_ctx->r12 = 0;
+                       new_ctx->r13 = 0;
+                       new_ctx->r14 = 0;
+                       new_ctx->r15 = 0;
+#ifdef TARGET_WIN32
+                       new_ctx->rdi = 0;
+                       new_ctx->rsi = 0;
+#endif
+               }
 
-               *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~3);
+               *lmf = (gpointer)(((guint64)(*lmf)->previous_lmf) & ~7);
 
                return TRUE;
        }
@@ -755,9 +762,6 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
-       if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj))
-               return;
-
        mono_handle_exception (&ctx, obj);
 
        mono_restore_context (&ctx);
@@ -775,6 +779,10 @@ mono_arch_setup_async_callback (MonoContext *ctx, void (*async_cb)(void *fun), g
        /* The stack should be unaligned */
        if ((sp % 16) == 0)
                sp -= 8;
+#ifdef __linux__
+       /* Preserve the call chain to prevent crashes in the libgcc unwinder (#15969) */
+       *(guint64*)sp = ctx->rip;
+#endif
        ctx->rsp = sp;
        ctx->rip = (guint64)async_cb;
 }
@@ -811,9 +819,6 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
 
        mono_arch_sigctx_to_monoctx (sigctx, &mctx);
 
-       if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj))
-               return TRUE;
-
        mono_handle_exception (&mctx, obj);
 
        mono_arch_monoctx_to_sigctx (&mctx, sigctx);
@@ -880,12 +885,6 @@ altstack_handle_and_restore (void *sigctx, gpointer obj, gboolean stack_ovf)
 
        mono_arch_sigctx_to_monoctx (sigctx, &mctx);
 
-       if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) {
-               if (stack_ovf)
-                       prepare_for_guard_pages (&mctx);
-               mono_restore_context (&mctx);
-       }
-
        mono_handle_exception (&mctx, obj);
        if (stack_ovf)
                prepare_for_guard_pages (&mctx);
@@ -1345,7 +1344,7 @@ mono_arch_unwindinfo_get_size (gpointer monoui)
                (sizeof (UNWIND_CODE) * (MONO_MAX_UNWIND_CODES - unwindinfo->unwindInfo.CountOfCodes));
 }
 
-PRUNTIME_FUNCTION
+static PRUNTIME_FUNCTION
 MONO_GET_RUNTIME_FUNCTION_CALLBACK ( DWORD64 ControlPc, IN PVOID Context )
 {
        MonoJitInfo *ji;
index a76f28207464fdf2a8772202bcd0402a7a6a6b02..8228280a9f1dc2315b960ed93ce5d6e81a083726 100644 (file)
@@ -60,10 +60,10 @@ mono_arch_get_restore_context (MonoTrampInfo **info, gboolean aot)
 
        ctx_reg = ARMREG_R0;
 
-#if defined(ARM_FPU_VFP)
-       ARM_ADD_REG_IMM8 (code, ARMREG_IP, ctx_reg, G_STRUCT_OFFSET (MonoContext, fregs));
-       ARM_FLDMD (code, ARM_VFP_D0, 16, ARMREG_IP);
-#endif
+       if (!mono_arch_is_soft_float ()) {
+               ARM_ADD_REG_IMM8 (code, ARMREG_IP, ctx_reg, G_STRUCT_OFFSET (MonoContext, fregs));
+               ARM_FLDMD (code, ARM_VFP_D0, 16, ARMREG_IP);
+       }
 
        /* move pc to PC */
        ARM_LDR_IMM (code, ARMREG_IP, ctx_reg, G_STRUCT_OFFSET (MonoContext, pc));
@@ -216,12 +216,12 @@ get_throw_trampoline (int size, gboolean corlib, gboolean rethrow, gboolean llvm
        mono_add_unwind_op_offset (unwind_ops, code, start, ARMREG_LR, - sizeof (mgreg_t));
 
        /* Save fp regs */
-       ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, sizeof (double) * 16);
-       cfa_offset += sizeof (double) * 16;
-       mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, cfa_offset);
-#if defined(ARM_FPU_VFP)
-       ARM_FSTMD (code, ARM_VFP_D0, 16, ARMREG_SP);
-#endif
+       if (!mono_arch_is_soft_float ()) {
+               ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, sizeof (double) * 16);
+               cfa_offset += sizeof (double) * 16;
+               mono_add_unwind_op_def_cfa_offset (unwind_ops, code, start, cfa_offset);
+               ARM_FSTMD (code, ARM_VFP_D0, 16, ARMREG_SP);
+       }
 
        /* Param area */
        ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, 8);
@@ -394,7 +394,7 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
 
        if (ji != NULL) {
                int i;
-               gssize regs [MONO_MAX_IREGS + 1];
+               gssize regs [MONO_MAX_IREGS + 1 + 8];
                guint8 *cfa;
                guint32 unwind_info_len;
                guint8 *unwind_info;
@@ -406,18 +406,32 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                else
                        unwind_info = mono_get_cached_unwind_info (ji->used_regs, &unwind_info_len);
 
+               /*
+               printf ("%s %p %p\n", ji->d.method->name, ji->code_start, ip);
+               mono_print_unwind_info (unwind_info, unwind_info_len);
+               */
+
                for (i = 0; i < 16; ++i)
                        regs [i] = new_ctx->regs [i];
+#ifdef TARGET_IOS
+               /* On IOS, d8..d15 are callee saved. They are mapped to 8..15 in unwind.c */
+               for (i = 0; i < 8; ++i)
+                       regs [MONO_MAX_IREGS + i] = new_ctx->fregs [8 + i];
+#endif
 
                mono_unwind_frame (unwind_info, unwind_info_len, ji->code_start, 
                                                   (guint8*)ji->code_start + ji->code_size,
-                                                  ip, regs, MONO_MAX_IREGS,
+                                                  ip, regs, MONO_MAX_IREGS + 8,
                                                   save_locations, MONO_MAX_IREGS, &cfa);
 
                for (i = 0; i < 16; ++i)
                        new_ctx->regs [i] = regs [i];
                new_ctx->pc = regs [ARMREG_LR];
                new_ctx->regs [ARMREG_SP] = (gsize)cfa;
+#ifdef TARGET_IOS
+               for (i = 0; i < 8; ++i)
+                       new_ctx->fregs [8 + i] = regs [MONO_MAX_IREGS + i];
+#endif
 
                if (*lmf && (MONO_CONTEXT_GET_SP (ctx) >= (gpointer)(*lmf)->sp)) {
                        /* remove any unused lmf */
index 8c1222c42ec26e37e75bf5fda057e4d588357d76..531b556e8c0442a9a7ac261fdafd9c5f2d5879e1 100644 (file)
@@ -32,7 +32,6 @@
 #include "mini.h"
 #include "mini-x86.h"
 #include "tasklets.h"
-#include "debug-mini.h"
 
 static gpointer signal_exception_trampoline;
 
@@ -496,23 +495,6 @@ mono_x86_throw_exception (mgreg_t *regs, MonoObject *exc,
                        mono_ex->stack_trace = NULL;
        }
 
-       if (mono_debug_using_mono_debugger ()) {
-               guint8 buf [16], *code;
-
-               mono_breakpoint_clean_code (NULL, (gpointer)eip, 8, buf, sizeof (buf));
-               code = buf + 8;
-
-               if (buf [3] == 0xe8) {
-                       MonoContext ctx_cp = ctx;
-                       ctx_cp.eip = eip - 5;
-
-                       if (mono_debugger_handle_exception (&ctx_cp, exc)) {
-                               mono_restore_context (&ctx_cp);
-                               g_assert_not_reached ();
-                       }
-               }
-       }
-
        /* adjust eip so that it point into the call instruction */
        ctx.eip -= 1;
 
@@ -855,9 +837,19 @@ mono_arch_find_jit_info (MonoDomain *domain, MonoJitTlsData *jit_tls,
                /* Adjust IP */
                new_ctx->eip --;
 
-               if (*lmf && (MONO_CONTEXT_GET_BP (ctx) >= (gpointer)(*lmf)->ebp)) {
-                       /* remove any unused lmf */
-                       *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3);
+               if (*lmf && ((*lmf) != jit_tls->first_lmf)) {
+                       gboolean is_tramp = ((guint32)((*lmf)->previous_lmf) & 1);
+                       gpointer lmf_esp;
+
+                       if (is_tramp)
+                               /* lmf->esp is only set in trampoline frames */
+                               lmf_esp = (gpointer)(*lmf)->esp;
+                       else
+                               /* In non-trampoline frames, ebp is the frame pointer */
+                               lmf_esp = (gpointer)(*lmf)->ebp;
+                       if (MONO_CONTEXT_GET_SP (ctx) >= lmf_esp)
+                               /* remove any unused lmf */
+                               *lmf = (gpointer)(((gsize)(*lmf)->previous_lmf) & ~3);
                }
 
                /* Pop arguments off the stack */
@@ -988,9 +980,6 @@ handle_signal_exception (gpointer obj)
 
        memcpy (&ctx, &jit_tls->ex_ctx, sizeof (MonoContext));
 
-       if (mono_debugger_handle_exception (&ctx, (MonoObject *)obj))
-               return;
-
        mono_handle_exception (&ctx, obj);
 
        mono_restore_context (&ctx);
@@ -1101,9 +1090,6 @@ mono_arch_handle_exception (void *sigctx, gpointer obj)
 
        mono_arch_sigctx_to_monoctx (sigctx, &mctx);
 
-       if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj))
-               return TRUE;
-
        mono_handle_exception (&mctx, obj);
 
        mono_arch_monoctx_to_sigctx (&mctx, sigctx);
@@ -1145,12 +1131,6 @@ altstack_handle_and_restore (MonoContext *ctx, gpointer obj, gboolean stack_ovf)
 
        mctx = *ctx;
 
-       if (mono_debugger_handle_exception (&mctx, (MonoObject *)obj)) {
-               if (stack_ovf)
-                       prepare_for_guard_pages (&mctx);
-               mono_restore_context (&mctx);
-       }
-
        mono_handle_exception (&mctx, obj);
        if (stack_ovf)
                prepare_for_guard_pages (&mctx);
index 49dca8d1ba12e720ceb0b07cf3fd67595e88c161..8144641273d407f1f930cdafbfc6250a9176894f 100644 (file)
@@ -24,11 +24,18 @@ using System.Runtime.CompilerServices;
  * the IL code looks.
  */
 
-class Tests {
-
+#if MOBILE
+class ExceptionTests
+#else
+class Tests
+#endif
+{
+
+#if !MOBILE
        public static int Main (string[] args) {
                return TestDriver.RunTests (typeof (Tests), args);
        }
+#endif
 
        public static int test_0_catch () {
                Exception x = new Exception ();
@@ -2408,7 +2415,7 @@ class Tests {
        }
 
        public static int test_0_nonvirt_nullref_at_clause_start () {
-               Tests t = null;
+               ExceptionTests t = null;
                try {
                        t.amethod ();
                } catch (NullReferenceException) {
@@ -2528,7 +2535,11 @@ class Tests {
        public static int test_0_lmf_filter () {
                try {
                        // The invoke calls a runtime-invoke wrapper which has a filter clause
+#if MOBILE
+                       typeof (ExceptionTests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
+#else
                        typeof (Tests).GetMethod ("lmf_filter").Invoke (null, new object [] { });
+#endif
                } catch (TargetInvocationException) {
                }
                return 0;
@@ -2732,3 +2743,8 @@ class Tests {
        }
 }
 
+#if !MOBILE
+class ExceptionTests : Tests
+{
+}
+#endif
\ No newline at end of file
index 09917f93e4b9b8e39a157fc5c540da1bf0ae0d88..d9b0adec2f1341ec9f7a076d8c2231d5bef07b97 100644 (file)
@@ -195,15 +195,15 @@ mono_print_label (FILE *fp, MonoInst *tree) {
                mono_print_label (fp, tree->inst_newa_len);
                break;
        case OP_CALL:
-       case OP_CALLVIRT:
+       case OP_CALL_MEMBASE:
        case OP_FCALL:
-       case OP_FCALLVIRT:
+       case OP_FCALL_MEMBASE:
        case OP_LCALL:
-       case OP_LCALLVIRT:
+       case OP_LCALL_MEMBASE:
        case OP_VCALL:
-       case OP_VCALLVIRT:
+       case OP_VCALL_MEMBASE:
        case OP_VOIDCALL:
-       case OP_VOIDCALLVIRT: {
+       case OP_VOIDCALL_MEMBASE: {
                MonoCallInst *call = (MonoCallInst*)tree;
                if (call->method) {
                        if (mono_method_signature (call->method)->hasthis && tree->inst_left) {
index 8ea5c06d27d9cd60facb5d53be76dccae498183f..2ed020c9ce00b9cb53f4032c0b83dece0b4b173c 100644 (file)
@@ -348,7 +348,7 @@ PASS:       ldc.i4.0
         IL_000a:  ret
     }
 
-       // Check that localloc can't be inlined
+       // Check that localloc cannot be inlined
        .method static public int32 test_0_localloc_inline () cil managed {
                .maxstack 16
                .locals init (
@@ -967,6 +967,15 @@ COND:   ldloc.0
                ret
        }
 
+       .method public static int32 test_1234_fconv_u () cil managed {
+               .maxstack 16
+
+               ldc.r8 1234.0
+               conv.u
+               conv.i4
+               ret
+       }
+
        .method public static int32 test_0_get_type_from_handle_on_bblock_boundary () cil managed 
        {
                .maxstack 16
index 9554e569c219f18e38606c943ebe00a7cddede60..c06a4c425516fd61b48664c4649850531b7e6d22 100644 (file)
 #define USE_ELF_WRITER 1
 #endif
 
-#if defined(USE_ELF_WRITER)
+#if defined(TARGET_X86) && defined(__APPLE__)
+#define USE_MACH_WRITER
+#endif
+
+#if defined(USE_ELF_WRITER) || defined(USE_MACH_WRITER)
 #define USE_BIN_WRITER 1
 #endif
 
@@ -481,6 +485,206 @@ bin_writer_emit_zero_bytes (MonoImageWriter *acfg, int num)
        acfg->cur_section->cur_offset += num;
 }
 
+static void
+bin_writer_fwrite (MonoImageWriter *acfg, void *val, size_t size, size_t nmemb)
+{
+       if (acfg->fp)
+               fwrite (val, size, nmemb, acfg->fp);
+       else {
+               g_assert (acfg->out_buf_pos + (size * nmemb) <= acfg->out_buf_size);
+               memcpy (acfg->out_buf + acfg->out_buf_pos, val, size * nmemb);
+               acfg->out_buf_pos += (size * nmemb);
+       }
+}
+
+static void
+bin_writer_fseek (MonoImageWriter *acfg, int offset)
+{
+       if (acfg->fp)
+               fseek (acfg->fp, offset, SEEK_SET);
+       else
+               acfg->out_buf_pos = offset;
+}
+
+#ifdef USE_MACH_WRITER
+
+/*
+ * This is a minimal implementation designed to support xdebug on 32 bit osx
+ * FIXME: 64 bit support
+ */
+
+#include <mach-o/loader.h>
+
+static gsize
+get_label_addr (MonoImageWriter *acfg, const char *name)
+{
+       int offset;
+       BinLabel *lab;
+       BinSection *section;
+       gsize value;
+
+       lab = g_hash_table_lookup (acfg->labels, name);
+       if (!lab)
+               g_error ("Undefined label: '%s'.\n", name);
+       section = lab->section;
+       offset = lab->offset;
+       if (section->parent) {
+               value = section->parent->virt_offset + section->cur_offset + offset;
+       } else {
+               value = section->virt_offset + offset;
+       }
+       return value;
+}
+
+
+static void
+resolve_reloc (MonoImageWriter *acfg, BinReloc *reloc, guint8 **out_data, gsize *out_vaddr, gsize *out_start_val, gsize *out_end_val)
+{
+       guint8 *data;
+       gssize end_val, start_val;
+       gsize vaddr;
+
+       end_val = get_label_addr (acfg, reloc->val1);
+       if (reloc->val2) {
+               start_val = get_label_addr (acfg, reloc->val2);
+       } else if (reloc->val2_section) {
+               start_val = reloc->val2_offset;
+               if (reloc->val2_section->parent)
+                       start_val += reloc->val2_section->parent->virt_offset + reloc->val2_section->cur_offset;
+               else
+                       start_val += reloc->val2_section->virt_offset;
+       } else {
+               start_val = 0;
+       }
+       end_val = end_val - start_val + reloc->offset;
+       if (reloc->section->parent) {
+               data = reloc->section->parent->data;
+               data += reloc->section->cur_offset;
+               data += reloc->section_offset;
+               vaddr = reloc->section->parent->virt_offset;
+               vaddr += reloc->section->cur_offset;
+               vaddr += reloc->section_offset;
+       } else {
+               data = reloc->section->data;
+               data += reloc->section_offset;
+               vaddr = reloc->section->virt_offset;
+               vaddr += reloc->section_offset;
+       }
+
+       *out_start_val = start_val;
+       *out_end_val = end_val;
+       *out_data = data;
+       *out_vaddr = vaddr;
+}
+
+static void
+resolve_relocations (MonoImageWriter *acfg)
+{
+       BinReloc *reloc;
+       guint8 *data;
+       gsize end_val, start_val;
+       gsize vaddr;
+
+       /* Only resolve static relocations */
+       for (reloc = acfg->relocations; reloc; reloc = reloc->next) {
+               resolve_reloc (acfg, reloc, &data, &vaddr, &start_val, &end_val);
+               data [0] = end_val;
+               data [1] = end_val >> 8;
+               data [2] = end_val >> 16;
+               data [3] = end_val >> 24;
+       }
+}
+
+static int
+bin_writer_emit_writeout (MonoImageWriter *acfg)
+{
+       BinSection *s;
+       int sindex, file_size, nsections, file_offset, vmaddr;
+       struct mach_header header;
+       struct segment_command segment;
+       struct section *sections;
+
+       /* Assing vm addresses to sections */
+       nsections = 0;
+       vmaddr = 0;
+       for (s = acfg->sections; s; s = s->next) {
+               s->virt_offset = vmaddr;
+               vmaddr += s->cur_offset;
+               nsections ++;
+       }
+
+       resolve_relocations (acfg);
+
+       file_offset = 0;
+
+       memset (&header, 0, sizeof (header));
+       header.magic = MH_MAGIC;
+       header.cputype = CPU_TYPE_X86;
+       header.cpusubtype = CPU_SUBTYPE_X86_ALL;
+       header.filetype = MH_OBJECT;
+       header.ncmds = 0;
+       header.sizeofcmds = 0;
+       header.flags = 0;
+
+       file_offset += sizeof (header);
+
+       memset (&segment, 0, sizeof (segment));
+       segment.cmd = LC_SEGMENT;
+       segment.cmdsize = sizeof (segment);
+       segment.maxprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
+       segment.initprot = VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE;
+
+       file_offset += sizeof (segment);
+       file_offset += nsections * sizeof (struct section);
+
+       sections = g_new0 (struct section, nsections);
+       sindex = 0;
+       for (s = acfg->sections; s; s = s->next) {
+               s->file_offset = file_offset;
+
+               /* .debug_line -> __debug_line */
+               sprintf (sections [sindex].sectname, "__%s", s->name + 1);
+               sprintf (sections [sindex].segname, "%s", "__DWARF");
+               sections [sindex].addr = s->virt_offset;
+               sections [sindex].size = s->cur_offset;
+               sections [sindex].offset = s->file_offset;
+
+               file_offset += s->cur_offset;
+
+               segment.nsects ++;
+               segment.cmdsize += sizeof (struct section);
+
+               sindex ++;
+       }
+
+       header.ncmds ++;
+       header.sizeofcmds += segment.cmdsize;
+
+       /* Emit data */
+       file_size = file_offset;
+
+       if (!acfg->fp) {
+               acfg->out_buf_size = file_size;
+               acfg->out_buf = g_malloc (acfg->out_buf_size);
+       }
+
+       bin_writer_fwrite (acfg, &header, sizeof (header), 1);
+       bin_writer_fwrite (acfg, &segment, sizeof (segment), 1);
+       bin_writer_fwrite (acfg, sections, sizeof (struct section), nsections);
+       for (s = acfg->sections; s; s = s->next) {
+               if (!acfg->fp)
+                       g_assert (acfg->out_buf_pos == s->file_offset);
+               bin_writer_fwrite (acfg, s->data, s->cur_offset, 1);
+       }
+
+       if (acfg->fp)
+               fclose (acfg->fp);
+
+       return 0;
+}
+
+#endif
+
 #ifdef USE_ELF_WRITER
 
 enum {
@@ -1042,27 +1246,6 @@ resolve_relocations (MonoImageWriter *acfg)
 
 #endif /* USE_ELF_RELA */
 
-static void
-bin_writer_fwrite (MonoImageWriter *acfg, void *val, size_t size, size_t nmemb)
-{
-       if (acfg->fp)
-               fwrite (val, size, nmemb, acfg->fp);
-       else {
-               g_assert (acfg->out_buf_pos + (size * nmemb) <= acfg->out_buf_size);
-               memcpy (acfg->out_buf + acfg->out_buf_pos, val, size * nmemb);
-               acfg->out_buf_pos += (size * nmemb);
-       }
-}
-
-static void
-bin_writer_fseek (MonoImageWriter *acfg, int offset)
-{
-       if (acfg->fp)
-               fseek (acfg->fp, offset, SEEK_SET);
-       else
-               acfg->out_buf_pos = offset;
-}
-
 static int normal_sections [] = { SECT_DATA, SECT_DEBUG_FRAME, SECT_DEBUG_INFO, SECT_DEBUG_ABBREV, SECT_DEBUG_LINE, SECT_DEBUG_LOC };
 
 static int
index 27954bf2e13cee23d018eebeccf609efef456c3a..1af3871966bfd1d69adbfcc03015de6d24247810 100644 (file)
@@ -337,6 +337,7 @@ handle_gsharedvt_ldaddr (MonoCompile *cfg)
                (dest)->type = STACK_MP;        \
                (dest)->klass = (var)->klass;   \
         (dest)->dreg = alloc_dreg ((cfg), STACK_MP); \
+               (cfg)->has_indirection = TRUE;  \
                          if (G_UNLIKELY (cfg->gsharedvt) && mini_is_gsharedvt_variable_type ((cfg), (var)->inst_vtype)) { handle_gsharedvt_ldaddr ((cfg)); } \
                if (SIZEOF_REGISTER == 4 && DECOMPOSE_INTO_REGPAIR ((var)->type)) { MonoInst *var1 = get_vreg_to_inst (cfg, (var)->dreg + 1); MonoInst *var2 = get_vreg_to_inst (cfg, (var)->dreg + 2); g_assert (var1); g_assert (var2); var1->flags |= MONO_INST_INDIRECT; var2->flags |= MONO_INST_INDIRECT; } \
        } while (0)
@@ -834,8 +835,6 @@ static int ccount = 0;
 
 /* Loads/Stores which can fault are handled correctly by the LLVM mono branch */
 #define MONO_EMIT_NEW_IMPLICIT_EXCEPTION_LOAD_STORE(cfg) do { \
-       if (COMPILE_LLVM (cfg) && !IS_LLVM_MONO_BRANCH)                 \
-               MONO_EMIT_NEW_IMPLICIT_EXCEPTION ((cfg));                       \
     } while (0)
 
 /* Emit an explicit null check which doesn't depend on SIGSEGV signal handling */
@@ -863,8 +862,6 @@ static int ccount = 0;
                int __ins_flags = ins_flags; \
                if (__ins_flags & MONO_INST_FAULT) {                                                            \
                        MONO_EMIT_NULL_CHECK ((cfg), (base));                                           \
-                       if (cfg->explicit_null_checks)                                                          \
-                               __ins_flags &= ~MONO_INST_FAULT;                                                        \
                }                                                                                                                               \
                NEW_LOAD_MEMBASE ((cfg), (dest), (op), (dr), (base), (offset)); \
                (dest)->flags = (__ins_flags);                                                                  \
@@ -875,8 +872,6 @@ static int ccount = 0;
                int __ins_flags = ins_flags; \
            if (__ins_flags & MONO_INST_FAULT) {                                                                        \
                        MONO_EMIT_NULL_CHECK ((cfg), (base));                                           \
-                       if (cfg->explicit_null_checks)                                                          \
-                               __ins_flags &= ~MONO_INST_FAULT;                                                        \
                }                                                                                                                               \
                NEW_LOAD_MEMBASE ((cfg), (inst), (op), (dr), (base), (offset)); \
                inst->flags = (__ins_flags); \
@@ -897,6 +892,12 @@ static int ccount = 0;
 
 #define MONO_EMIT_NEW_LOAD_MEMBASE_FAULT(cfg,dr,base,offset) MONO_EMIT_NEW_LOAD_MEMBASE_OP_FAULT ((cfg), (OP_LOAD_MEMBASE), (dr), (base), (offset))
 
+#define NEW_LOAD_MEMBASE_INVARIANT(cfg,dest,op,dr,base,offset) NEW_LOAD_MEMBASE_FLAGS ((cfg), (dest), (op), (dr), (base), (offset), MONO_INST_INVARIANT_LOAD)
+
+#define MONO_EMIT_NEW_LOAD_MEMBASE_OP_INVARIANT(cfg,op,dr,base,offset) MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS ((cfg), (op), (dr), (base), (offset), MONO_INST_INVARIANT_LOAD)
+
+#define MONO_EMIT_NEW_LOAD_MEMBASE_INVARIANT(cfg,dr,base,offset) MONO_EMIT_NEW_LOAD_MEMBASE_OP_INVARIANT ((cfg), (OP_LOAD_MEMBASE), (dr), (base), (offset))
+
 /*Object Model related macros*/
 
 /* Default bounds check implementation for most architectures + llvm */
@@ -905,7 +906,7 @@ static int ccount = 0;
                        if (fault) \
                                MONO_EMIT_NEW_LOAD_MEMBASE_OP_FAULT (cfg, OP_LOADI4_MEMBASE, _length_reg, array_reg, offset); \
                        else \
-                               MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS (cfg, OP_LOADI4_MEMBASE, _length_reg, array_reg, offset, MONO_INST_CONSTANT_LOAD); \
+                               MONO_EMIT_NEW_LOAD_MEMBASE_OP_FLAGS (cfg, OP_LOADI4_MEMBASE, _length_reg, array_reg, offset, MONO_INST_INVARIANT_LOAD); \
                        MONO_EMIT_NEW_BIALU (cfg, OP_COMPARE, -1, _length_reg, index_reg); \
                        MONO_EMIT_NEW_COND_EXC (cfg, LE_UN, "IndexOutOfRangeException"); \
        } while (0)
index 02e3c0857f49698c9b8bfb351c1032bebc9fff9c..a5cbabb53a53333dd2ecf2a2cfd1012bb780d507 100644 (file)
@@ -219,7 +219,8 @@ analyze_liveness_bb (MonoCompile *cfg, MonoBasicBlock *bb)
        MonoMethodVar *vars = cfg->vars;
        guint32 abs_pos = (bb->dfn << 16);
        
-       for (inst_num = 0, ins = bb->code; ins; ins = ins->next, inst_num += 2) {
+       /* Start inst_num from > 0, so last_use.abs_pos is only 0 for dead variables */
+       for (inst_num = 2, ins = bb->code; ins; ins = ins->next, inst_num += 2) {
                const char *spec = INS_INFO (ins->opcode);
                int num_sregs, i;
                int sregs [MONO_MAX_SRC_REGS];
diff --git a/mono/mini/mdb-debug-info32-darwin.s b/mono/mini/mdb-debug-info32-darwin.s
deleted file mode 100644 (file)
index 5d80af7..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-.text
-.globl         _MONO_DEBUGGER__debugger_info
-.globl         _MONO_DEBUGGER__notification_function   
-_MONO_DEBUGGER__notification_function:
-               int3
-               ret
-.section       .mdb_debug_info, "aw"
-.globl         _MONO_DEBUGGER__debugger_info_ptr
-.globl         _MONO_DEBUGGER__using_debugger
-_MONO_DEBUGGER__debugger_info_ptr:
-               .long   _MONO_DEBUGGER__debugger_info
-_MONO_DEBUGGER__using_debugger:
-               .long   0
-               .long   0
diff --git a/mono/mini/mdb-debug-info32.s b/mono/mini/mdb-debug-info32.s
deleted file mode 100644 (file)
index 230ccef..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-       .text
-.global                MONO_DEBUGGER__debugger_info
-.global                MONO_DEBUGGER__notification_function    
-MONO_DEBUGGER__notification_function:
-               int3
-               ret
-.section       .mdb_debug_info, "aw", @progbits
-.global                MONO_DEBUGGER__debugger_info_ptr
-.global                MONO_DEBUGGER__using_debugger
-MONO_DEBUGGER__debugger_info_ptr:
-               .long   MONO_DEBUGGER__debugger_info
-MONO_DEBUGGER__using_debugger:
-               .quad   0
diff --git a/mono/mini/mdb-debug-info64.s b/mono/mini/mdb-debug-info64.s
deleted file mode 100644 (file)
index d32add4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-.text
-.global                MONO_DEBUGGER__debugger_info
-.global                MONO_DEBUGGER__notification_function
-MONO_DEBUGGER__notification_function:
-               int3
-               ret
-.section       .mdb_debug_info, "aw", @progbits
-.global                MONO_DEBUGGER__debugger_info_ptr
-.global                MONO_DEBUGGER__using_debugger
-MONO_DEBUGGER__debugger_info_ptr:
-               .quad   MONO_DEBUGGER__debugger_info
-MONO_DEBUGGER__using_debugger:
-               .quad   0
-.section       .note.GNU-stack, "", @progbits
-.previous
index 97f053511f0b384036c715ecdc94a624175b84d7..8d4245a32c32dab7b2b0e3f5c1df904ed8a311a0 100644 (file)
@@ -264,6 +264,7 @@ mono_type_to_regmove (MonoCompile *cfg, MonoType *type)
        if (type->byref)
                return OP_MOVE;
 
+       type = mini_type_get_underlying_type (NULL, type);
 handle_enum:
        switch (type->type) {
        case MONO_TYPE_I1:
@@ -608,7 +609,7 @@ mono_create_spvar_for_region (MonoCompile *cfg, int region)
 
        var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
        /* prevent it from being register allocated */
-       var->flags |= MONO_INST_INDIRECT;
+       var->flags |= MONO_INST_VOLATILE;
 
        g_hash_table_insert (cfg->spvars, GINT_TO_POINTER (region), var);
 }
@@ -630,7 +631,7 @@ mono_create_exvar_for_offset (MonoCompile *cfg, int offset)
 
        var = mono_compile_create_var (cfg, &mono_defaults.object_class->byval_arg, OP_LOCAL);
        /* prevent it from being register allocated */
-       var->flags |= MONO_INST_INDIRECT;
+       var->flags |= MONO_INST_VOLATILE;
 
        g_hash_table_insert (cfg->exvars, GINT_TO_POINTER (offset), var);
 
@@ -646,6 +647,7 @@ type_to_eval_stack_type (MonoCompile *cfg, MonoType *type, MonoInst *inst)
 {
        MonoClass *klass;
 
+       type = mini_type_get_underlying_type (NULL, type);
        inst->klass = klass = mono_class_from_mono_type (type);
        if (type->byref) {
                inst->type = STACK_MP;
@@ -1155,7 +1157,7 @@ mono_get_vtable_var (MonoCompile *cfg)
        if (!cfg->rgctx_var) {
                cfg->rgctx_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                /* force the var to be stack allocated */
-               cfg->rgctx_var->flags |= MONO_INST_INDIRECT;
+               cfg->rgctx_var->flags |= MONO_INST_VOLATILE;
        }
 
        return cfg->rgctx_var;
@@ -1868,17 +1870,133 @@ mini_emit_memcpy (MonoCompile *cfg, int destreg, int doffset, int srcreg, int so
        }
 }
 
+static void
+emit_tls_set (MonoCompile *cfg, int sreg1, int tls_key)
+{
+       MonoInst *ins, *c;
+
+       if (cfg->compile_aot) {
+               EMIT_NEW_TLS_OFFSETCONST (cfg, c, tls_key);
+               MONO_INST_NEW (cfg, ins, OP_TLS_SET_REG);
+               ins->sreg1 = sreg1;
+               ins->sreg2 = c->dreg;
+               MONO_ADD_INS (cfg->cbb, ins);
+       } else {
+               MONO_INST_NEW (cfg, ins, OP_TLS_SET);
+               ins->sreg1 = sreg1;
+               ins->inst_offset = mini_get_tls_offset (tls_key);
+               MONO_ADD_INS (cfg->cbb, ins);
+       }
+}
+
+/*
+ * emit_push_lmf:
+ *
+ *   Emit IR to push the current LMF onto the LMF stack.
+ */
+static void
+emit_push_lmf (MonoCompile *cfg)
+{
+       /*
+        * Emit IR to push the LMF:
+        * lmf_addr = <lmf_addr from tls>
+        * lmf->lmf_addr = lmf_addr
+        * lmf->prev_lmf = *lmf_addr
+        * *lmf_addr = lmf
+        */
+       int lmf_reg, prev_lmf_reg;
+       MonoInst *ins, *lmf_ins;
+
+       if (!cfg->lmf_ir)
+               return;
+
+       if (cfg->lmf_ir_mono_lmf && mini_tls_get_supported (cfg, TLS_KEY_LMF)) {
+               /* Load current lmf */
+               lmf_ins = mono_get_lmf_intrinsic (cfg);
+               g_assert (lmf_ins);
+               MONO_ADD_INS (cfg->cbb, lmf_ins);
+               EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
+               lmf_reg = ins->dreg;
+               /* Save previous_lmf */
+               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_reg, G_STRUCT_OFFSET (MonoLMF, previous_lmf), lmf_ins->dreg);
+               /* Set new LMF */
+               emit_tls_set (cfg, lmf_reg, TLS_KEY_LMF);
+       } else {
+               /*
+                * Store lmf_addr in a variable, so it can be allocated to a global register.
+                */
+               if (!cfg->lmf_addr_var)
+                       cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+
+               lmf_ins = mono_get_lmf_addr_intrinsic (cfg);
+               if (lmf_ins) 
+                       MONO_ADD_INS (cfg->cbb, lmf_ins);
+               else
+                       lmf_ins = mono_emit_jit_icall (cfg, mono_get_lmf_addr, NULL);
+               lmf_ins->dreg = cfg->lmf_addr_var->dreg;
+
+               EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
+               lmf_reg = ins->dreg;
+
+               prev_lmf_reg = alloc_preg (cfg);
+               /* Save previous_lmf */
+               EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, cfg->lmf_addr_var->dreg, 0);
+               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_reg, G_STRUCT_OFFSET (MonoLMF, previous_lmf), prev_lmf_reg);
+               /* Set new lmf */
+               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, cfg->lmf_addr_var->dreg, 0, lmf_reg);
+       }
+}
+
+/*
+ * emit_pop_lmf:
+ *
+ *   Emit IR to pop the current LMF from the LMF stack.
+ */
+static void
+emit_pop_lmf (MonoCompile *cfg)
+{
+       int lmf_reg, lmf_addr_reg, prev_lmf_reg;
+       MonoInst *ins;
+
+       if (!cfg->lmf_ir)
+               return;
+
+       EMIT_NEW_VARLOADA (cfg, ins, cfg->lmf_var, NULL);
+       lmf_reg = ins->dreg;
+
+       if (cfg->lmf_ir_mono_lmf && mini_tls_get_supported (cfg, TLS_KEY_LMF)) {
+               /* Load previous_lmf */
+               prev_lmf_reg = alloc_preg (cfg);
+               EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, lmf_reg, G_STRUCT_OFFSET (MonoLMF, previous_lmf));
+               /* Set new LMF */
+               emit_tls_set (cfg, prev_lmf_reg, TLS_KEY_LMF);
+       } else {
+               /*
+                * Emit IR to pop the LMF:
+                * *(lmf->lmf_addr) = lmf->prev_lmf
+                */
+               /* This could be called before emit_push_lmf () */
+               if (!cfg->lmf_addr_var)
+                       cfg->lmf_addr_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+               lmf_addr_reg = cfg->lmf_addr_var->dreg;
+
+               prev_lmf_reg = alloc_preg (cfg);
+               EMIT_NEW_LOAD_MEMBASE (cfg, ins, OP_LOAD_MEMBASE, prev_lmf_reg, lmf_reg, G_STRUCT_OFFSET (MonoLMF, previous_lmf));
+               EMIT_NEW_STORE_MEMBASE (cfg, ins, OP_STORE_MEMBASE_REG, lmf_addr_reg, 0, prev_lmf_reg);
+       }
+}
+
 static int
 ret_type_to_call_opcode (MonoType *type, int calli, int virt, MonoGenericSharingContext *gsctx)
 {
        if (type->byref)
-               return calli? OP_CALL_REG: virt? OP_CALLVIRT: OP_CALL;
+               return calli? OP_CALL_REG: virt? OP_CALL_MEMBASE: OP_CALL;
 
 handle_enum:
        type = mini_get_basic_type_from_generic (gsctx, type);
        switch (type->type) {
        case MONO_TYPE_VOID:
-               return calli? OP_VOIDCALL_REG: virt? OP_VOIDCALLVIRT: OP_VOIDCALL;
+               return calli? OP_VOIDCALL_REG: virt? OP_VOIDCALL_MEMBASE: OP_VOIDCALL;
        case MONO_TYPE_I1:
        case MONO_TYPE_U1:
        case MONO_TYPE_BOOLEAN:
@@ -1887,39 +2005,39 @@ handle_enum:
        case MONO_TYPE_CHAR:
        case MONO_TYPE_I4:
        case MONO_TYPE_U4:
-               return calli? OP_CALL_REG: virt? OP_CALLVIRT: OP_CALL;
+               return calli? OP_CALL_REG: virt? OP_CALL_MEMBASE: OP_CALL;
        case MONO_TYPE_I:
        case MONO_TYPE_U:
        case MONO_TYPE_PTR:
        case MONO_TYPE_FNPTR:
-               return calli? OP_CALL_REG: virt? OP_CALLVIRT: OP_CALL;
+               return calli? OP_CALL_REG: virt? OP_CALL_MEMBASE: OP_CALL;
        case MONO_TYPE_CLASS:
        case MONO_TYPE_STRING:
        case MONO_TYPE_OBJECT:
        case MONO_TYPE_SZARRAY:
        case MONO_TYPE_ARRAY:    
-               return calli? OP_CALL_REG: virt? OP_CALLVIRT: OP_CALL;
+               return calli? OP_CALL_REG: virt? OP_CALL_MEMBASE: OP_CALL;
        case MONO_TYPE_I8:
        case MONO_TYPE_U8:
-               return calli? OP_LCALL_REG: virt? OP_LCALLVIRT: OP_LCALL;
+               return calli? OP_LCALL_REG: virt? OP_LCALL_MEMBASE: OP_LCALL;
        case MONO_TYPE_R4:
        case MONO_TYPE_R8:
-               return calli? OP_FCALL_REG: virt? OP_FCALLVIRT: OP_FCALL;
+               return calli? OP_FCALL_REG: virt? OP_FCALL_MEMBASE: OP_FCALL;
        case MONO_TYPE_VALUETYPE:
                if (type->data.klass->enumtype) {
                        type = mono_class_enum_basetype (type->data.klass);
                        goto handle_enum;
                } else
-                       return calli? OP_VCALL_REG: virt? OP_VCALLVIRT: OP_VCALL;
+                       return calli? OP_VCALL_REG: virt? OP_VCALL_MEMBASE: OP_VCALL;
        case MONO_TYPE_TYPEDBYREF:
-               return calli? OP_VCALL_REG: virt? OP_VCALLVIRT: OP_VCALL;
+               return calli? OP_VCALL_REG: virt? OP_VCALL_MEMBASE: OP_VCALL;
        case MONO_TYPE_GENERICINST:
                type = &type->data.generic_class->container_class->byval_arg;
                goto handle_enum;
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                /* gsharedvt */
-               return calli? OP_VCALL_REG: virt? OP_VCALLVIRT: OP_VCALL;
+               return calli? OP_VCALL_REG: virt? OP_VCALL_MEMBASE: OP_VCALL;
        default:
                g_error ("unknown type 0x%02x in ret_type_to_call_opcode", type->type);
        }
@@ -1943,6 +2061,7 @@ target_type_is_incompatible (MonoCompile *cfg, MonoType *target, MonoInst *arg)
        MonoType *simple_type;
        MonoClass *klass;
 
+       target = mini_type_get_underlying_type (NULL, target);
        if (target->byref) {
                /* FIXME: check that the pointed to types match */
                if (arg->type == STACK_MP)
@@ -2148,15 +2267,15 @@ static int
 callvirt_to_call (int opcode)
 {
        switch (opcode) {
-       case OP_CALLVIRT:
+       case OP_CALL_MEMBASE:
                return OP_CALL;
-       case OP_VOIDCALLVIRT:
+       case OP_VOIDCALL_MEMBASE:
                return OP_VOIDCALL;
-       case OP_FCALLVIRT:
+       case OP_FCALL_MEMBASE:
                return OP_FCALL;
-       case OP_VCALLVIRT:
+       case OP_VCALL_MEMBASE:
                return OP_VCALL;
-       case OP_LCALLVIRT:
+       case OP_LCALL_MEMBASE:
                return OP_LCALL;
        default:
                g_assert_not_reached ();
@@ -2165,27 +2284,6 @@ callvirt_to_call (int opcode)
        return -1;
 }
 
-static int
-callvirt_to_call_membase (int opcode)
-{
-       switch (opcode) {
-       case OP_CALLVIRT:
-               return OP_CALL_MEMBASE;
-       case OP_VOIDCALLVIRT:
-               return OP_VOIDCALL_MEMBASE;
-       case OP_FCALLVIRT:
-               return OP_FCALL_MEMBASE;
-       case OP_LCALLVIRT:
-               return OP_LCALL_MEMBASE;
-       case OP_VCALLVIRT:
-               return OP_VCALL_MEMBASE;
-       default:
-               g_assert_not_reached ();
-       }
-
-       return -1;
-}
-
 #ifdef MONO_ARCH_HAVE_IMT
 /* Either METHOD or IMT_ARG needs to be set */
 static void
@@ -2336,6 +2434,7 @@ inline static MonoCallInst *
 mono_emit_call_args (MonoCompile *cfg, MonoMethodSignature *sig, 
                                         MonoInst **args, int calli, int virtual, int tail, int rgctx, int unbox_trampoline)
 {
+       MonoType *sig_ret;
        MonoCallInst *call;
 #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
        int i;
@@ -2349,16 +2448,17 @@ mono_emit_call_args (MonoCompile *cfg, MonoMethodSignature *sig,
        call->args = args;
        call->signature = sig;
        call->rgctx_reg = rgctx;
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
-       type_to_eval_stack_type ((cfg), sig->ret, &call->inst);
+       type_to_eval_stack_type ((cfg), sig_ret, &call->inst);
 
        if (tail) {
-               if (mini_type_is_vtype (cfg, sig->ret)) {
+               if (mini_type_is_vtype (cfg, sig_ret)) {
                        call->vret_var = cfg->vret_addr;
                        //g_assert_not_reached ();
                }
-       } else if (mini_type_is_vtype (cfg, sig->ret)) {
-               MonoInst *temp = mono_compile_create_var (cfg, sig->ret, OP_LOCAL);
+       } else if (mini_type_is_vtype (cfg, sig_ret)) {
+               MonoInst *temp = mono_compile_create_var (cfg, sig_ret, OP_LOCAL);
                MonoInst *loada;
 
                temp->backend.is_pinvoke = sig->pinvoke;
@@ -2381,7 +2481,7 @@ mono_emit_call_args (MonoCompile *cfg, MonoMethodSignature *sig,
                call->inst.dreg = temp->dreg;
 
                call->vret_var = loada;
-       } else if (!MONO_TYPE_IS_VOID (sig->ret))
+       } else if (!MONO_TYPE_IS_VOID (sig_ret))
                call->inst.dreg = alloc_dreg (cfg, call->inst.type);
 
 #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
@@ -2556,7 +2656,6 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
                        MONO_EMIT_NULL_CHECK (cfg, this_reg);
 
                        /* Make a call to delegate->invoke_impl */
-                       call->inst.opcode = callvirt_to_call_membase (call->inst.opcode);
                        call->inst.inst_basereg = this_reg;
                        call->inst.inst_offset = G_STRUCT_OFFSET (MonoDelegate, invoke_impl);
                        MONO_ADD_INS (cfg->cbb, (MonoInst*)call);
@@ -2611,8 +2710,6 @@ mono_emit_method_call_full (MonoCompile *cfg, MonoMethod *method, MonoMethodSign
 
                        call->inst.opcode = callvirt_to_call (call->inst.opcode);
                } else {
-                       call->inst.opcode = callvirt_to_call_membase (call->inst.opcode);
-
                        vtable_reg = alloc_preg (cfg);
                        MONO_EMIT_NEW_LOAD_MEMBASE_FAULT (cfg, vtable_reg, this_reg, G_STRUCT_OFFSET (MonoObject, vtable));
                        if (method->klass->flags & TYPE_ATTRIBUTE_INTERFACE) {
@@ -2811,7 +2908,7 @@ emit_write_barrier (MonoCompile *cfg, MonoInst *ptr, MonoInst *value)
        has_card_table_wb = TRUE;
 #endif
 
-       if (has_card_table_wb && !cfg->compile_aot && card_table && nursery_shift_bits > 0) {
+       if (has_card_table_wb && !cfg->compile_aot && card_table && nursery_shift_bits > 0 && !COMPILE_LLVM (cfg)) {
                MonoInst *wbarrier;
 
                MONO_INST_NEW (cfg, wbarrier, OP_CARD_TABLE_WBARRIER);
@@ -4317,7 +4414,7 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono
         * in mono_delegate_trampoline (), we allocate a per-domain memory slot to
         * store it, and we fill it after the method has been compiled.
         */
-       if (!cfg->compile_aot && !method->dynamic && !(cfg->opt & MONO_OPT_SHARED)) {
+       if (!method->dynamic && !(cfg->opt & MONO_OPT_SHARED)) {
                MonoInst *code_slot_ins;
 
                if (context_used) {
@@ -4334,7 +4431,10 @@ handle_delegate_ctor (MonoCompile *cfg, MonoClass *klass, MonoInst *target, Mono
                        }
                        mono_domain_unlock (domain);
 
-                       EMIT_NEW_PCONST (cfg, code_slot_ins, code_slot);
+                       if (cfg->compile_aot)
+                               EMIT_NEW_AOTCONST (cfg, code_slot_ins, MONO_PATCH_INFO_METHOD_CODE_SLOT, method);
+                       else
+                               EMIT_NEW_PCONST (cfg, code_slot_ins, code_slot);
                }
                MONO_EMIT_NEW_STORE_MEMBASE (cfg, OP_STORE_MEMBASE_REG, obj->dreg, G_STRUCT_OFFSET (MonoDelegate, method_code), code_slot_ins->dreg);           
        }
@@ -4461,7 +4561,13 @@ mono_method_check_inlining (MonoCompile *cfg, MonoMethod *method)
         * inside the inlined code
         */
        if (!(cfg->opt & MONO_OPT_SHARED)) {
-               if (method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
+               /* The AggressiveInlining hint is a good excuse to force that cctor to run. */
+               if (method->iflags & METHOD_IMPL_ATTRIBUTE_AGGRESSIVE_INLINING) {
+                       vtable = mono_class_vtable (cfg->domain, method->klass);
+                       if (!vtable)
+                               return FALSE;
+                       mono_runtime_class_init (vtable);
+               } else if (method->klass->flags & TYPE_ATTRIBUTE_BEFORE_FIELD_INIT) {
                        if (cfg->run_cctors && method->klass->has_cctor) {
                                /*FIXME it would easier and lazier to just use mono_class_try_get_vtable */
                                if (!method->klass->runtime_info)
@@ -4758,7 +4864,8 @@ should_insert_brekpoint (MonoMethod *method) {
        case MONO_BREAK_POLICY_NEVER:
                return FALSE;
        case MONO_BREAK_POLICY_ON_DBG:
-               return mono_debug_using_mono_debugger ();
+               g_warning ("mdb no longer supported");
+               return FALSE;
        default:
                g_warning ("Incorrect value returned from break policy callback");
                return FALSE;
@@ -5571,35 +5678,48 @@ check_inline_caller_method_name_limit (MonoMethod *caller_method)
 #endif
 
 static void
-emit_init_rvar (MonoCompile *cfg, MonoInst *rvar, MonoType *rtype)
+emit_init_rvar (MonoCompile *cfg, int dreg, MonoType *rtype)
 {
        static double r8_0 = 0.0;
        MonoInst *ins;
-
-       switch (rvar->type) {
-       case STACK_I4:
-               MONO_EMIT_NEW_ICONST (cfg, rvar->dreg, 0);
-               break;
-       case STACK_I8:
-               MONO_EMIT_NEW_I8CONST (cfg, rvar->dreg, 0);
-               break;
-       case STACK_PTR:
-       case STACK_MP:
-       case STACK_OBJ:
-               MONO_EMIT_NEW_PCONST (cfg, rvar->dreg, 0);
-               break;
-       case STACK_R8:
+       int t;
+
+       rtype = mini_type_get_underlying_type (NULL, rtype);
+       t = rtype->type;
+
+       if (rtype->byref) {
+               MONO_EMIT_NEW_PCONST (cfg, dreg, NULL);
+       } else if (t >= MONO_TYPE_BOOLEAN && t <= MONO_TYPE_U4) {
+               MONO_EMIT_NEW_ICONST (cfg, dreg, 0);
+       } else if (t == MONO_TYPE_I8 || t == MONO_TYPE_U8) {
+               MONO_EMIT_NEW_I8CONST (cfg, dreg, 0);
+       } else if (t == MONO_TYPE_R4 || t == MONO_TYPE_R8) {
                MONO_INST_NEW (cfg, ins, OP_R8CONST);
                ins->type = STACK_R8;
                ins->inst_p0 = (void*)&r8_0;
-               ins->dreg = rvar->dreg;
+               ins->dreg = dreg;
                MONO_ADD_INS (cfg->cbb, ins);
-               break;
-       case STACK_VTYPE:
-               MONO_EMIT_NEW_VZERO (cfg, rvar->dreg, mono_class_from_mono_type (rtype));
-               break;
-       default:
-               g_assert_not_reached ();
+       } else if ((t == MONO_TYPE_VALUETYPE) || (t == MONO_TYPE_TYPEDBYREF) ||
+                  ((t == MONO_TYPE_GENERICINST) && mono_type_generic_inst_is_valuetype (rtype))) {
+               MONO_EMIT_NEW_VZERO (cfg, dreg, mono_class_from_mono_type (rtype));
+       } else if (((t == MONO_TYPE_VAR) || (t == MONO_TYPE_MVAR)) && mini_type_var_is_vt (cfg, rtype)) {
+               MONO_EMIT_NEW_VZERO (cfg, dreg, mono_class_from_mono_type (rtype));
+       } else {
+               MONO_EMIT_NEW_PCONST (cfg, dreg, NULL);
+       }
+}
+
+static void
+emit_init_local (MonoCompile *cfg, int local, MonoType *type)
+{
+       MonoInst *var = cfg->locals [local];
+       if (COMPILE_SOFT_FLOAT (cfg)) {
+               MonoInst *store;
+               int reg = alloc_dreg (cfg, var->type);
+               emit_init_rvar (cfg, reg, type);
+               EMIT_NEW_LOCSTORE (cfg, store, local, cfg->cbb->last_ins);
+       } else {
+               emit_init_rvar (cfg, var->dreg, type);
        }
 }
 
@@ -5764,7 +5884,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
                                        if (bb->last_ins && bb->last_ins->opcode == OP_NOT_REACHED) {
                                                cfg->cbb = bb;
 
-                                               emit_init_rvar (cfg, rvar, fsig->ret);
+                                               emit_init_rvar (cfg, rvar->dreg, fsig->ret);
                                        }
                                }
                        }
@@ -5778,7 +5898,7 @@ inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig,
                         * set, so set it to a dummy value.
                         */
                        if (!ret_var_set)
-                               emit_init_rvar (cfg, rvar, fsig->ret);
+                               emit_init_rvar (cfg, rvar->dreg, fsig->ret);
 
                        EMIT_NEW_TEMPLOAD (cfg, ins, rvar->inst_c0);
                        *sp++ = ins;
@@ -6146,9 +6266,6 @@ initialize_array_data (MonoMethod *method, gboolean aot, unsigned char *ip, Mono
                case MONO_TYPE_R4:
                        size = 4; break;
                case MONO_TYPE_R8:
-#ifdef ARM_FPU_FPA
-                       return NULL; /* stupid ARM FP swapped format */
-#endif
                case MONO_TYPE_I8:
                case MONO_TYPE_U8:
                        size = 8; break;
@@ -6232,6 +6349,7 @@ emit_optimized_ldloca_ir (MonoCompile *cfg, unsigned char *ip, unsigned char *en
 {
        int local, token;
        MonoClass *klass;
+       MonoType *type;
 
        if (size == 1) {
                local = ip [1];
@@ -6242,22 +6360,13 @@ emit_optimized_ldloca_ir (MonoCompile *cfg, unsigned char *ip, unsigned char *en
        }
        
        if (ip + 6 < end && (ip [0] == CEE_PREFIX1) && (ip [1] == CEE_INITOBJ) && ip_in_bb (cfg, cfg->cbb, ip + 1)) {
-               gboolean skip = FALSE;
-
                /* From the INITOBJ case */
                token = read32 (ip + 2);
                klass = mini_get_class (cfg->current_method, token, cfg->generic_context);
                CHECK_TYPELOAD (klass);
-               if (mini_type_is_reference (cfg, &klass->byval_arg)) {
-                       MONO_EMIT_NEW_PCONST (cfg, cfg->locals [local]->dreg, NULL);
-               } else if (MONO_TYPE_ISSTRUCT (&klass->byval_arg)) {
-                       MONO_EMIT_NEW_VZERO (cfg, cfg->locals [local]->dreg, klass);
-               } else {
-                       skip = TRUE;
-               }
-                       
-               if (!skip)
-                       return ip + 6;
+               type = mini_type_get_underlying_type (NULL, &klass->byval_arg);
+               emit_init_local (cfg, local, type);
+               return ip + 6;
        }
 load_error:
        return NULL;
@@ -6338,13 +6447,13 @@ is_jit_optimizer_disabled (MonoMethod *m)
 }
 
 static gboolean
-is_supported_tail_call (MonoCompile *cfg, MonoMethod *method, MonoMethod *cmethod, MonoMethodSignature *fsig)
+is_supported_tail_call (MonoCompile *cfg, MonoMethod *method, MonoMethod *cmethod, MonoMethodSignature *fsig, int call_opcode)
 {
        gboolean supported_tail_call;
        int i;
 
-#ifdef MONO_ARCH_USE_OP_TAIL_CALL
-       supported_tail_call = MONO_ARCH_USE_OP_TAIL_CALL (mono_method_signature (method), mono_method_signature (cmethod));
+#ifdef MONO_ARCH_HAVE_OP_TAIL_CALL
+       supported_tail_call = mono_arch_tail_call_supported (mono_method_signature (method), mono_method_signature (cmethod));
 #else
        supported_tail_call = mono_metadata_signature_equal (mono_method_signature (method), mono_method_signature (cmethod)) && !MONO_TYPE_ISSTRUCT (mono_method_signature (cmethod)->ret);
 #endif
@@ -6363,6 +6472,8 @@ is_supported_tail_call (MonoCompile *cfg, MonoMethod *method, MonoMethod *cmetho
                supported_tail_call = FALSE;
        if (cmethod->wrapper_type && cmethod->wrapper_type != MONO_WRAPPER_DYNAMIC_METHOD)
                supported_tail_call = FALSE;
+       if (call_opcode != CEE_CALL)
+               supported_tail_call = FALSE;
 
        /* Debugging support */
 #if 0
@@ -6476,7 +6587,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
        MonoClass *klass;
        MonoClass *constrained_call = NULL;
        unsigned char *ip, *end, *target, *err_pos;
-       static double r8_0 = 0.0;
        MonoMethodSignature *sig;
        MonoGenericContext *generic_context = NULL;
        MonoGenericContainer *generic_container = NULL;
@@ -6586,9 +6696,6 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                dont_verify_stloc = TRUE;
        }
 
-       if (mono_debug_using_mono_debugger ())
-               cfg->keep_cil_nops = TRUE;
-
        if (sig->is_inflated)
                generic_context = mono_method_get_context (method);
        else if (generic_container)
@@ -6669,7 +6776,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        tblock->real_offset = clause->handler_offset;
                        tblock->flags |= BB_EXCEPTION_HANDLER;
 
-                       link_bblock (cfg, try_bb, tblock);
+                       /*
+                        * Linking the try block with the EH block hinders inlining as we won't be able to 
+                        * merge the bblocks from inlining and produce an artificial hole for no good reason.
+                        */
+                       if (COMPILE_LLVM (cfg))
+                               link_bblock (cfg, try_bb, tblock);
 
                        if (*(ip + clause->handler_offset) == CEE_POP)
                                tblock->flags |= BB_EXCEPTION_DEAD_OBJ;
@@ -6770,7 +6882,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
        if (cfg->method == method) {
                breakpoint_id = mono_debugger_method_has_breakpoint (method);
-               if (breakpoint_id && (mono_debug_format != MONO_DEBUG_FORMAT_DEBUGGER)) {
+               if (breakpoint_id) {
                        MONO_INST_NEW (cfg, ins, OP_BREAK);
                        MONO_ADD_INS (bblock, ins);
                }
@@ -6845,7 +6957,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                /* prevent it from being register allocated */
-               //var->flags |= MONO_INST_INDIRECT;
+               //var->flags |= MONO_INST_VOLATILE;
                cfg->gsharedvt_info_var = var;
 
                ins = emit_get_rgctx_gsharedvt_method (cfg, mini_method_check_context_used (cfg, method), method, info);
@@ -6854,7 +6966,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                /* Allocate locals */
                locals_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                /* prevent it from being register allocated */
-               //locals_var->flags |= MONO_INST_INDIRECT;
+               //locals_var->flags |= MONO_INST_VOLATILE;
                cfg->gsharedvt_locals_var = locals_var;
 
                dreg = alloc_ireg (cfg);
@@ -6959,7 +7071,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        /* FIXME: Is there a better way to do this?
                           We need the variable live for the duration
                           of the whole method. */
-                       cfg->args [0]->flags |= MONO_INST_INDIRECT;
+                       cfg->args [0]->flags |= MONO_INST_VOLATILE;
                }
        }
 
@@ -7421,8 +7533,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        if (mono_security_cas_enabled ())
                                CHECK_CFG_EXCEPTION;
 
-#ifdef MONO_ARCH_USE_OP_TAIL_CALL
-                       {
+                       if (ARCH_HAVE_OP_TAIL_CALL) {
                                MonoMethodSignature *fsig = mono_method_signature (cmethod);
                                int i, n;
 
@@ -7440,17 +7551,16 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                mono_arch_emit_call (cfg, call);
                                MONO_ADD_INS (bblock, (MonoInst*)call);
-                       }
-#else
-                       for (i = 0; i < num_args; ++i)
-                               /* Prevent arguments from being optimized away */
-                               arg_array [i]->flags |= MONO_INST_VOLATILE;
+                       } else {
+                               for (i = 0; i < num_args; ++i)
+                                       /* Prevent arguments from being optimized away */
+                                       arg_array [i]->flags |= MONO_INST_VOLATILE;
 
-                       MONO_INST_NEW_CALL (cfg, call, OP_JMP);
-                       ins = (MonoInst*)call;
-                       ins->inst_p0 = cmethod;
-                       MONO_ADD_INS (bblock, ins);
-#endif
+                               MONO_INST_NEW_CALL (cfg, call, OP_JMP);
+                               ins = (MonoInst*)call;
+                               ins->inst_p0 = cmethod;
+                               MONO_ADD_INS (bblock, ins);
+                       }
 
                        ip += 5;
                        start_new_bblock = 1;
@@ -8045,7 +8155,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        /*
                         * Making generic calls out of gsharedvt methods.
                         */
-                       if (cmethod && cfg->gsharedvt && mini_is_gsharedvt_signature (cfg, fsig)) {
+                       if (cmethod && cfg->gsharedvt && mini_is_gsharedvt_variable_signature (fsig)) {
                                MonoRgctxInfoType info_type;
 
                                if (virtual) {
@@ -8215,12 +8325,8 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        /* FIXME: runtime generic context pointer for jumps? */
                        /* FIXME: handle this for generic sharing eventually */
                        if (cmethod && (ins_flag & MONO_INST_TAILCALL) &&
-                               !vtable_arg && !cfg->generic_sharing_context && is_supported_tail_call (cfg, method, cmethod, fsig))
+                               !vtable_arg && !cfg->generic_sharing_context && is_supported_tail_call (cfg, method, cmethod, fsig, call_opcode))
                                supported_tail_call = TRUE;
-                       if (supported_tail_call) {
-                               if (call_opcode != CEE_CALL)
-                                       supported_tail_call = FALSE;
-                       }
 
                        if (supported_tail_call) {
                                MonoCallInst *call;
@@ -8230,7 +8336,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                                //printf ("HIT: %s -> %s\n", mono_method_full_name (cfg->method, TRUE), mono_method_full_name (cmethod, TRUE));
 
-                               if (ARCH_USE_OP_TAIL_CALL) {
+                               if (ARCH_HAVE_OP_TAIL_CALL) {
                                        /* Handle tail calls similarly to normal calls */
                                        tail_call = TRUE;
                                } else {
@@ -8361,8 +8467,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                        cfg->ret_var_set = TRUE;
                                } 
                        } else {
+                               if (cfg->lmf_var && cfg->cbb->in_count)
+                                       emit_pop_lmf (cfg);
+
                                if (cfg->ret) {
-                                       MonoType *ret_type = mono_method_signature (method)->ret;
+                                       MonoType *ret_type = mini_type_get_underlying_type (NULL, mono_method_signature (method)->ret);
 
                                        if (seq_points && !sym_seq_points) {
                                                /* 
@@ -9235,7 +9344,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                
                                if (cmethod->klass->valuetype) {
                                        iargs [0] = mono_compile_create_var (cfg, &cmethod->klass->byval_arg, OP_LOCAL);
-                                       MONO_EMIT_NEW_VZERO (cfg, iargs [0]->dreg, cmethod->klass);
+                                       emit_init_rvar (cfg, iargs [0]->dreg, &cmethod->klass->byval_arg);
                                        EMIT_NEW_TEMPLOADA (cfg, *sp, iargs [0]->inst_c0);
 
                                        alloc = NULL;
@@ -9711,6 +9820,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                        gboolean is_special_static;
                        MonoType *ftype;
                        MonoInst *store_val = NULL;
+                       MonoInst *thread_ins;
 
                        op = *ip;
                        is_instance = (op == CEE_LDFLD || op == CEE_LDFLDA || op == CEE_STFLD);
@@ -9990,8 +10100,13 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                        is_special_static = mono_class_field_is_special_static (field);
 
+                       if (is_special_static && ((gsize)addr & 0x80000000) == 0)
+                               thread_ins = mono_get_thread_intrinsic (cfg);
+                       else
+                               thread_ins = NULL;
+
                        /* Generate IR to compute the field address */
-                       if (is_special_static && ((gsize)addr & 0x80000000) == 0 && mono_get_thread_intrinsic (cfg) && !(cfg->opt & MONO_OPT_SHARED) && !context_used) {
+                       if (is_special_static && ((gsize)addr & 0x80000000) == 0 && thread_ins && !(cfg->opt & MONO_OPT_SHARED) && !context_used) {
                                /*
                                 * Fast access to TLS data
                                 * Inline version of get_thread_static_data () in
@@ -9999,15 +10114,12 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                 */
                                guint32 offset;
                                int idx, static_data_reg, array_reg, dreg;
-                               MonoInst *thread_ins;
 
                                GSHAREDVT_FAILURE (op);
 
                                // offset &= 0x7fffffff;
                                // idx = (offset >> 24) - 1;
                                //      return ((char*) thread->static_data [idx]) + (offset & 0xffffff);
-
-                               thread_ins = mono_get_thread_intrinsic (cfg);
                                MONO_ADD_INS (cfg->cbb, thread_ins);
                                static_data_reg = alloc_ireg (cfg);
                                MONO_EMIT_NEW_LOAD_MEMBASE (cfg, static_data_reg, thread_ins->dreg, G_STRUCT_OFFSET (MonoInternalThread, static_data));
@@ -11159,7 +11271,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                if (!cfg->dyn_call_var) {
                                        cfg->dyn_call_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
                                        /* prevent it from being register allocated */
-                                       cfg->dyn_call_var->flags |= MONO_INST_INDIRECT;
+                                       cfg->dyn_call_var->flags |= MONO_INST_VOLATILE;
                                }
 
                                /* Has to use a call inst since it local regalloc expects it */
@@ -11170,9 +11282,7 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                                ins->sreg2 = sp [1]->dreg;
                                MONO_ADD_INS (bblock, ins);
 
-#ifdef MONO_ARCH_DYN_CALL_PARAM_AREA
                                cfg->param_area = MAX (cfg->param_area, MONO_ARCH_DYN_CALL_PARAM_AREA);
-#endif
 
                                ip += 2;
                                inline_costs += 10 * num_calls++;
@@ -11754,13 +11864,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
 
                cfg->cbb = init_localsbb;
 
-               if (! (get_domain = mono_arch_get_domain_intrinsic (cfg))) {
+               if ((get_domain = mono_get_domain_intrinsic (cfg))) {
+                       MONO_ADD_INS (cfg->cbb, get_domain);
+               } else {
                        get_domain = mono_emit_jit_icall (cfg, mono_domain_get, NULL);
                }
-               else {
-                       get_domain->dreg = alloc_preg (cfg);
-                       MONO_ADD_INS (cfg->cbb, get_domain);
-               }               
                NEW_TEMPSTORE (cfg, store, cfg->domainvar->inst_c0, get_domain);
                MONO_ADD_INS (cfg->cbb, store);
        }
@@ -11775,38 +11883,10 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                mono_emit_load_got_addr (cfg);
 
        if (init_locals) {
-               MonoInst *store;
-
                cfg->cbb = init_localsbb;
                cfg->ip = NULL;
                for (i = 0; i < header->num_locals; ++i) {
-                       MonoType *ptype = header->locals [i];
-                       int t = ptype->type;
-                       dreg = cfg->locals [i]->dreg;
-
-                       if (t == MONO_TYPE_VALUETYPE && ptype->data.klass->enumtype)
-                               t = mono_class_enum_basetype (ptype->data.klass)->type;
-                       if (ptype->byref) {
-                               MONO_EMIT_NEW_PCONST (cfg, dreg, NULL);
-                       } else if (t >= MONO_TYPE_BOOLEAN && t <= MONO_TYPE_U4) {
-                               MONO_EMIT_NEW_ICONST (cfg, cfg->locals [i]->dreg, 0);
-                       } else if (t == MONO_TYPE_I8 || t == MONO_TYPE_U8) {
-                               MONO_EMIT_NEW_I8CONST (cfg, cfg->locals [i]->dreg, 0);
-                       } else if (t == MONO_TYPE_R4 || t == MONO_TYPE_R8) {
-                               MONO_INST_NEW (cfg, ins, OP_R8CONST);
-                               ins->type = STACK_R8;
-                               ins->inst_p0 = (void*)&r8_0;
-                               ins->dreg = alloc_dreg (cfg, STACK_R8);
-                               MONO_ADD_INS (init_localsbb, ins);
-                               EMIT_NEW_LOCSTORE (cfg, store, i, ins);
-                       } else if ((t == MONO_TYPE_VALUETYPE) || (t == MONO_TYPE_TYPEDBYREF) ||
-                                  ((t == MONO_TYPE_GENERICINST) && mono_type_generic_inst_is_valuetype (ptype))) {
-                               MONO_EMIT_NEW_VZERO (cfg, dreg, mono_class_from_mono_type (ptype));
-                       } else if (((t == MONO_TYPE_VAR) || (t == MONO_TYPE_MVAR)) && mini_type_var_is_vt (cfg, ptype)) {
-                               MONO_EMIT_NEW_VZERO (cfg, dreg, mono_class_from_mono_type (ptype));
-                       } else {
-                               MONO_EMIT_NEW_PCONST (cfg, dreg, NULL);
-                       }
+                       emit_init_local (cfg, i, header->locals [i]);
                }
        }
 
@@ -11821,6 +11901,11 @@ mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoBasicBlock *start_b
                }
        }
 
+       if (cfg->lmf_var && cfg->method == method) {
+               cfg->cbb = init_localsbb;
+               emit_push_lmf (cfg);
+       }
+
        if (seq_points) {
                MonoBasicBlock *bb;
 
@@ -12544,7 +12629,7 @@ mono_handle_global_vregs (MonoCompile *cfg)
                        /* Arguments are implicitly global */
                        /* Putting R4 vars into registers doesn't work currently */
                        /* The gsharedvt vars are implicitly referenced by ldaddr opcodes, but those opcodes are only generated later */
-                       if ((var->opcode != OP_ARG) && (var != cfg->ret) && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && (vreg_to_bb [var->dreg] != -1) && (var->klass->byval_arg.type != MONO_TYPE_R4) && !cfg->disable_vreg_to_lvreg && var != cfg->gsharedvt_info_var && var != cfg->gsharedvt_locals_var) {
+                       if ((var->opcode != OP_ARG) && (var != cfg->ret) && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)) && (vreg_to_bb [var->dreg] != -1) && (var->klass->byval_arg.type != MONO_TYPE_R4) && !cfg->disable_vreg_to_lvreg && var != cfg->gsharedvt_info_var && var != cfg->gsharedvt_locals_var && var != cfg->lmf_addr_var) {
                                /* 
                                 * Make that the variable's liveness interval doesn't contain a call, since
                                 * that would cause the lvreg to be spilled, making the whole optimization
index e84308beeb910e24d6e2be7b4a74b351b0f01eed..bdfc9858370e1783b49a90dfee6362c70cf423cb 100644 (file)
@@ -39,9 +39,9 @@
 #include "debugger-agent.h"
 #include "mini-gc.h"
 
-static gint lmf_tls_offset = -1;
-static gint lmf_addr_tls_offset = -1;
-static gint appdomain_tls_offset = -1;
+#ifdef HOST_WIN32
+static gint jit_tls_offset = -1;
+#endif
 
 #ifdef MONO_XEN_OPT
 static gboolean optimize_for_xen = TRUE;
@@ -1004,7 +1004,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                case MONO_TYPE_VALUETYPE: {
                        guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
 
-                       add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
+                       add_valuetype (gsctx, sig, &cinfo->ret, ret_type, TRUE, &tmp_gr, &tmp_fr, &tmp_stacksize);
                        if (cinfo->ret.storage == ArgOnStack) {
                                cinfo->vtype_retaddr = TRUE;
                                /* The caller passes the address where the value is stored */
@@ -1020,7 +1020,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                case MONO_TYPE_VOID:
                        break;
                default:
-                       g_error ("Can't handle as return value 0x%x", sig->ret->type);
+                       g_error ("Can't handle as return value 0x%x", ret_type->type);
                }
        }
 
@@ -1204,15 +1204,17 @@ mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignatu
 }
 
 gboolean
-mono_amd64_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
+mono_arch_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
 {
        CallInfo *c1, *c2;
        gboolean res;
+       MonoType *callee_ret;
 
        c1 = get_call_info (NULL, NULL, caller_sig);
        c2 = get_call_info (NULL, NULL, callee_sig);
        res = c1->stack_usage >= c2->stack_usage;
-       if (callee_sig->ret && MONO_TYPE_ISSTRUCT (callee_sig->ret) && c2->ret.storage != ArgValuetypeInReg)
+       callee_ret = mini_type_get_underlying_type (NULL, callee_sig->ret);
+       if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg)
                /* An address on the callee's stack is passed as the first argument */
                res = FALSE;
 
@@ -1608,6 +1610,7 @@ mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
 void
 mono_arch_fill_argument_info (MonoCompile *cfg)
 {
+       MonoType *sig_ret;
        MonoMethodSignature *sig;
        MonoMethodHeader *header;
        MonoInst *ins;
@@ -1619,6 +1622,7 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        cinfo = cfg->arch.cinfo;
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
        /*
         * Contrary to mono_arch_allocate_vars (), the information should describe
@@ -1626,12 +1630,12 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
         * accessed during the execution of the method. The later makes no sense for the 
         * global register allocator, since a variable can be in more than one location.
         */
-       if (sig->ret->type != MONO_TYPE_VOID) {
+       if (sig_ret->type != MONO_TYPE_VOID) {
                switch (cinfo->ret.storage) {
                case ArgInIReg:
                case ArgInFloatSSEReg:
                case ArgInDoubleSSEReg:
-                       if ((MONO_TYPE_ISSTRUCT (sig->ret) && !mono_class_from_mono_type (sig->ret)->enumtype) || ((sig->ret->type == MONO_TYPE_TYPEDBYREF) && cinfo->vtype_retaddr)) {
+                       if ((MONO_TYPE_ISSTRUCT (sig_ret) && !mono_class_from_mono_type (sig_ret)->enumtype) || ((sig_ret->type == MONO_TYPE_TYPEDBYREF) && cinfo->vtype_retaddr)) {
                                cfg->vret_addr->opcode = OP_REGVAR;
                                cfg->vret_addr->inst_c0 = cinfo->ret.reg;
                        }
@@ -1686,6 +1690,7 @@ mono_arch_fill_argument_info (MonoCompile *cfg)
 void
 mono_arch_allocate_vars (MonoCompile *cfg)
 {
+       MonoType *sig_ret;
        MonoMethodSignature *sig;
        MonoMethodHeader *header;
        MonoInst *ins;
@@ -1699,6 +1704,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        sig = mono_method_signature (cfg->method);
 
        cinfo = cfg->arch.cinfo;
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
        mono_arch_compute_omit_fp (cfg);
 
@@ -1738,14 +1744,16 @@ mono_arch_allocate_vars (MonoCompile *cfg)
                        if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
                                offset += sizeof(mgreg_t);
                        }
+               if (!cfg->arch.omit_fp)
+                       cfg->arch.reg_save_area_offset = -offset;
        }
 
-       if (sig->ret->type != MONO_TYPE_VOID) {
+       if (sig_ret->type != MONO_TYPE_VOID) {
                switch (cinfo->ret.storage) {
                case ArgInIReg:
                case ArgInFloatSSEReg:
                case ArgInDoubleSSEReg:
-                       if ((MONO_TYPE_ISSTRUCT (sig->ret) && !mono_class_from_mono_type (sig->ret)->enumtype) || ((sig->ret->type == MONO_TYPE_TYPEDBYREF) && cinfo->vtype_retaddr)) {
+                       if ((MONO_TYPE_ISSTRUCT (sig_ret) && !mono_class_from_mono_type (sig_ret)->enumtype) || ((sig_ret->type == MONO_TYPE_TYPEDBYREF) && cinfo->vtype_retaddr)) {
                                if (cfg->globalra) {
                                        cfg->vret_addr->opcode = OP_REGVAR;
                                        cfg->vret_addr->inst_c0 = cinfo->ret.reg;
@@ -1965,6 +1973,7 @@ mono_arch_create_vars (MonoCompile *cfg)
 {
        MonoMethodSignature *sig;
        CallInfo *cinfo;
+       MonoType *sig_ret;
 
        sig = mono_method_signature (cfg->method);
 
@@ -1975,7 +1984,8 @@ mono_arch_create_vars (MonoCompile *cfg)
        if (cinfo->ret.storage == ArgValuetypeInReg)
                cfg->ret_var_is_local = TRUE;
 
-       if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig->ret)) {
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
+       if ((cinfo->ret.storage != ArgValuetypeInReg) && MONO_TYPE_ISSTRUCT (sig_ret)) {
                cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
                if (G_UNLIKELY (cfg->verbose_level > 1)) {
                        printf ("vret_addr = ");
@@ -2010,12 +2020,16 @@ mono_arch_create_vars (MonoCompile *cfg)
        cfg->arch.no_pushes = TRUE;
 #endif
 
+       if (cfg->method->save_lmf)
+               cfg->create_lmf_var = TRUE;
+
+#if !defined(HOST_WIN32)
        if (cfg->method->save_lmf) {
-               MonoInst *lmf_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
-               lmf_var->flags |= MONO_INST_VOLATILE;
-               lmf_var->flags |= MONO_INST_LMF;
-               cfg->arch.lmf_var = lmf_var;
+               cfg->lmf_ir = TRUE;
+               if (mono_get_lmf_tls_offset () != -1 && !optimize_for_xen)
+                       cfg->lmf_ir_mono_lmf = TRUE;
        }
+#endif
 
 #ifndef MONO_AMD64_NO_PUSHES
        cfg->arch_eh_jit_info = 1;
@@ -2136,9 +2150,10 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
        ArgInfo *ainfo;
        int j;
        LLVMCallInfo *linfo;
-       MonoType *t;
+       MonoType *t, *sig_ret;
 
        n = sig->param_count + sig->hasthis;
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
 
@@ -2162,7 +2177,7 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
                        linfo->ret.pair_storage [j] = arg_storage_to_llvm_arg_storage (cfg, cinfo->ret.pair_storage [j]);
        }
 
-       if (MONO_TYPE_ISSTRUCT (sig->ret) && cinfo->ret.storage == ArgInIReg) {
+       if (MONO_TYPE_ISSTRUCT (sig_ret) && cinfo->ret.storage == ArgInIReg) {
                /* Vtype returned using a hidden argument */
                linfo->ret.storage = LLVMArgVtypeRetAddr;
                linfo->vret_arg_index = cinfo->vret_arg_index;
@@ -2226,6 +2241,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
 {
        MonoInst *arg, *in;
        MonoMethodSignature *sig;
+       MonoType *sig_ret;
        int i, n, stack_size;
        CallInfo *cinfo;
        ArgInfo *ainfo;
@@ -2237,6 +2253,8 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
 
+       sig_ret = sig->ret;
+
        if (COMPILE_LLVM (cfg)) {
                /* We shouldn't be called in the llvm case */
                cfg->disable_llvm = TRUE;
@@ -2394,7 +2412,8 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        if (!sig->pinvoke && (sig->call_convention == MONO_CALL_VARARG) && (n == sig->sentinelpos))
                emit_sig_cookie (cfg, call, cinfo);
 
-       if (sig->ret && MONO_TYPE_ISSTRUCT (sig->ret)) {
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
+       if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) {
                MonoInst *vtarg;
 
                if (cinfo->ret.storage == ArgValuetypeInReg) {
@@ -2439,7 +2458,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
        }
 
 #ifdef HOST_WIN32
-       if (call->inst.opcode != OP_JMP && OP_TAILCALL != call->inst.opcode) {
+       if (call->inst.opcode != OP_TAILCALL) {
                MONO_EMIT_NEW_BIALU_IMM (cfg, OP_SUB_IMM, X86_ESP, X86_ESP, 0x20);
        }
 #endif
@@ -2494,6 +2513,7 @@ mono_arch_emit_outarg_vt (MonoCompile *cfg, MonoInst *ins, MonoInst *src)
                g_assert (!cfg->arch.no_pushes);
 
                MONO_INST_NEW (cfg, load, OP_LDADDR);
+               cfg->has_indirection = TRUE;
                load->inst_p0 = vtaddr;
                vtaddr->flags |= MONO_INST_INDIRECT;
                load->type = STACK_MP;
@@ -2833,8 +2853,9 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf)
        MonoMethodSignature *sig = dinfo->sig;
        guint8 *ret = ((DynCallArgs*)buf)->ret;
        mgreg_t res = ((DynCallArgs*)buf)->res;
+       MonoType *sig_ret = mono_type_get_underlying_type (sig->ret);
 
-       switch (mono_type_get_underlying_type (sig->ret)->type) {
+       switch (sig_ret->type) {
        case MONO_TYPE_VOID:
                *(gpointer*)ret = NULL;
                break;
@@ -2875,7 +2896,7 @@ mono_arch_finish_dyn_call (MonoDynCallInfo *info, guint8 *buf)
                *(guint64*)ret = res;
                break;
        case MONO_TYPE_GENERICINST:
-               if (MONO_TYPE_IS_REFERENCE (sig->ret)) {
+               if (MONO_TYPE_IS_REFERENCE (sig_ret)) {
                        *(gpointer*)ret = GREG_TO_PTR(res);
                        break;
                } else {
@@ -3602,6 +3623,17 @@ mono_amd64_have_tls_get (void)
 #endif
 }
 
+int
+mono_amd64_get_tls_gs_offset (void)
+{
+#ifdef TARGET_OSX
+       return tls_gs_offset;
+#else
+       g_assert_not_reached ();
+       return -1;
+#endif
+}
+
 /*
  * mono_amd64_emit_tls_get:
  * @code: buffer to store code to
@@ -3637,6 +3669,83 @@ mono_amd64_emit_tls_get (guint8* code, int dreg, int tls_offset)
        return code;
 }
 
+static guint8*
+emit_tls_get_reg (guint8* code, int dreg, int offset_reg)
+{
+       /* offset_reg contains a value translated by mono_arch_translate_tls_offset () */
+#ifdef TARGET_OSX
+       if (dreg != offset_reg)
+               amd64_mov_reg_reg (code, dreg, offset_reg, sizeof (mgreg_t));
+       amd64_prefix (code, X86_GS_PREFIX);
+       amd64_mov_reg_membase (code, dreg, dreg, 0, sizeof (mgreg_t));
+#elif defined(__linux__)
+       int tmpreg = -1;
+
+       if (dreg == offset_reg) {
+               /* Use a temporary reg by saving it to the redzone */
+               tmpreg = dreg == AMD64_RAX ? AMD64_RCX : AMD64_RAX;
+               amd64_mov_membase_reg (code, AMD64_RSP, -8, tmpreg, 8);
+               amd64_mov_reg_reg (code, tmpreg, offset_reg, sizeof (gpointer));
+               offset_reg = tmpreg;
+       }
+       x86_prefix (code, X86_FS_PREFIX);
+       amd64_mov_reg_mem (code, dreg, 0, 8);
+       amd64_mov_reg_memindex (code, dreg, dreg, 0, offset_reg, 0, 8);
+       if (tmpreg != -1)
+               amd64_mov_reg_membase (code, tmpreg, AMD64_RSP, -8, 8);
+#else
+       g_assert_not_reached ();
+#endif
+       return code;
+}
+
+static guint8*
+amd64_emit_tls_set (guint8 *code, int sreg, int tls_offset)
+{
+#ifdef HOST_WIN32
+       g_assert_not_reached ();
+#elif defined(__APPLE__)
+       x86_prefix (code, X86_GS_PREFIX);
+       amd64_mov_mem_reg (code, tls_gs_offset + (tls_offset * 8), sreg, 8);
+#else
+       g_assert (!optimize_for_xen);
+       x86_prefix (code, X86_FS_PREFIX);
+       amd64_mov_mem_reg (code, tls_offset, sreg, 8);
+#endif
+       return code;
+}
+
+static guint8*
+amd64_emit_tls_set_reg (guint8 *code, int sreg, int offset_reg)
+{
+       /* offset_reg contains a value translated by mono_arch_translate_tls_offset () */
+#ifdef HOST_WIN32
+       g_assert_not_reached ();
+#elif defined(__APPLE__)
+       x86_prefix (code, X86_GS_PREFIX);
+       amd64_mov_membase_reg (code, offset_reg, 0, sreg, 8);
+#else
+       x86_prefix (code, X86_FS_PREFIX);
+       amd64_mov_membase_reg (code, offset_reg, 0, sreg, 8);
+#endif
+       return code;
+}
+ /*
+ * mono_arch_translate_tls_offset:
+ *
+ *   Translate the TLS offset OFFSET computed by MONO_THREAD_VAR_OFFSET () into a format usable by OP_TLS_GET_REG/OP_TLS_SET_REG.
+ */
+int
+mono_arch_translate_tls_offset (int offset)
+{
+#ifdef __APPLE__
+       return tls_gs_offset + (offset * 8);
+#else
+       return offset;
+#endif
+}
+
 /*
  * emit_setup_lmf:
  *
@@ -3687,8 +3796,9 @@ emit_setup_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, int cfa_offse
 
        /* These can't contain refs */
        mini_gc_set_slot_type_from_fp (cfg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), SLOT_NOREF);
+#ifdef HOST_WIN32
        mini_gc_set_slot_type_from_fp (cfg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), SLOT_NOREF);
-       mini_gc_set_slot_type_from_fp (cfg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, method), SLOT_NOREF);
+#endif
        mini_gc_set_slot_type_from_fp (cfg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rip), SLOT_NOREF);
        mini_gc_set_slot_type_from_fp (cfg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rsp), SLOT_NOREF);
 
@@ -3707,94 +3817,59 @@ emit_setup_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, int cfa_offse
        return code;
 }
 
+#ifdef HOST_WIN32
 /*
- * emit_save_lmf:
+ * emit_push_lmf:
  *
  *   Emit code to push an LMF structure on the LMF stack.
  */
 static guint8*
-emit_save_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, gboolean *args_clobbered)
+emit_push_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, gboolean *args_clobbered)
 {
-       if ((lmf_tls_offset != -1) && !optimize_for_xen) {
-               /*
-                * Optimized version which uses the mono_lmf TLS variable instead of 
-                * indirection through the mono_lmf_addr TLS variable.
-                */
-               /* %rax = previous_lmf */
-               x86_prefix (code, X86_FS_PREFIX);
-               amd64_mov_reg_mem (code, AMD64_RAX, lmf_tls_offset, 8);
-
-               /* Save previous_lmf */
-               amd64_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), AMD64_RAX, 8);
-               /* Set new lmf */
-               if (lmf_offset == 0) {
-                       x86_prefix (code, X86_FS_PREFIX);
-                       amd64_mov_mem_reg (code, lmf_tls_offset, cfg->frame_reg, 8);
-               } else {
-                       amd64_lea_membase (code, AMD64_R11, cfg->frame_reg, lmf_offset);
-                       x86_prefix (code, X86_FS_PREFIX);
-                       amd64_mov_mem_reg (code, lmf_tls_offset, AMD64_R11, 8);
-               }
+       if (jit_tls_offset != -1) {
+               code = mono_amd64_emit_tls_get (code, AMD64_RAX, jit_tls_offset);
+               amd64_alu_reg_imm (code, X86_ADD, AMD64_RAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
        } else {
-               if (lmf_addr_tls_offset != -1) {
-                       /* Load lmf quicky using the FS register */
-                       code = mono_amd64_emit_tls_get (code, AMD64_RAX, lmf_addr_tls_offset);
-#ifdef HOST_WIN32
-                       /* The TLS key actually contains a pointer to the MonoJitTlsData structure */
-                       /* FIXME: Add a separate key for LMF to avoid this */
-                       amd64_alu_reg_imm (code, X86_ADD, AMD64_RAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
-#endif
-               }
-               else {
-                       /* 
-                        * The call might clobber argument registers, but they are already
-                        * saved to the stack/global regs.
-                        */
-                       if (args_clobbered)
-                               *args_clobbered = TRUE;
-                       code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, 
-                                                         (gpointer)"mono_get_lmf_addr", TRUE);         
-               }
-
-               /* Save lmf_addr */
-               amd64_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), AMD64_RAX, sizeof(gpointer));
-               /* Save previous_lmf */
-               amd64_mov_reg_membase (code, AMD64_R11, AMD64_RAX, 0, sizeof(gpointer));
-               amd64_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), AMD64_R11, sizeof(gpointer));
-               /* Set new lmf */
-               amd64_lea_membase (code, AMD64_R11, cfg->frame_reg, lmf_offset);
-               amd64_mov_membase_reg (code, AMD64_RAX, 0, AMD64_R11, sizeof(gpointer));
+               /* 
+                * The call might clobber argument registers, but they are already
+                * saved to the stack/global regs.
+                */
+               if (args_clobbered)
+                       *args_clobbered = TRUE;
+               code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, 
+                                                 (gpointer)"mono_get_lmf_addr", TRUE);         
        }
 
+       /* Save lmf_addr */
+       amd64_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), AMD64_RAX, sizeof(gpointer));
+       /* Save previous_lmf */
+       amd64_mov_reg_membase (code, AMD64_R11, AMD64_RAX, 0, sizeof(gpointer));
+       amd64_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), AMD64_R11, sizeof(gpointer));
+       /* Set new lmf */
+       amd64_lea_membase (code, AMD64_R11, cfg->frame_reg, lmf_offset);
+       amd64_mov_membase_reg (code, AMD64_RAX, 0, AMD64_R11, sizeof(gpointer));
+
        return code;
 }
+#endif
 
+#ifdef HOST_WIN32
 /*
- * emit_save_lmf:
+ * emit_pop_lmf:
  *
  *   Emit code to pop an LMF structure from the LMF stack.
  */
 static guint8*
-emit_restore_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
+emit_pop_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
 {
-       if ((lmf_tls_offset != -1) && !optimize_for_xen) {
-               /*
-                * Optimized version which uses the mono_lmf TLS variable instead of indirection
-                * through the mono_lmf_addr TLS variable.
-                */
-               /* reg = previous_lmf */
-               amd64_mov_reg_membase (code, AMD64_R11, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), sizeof(gpointer));
-               x86_prefix (code, X86_FS_PREFIX);
-               amd64_mov_mem_reg (code, lmf_tls_offset, AMD64_R11, 8);
-       } else {
-               /* Restore previous lmf */
-               amd64_mov_reg_membase (code, AMD64_RCX, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), sizeof(gpointer));
-               amd64_mov_reg_membase (code, AMD64_R11, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), sizeof(gpointer));
-               amd64_mov_membase_reg (code, AMD64_R11, 0, AMD64_RCX, sizeof(gpointer));
-       }
+       /* Restore previous lmf */
+       amd64_mov_reg_membase (code, AMD64_RCX, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), sizeof(gpointer));
+       amd64_mov_reg_membase (code, AMD64_R11, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), sizeof(gpointer));
+       amd64_mov_membase_reg (code, AMD64_R11, 0, AMD64_RCX, sizeof(gpointer));
 
        return code;
 }
+#endif
 
 #define REAL_PRINT_REG(text,reg) \
 mono_assert (reg >= 0); \
@@ -4741,7 +4816,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                }
                case OP_TAILCALL: {
                        MonoCallInst *call = (MonoCallInst*)ins;
-                       int pos = 0, i;
+                       int i, save_area_offset;
 
                        /* FIXME: no tracing support... */
                        if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE)
@@ -4749,41 +4824,26 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        g_assert (!cfg->method->save_lmf);
 
-                       if (cfg->arch.omit_fp) {
-                               guint32 save_offset = 0;
-                               /* Pop callee-saved registers */
-                               for (i = 0; i < AMD64_NREG; ++i)
-                                       if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                                               amd64_mov_reg_membase (code, i, AMD64_RSP, save_offset, 8);
-                                               save_offset += 8;
-                                       }
-                               amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, cfg->arch.stack_alloc_size);
+                       /* Restore callee saved registers */
+                       save_area_offset = cfg->arch.reg_save_area_offset;
+                       for (i = 0; i < AMD64_NREG; ++i)
+                               if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
+                                       amd64_mov_reg_membase (code, i, cfg->frame_reg, save_area_offset, 8);
+                                       save_area_offset += 8;
+                               }
 
+                       if (cfg->arch.omit_fp) {
+                               if (cfg->arch.stack_alloc_size)
+                                       amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, cfg->arch.stack_alloc_size);
                                // FIXME:
                                if (call->stack_usage)
                                        NOT_IMPLEMENTED;
-                       }
-                       else {
-                               for (i = 0; i < AMD64_NREG; ++i)
-                                       if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i)))
-                                               pos -= sizeof(mgreg_t);
-
-                               /* Restore callee-saved registers */
-                               for (i = AMD64_NREG - 1; i > 0; --i) {
-                                       if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                                               amd64_mov_reg_membase (code, i, AMD64_RBP, pos, sizeof(mgreg_t));
-                                               pos += sizeof(mgreg_t);
-                                       }
-                               }
-
+                       } else {
                                /* Copy arguments on the stack to our argument area */
                                for (i = 0; i < call->stack_usage; i += sizeof(mgreg_t)) {
                                        amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RSP, i, sizeof(mgreg_t));
                                        amd64_mov_membase_reg (code, AMD64_RBP, 16 + i, AMD64_RAX, sizeof(mgreg_t));
                                }
-                       
-                               if (pos)
-                                       amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, pos);
 
                                amd64_leave (code);
                        }
@@ -4942,8 +5002,8 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                }
                case OP_AMD64_SAVE_SP_TO_LMF: {
-                       MonoInst *lmf_var = cfg->arch.lmf_var;
-                       amd64_mov_membase_reg (code, cfg->frame_reg, lmf_var->inst_offset + G_STRUCT_OFFSET (MonoLMF, rsp), AMD64_RSP, 8);
+                       MonoInst *lmf_var = cfg->lmf_var;
+                       amd64_mov_membase_reg (code, lmf_var->inst_basereg, lmf_var->inst_offset + G_STRUCT_OFFSET (MonoLMF, rsp), AMD64_RSP, 8);
                        break;
                }
                case OP_X86_PUSH:
@@ -5103,6 +5163,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_BR_REG:
                        amd64_jump_reg (code, ins->sreg1);
                        break;
+               case OP_ICNEQ:
+               case OP_ICGE:
+               case OP_ICLE:
+               case OP_ICGE_UN:
+               case OP_ICLE_UN:
+
                case OP_CEQ:
                case OP_LCEQ:
                case OP_ICEQ:
@@ -5199,16 +5265,23 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        amd64_sse_movss_reg_membase (code, ins->dreg, ins->inst_basereg, ins->inst_offset);
                        amd64_sse_cvtss2sd_reg_reg (code, ins->dreg, ins->dreg);
                        break;
-               case OP_ICONV_TO_R4: /* FIXME: change precision */
+               case OP_ICONV_TO_R4:
+                       amd64_sse_cvtsi2ss_reg_reg_size (code, ins->dreg, ins->sreg1, 4);
+                       amd64_sse_cvtss2sd_reg_reg (code, ins->dreg, ins->dreg);
+                       break;
                case OP_ICONV_TO_R8:
                        amd64_sse_cvtsi2sd_reg_reg_size (code, ins->dreg, ins->sreg1, 4);
                        break;
-               case OP_LCONV_TO_R4: /* FIXME: change precision */
+               case OP_LCONV_TO_R4:
+                       amd64_sse_cvtsi2ss_reg_reg (code, ins->dreg, ins->sreg1);
+                       amd64_sse_cvtss2sd_reg_reg (code, ins->dreg, ins->dreg);
+                       break;
                case OP_LCONV_TO_R8:
                        amd64_sse_cvtsi2sd_reg_reg (code, ins->dreg, ins->sreg1);
                        break;
                case OP_FCONV_TO_R4:
-                       /* FIXME: nothing to do ?? */
+                       amd64_sse_cvtsd2ss_reg_reg (code, ins->dreg, ins->sreg1);
+                       amd64_sse_cvtss2sd_reg_reg (code, ins->dreg, ins->dreg);
                        break;
                case OP_FCONV_TO_I1:
                        code = emit_float_to_int (cfg, code, ins->dreg, ins->sreg1, 1, TRUE);
@@ -5371,6 +5444,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                         */
                        amd64_sse_comisd_reg_reg (code, ins->sreg2, ins->sreg1);
                        break;
+               case OP_FCNEQ:
                case OP_FCEQ: {
                        /* zeroing the register at the start results in 
                         * shorter and faster code (we can also remove the widening op)
@@ -5380,8 +5454,19 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        amd64_sse_comisd_reg_reg (code, ins->sreg1, ins->sreg2);
                        unordered_check = code;
                        x86_branch8 (code, X86_CC_P, 0, FALSE);
-                       amd64_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
-                       amd64_patch (unordered_check, code);
+
+                       if (ins->opcode == OP_FCEQ) {
+                               amd64_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
+                               amd64_patch (unordered_check, code);
+                       } else {
+                               guchar *jump_to_end;
+                               amd64_set_reg (code, X86_CC_NE, ins->dreg, FALSE);
+                               jump_to_end = code;
+                               x86_jump8 (code, 0);
+                               amd64_patch (unordered_check, code);
+                               amd64_inc_reg (code, ins->dreg);
+                               amd64_patch (jump_to_end, code);
+                       }
                        break;
                }
                case OP_FCLT:
@@ -5405,6 +5490,16 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                amd64_set_reg (code, X86_CC_GT, ins->dreg, FALSE);
                        }
                        break;
+               case OP_FCLE: {
+                       guchar *unordered_check;
+                       amd64_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                       amd64_sse_comisd_reg_reg (code, ins->sreg2, ins->sreg1);
+                       unordered_check = code;
+                       x86_branch8 (code, X86_CC_P, 0, FALSE);
+                       amd64_set_reg (code, X86_CC_NB, ins->dreg, FALSE);
+                       amd64_patch (unordered_check, code);
+                       break;
+               }
                case OP_FCGT:
                case OP_FCGT_UN: {
                        /* zeroing the register at the start results in 
@@ -5423,6 +5518,17 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        }
                        break;
                }
+               case OP_FCGE: {
+                       guchar *unordered_check;
+                       amd64_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                       amd64_sse_comisd_reg_reg (code, ins->sreg2, ins->sreg1);
+                       unordered_check = code;
+                       x86_branch8 (code, X86_CC_P, 0, FALSE);
+                       amd64_set_reg (code, X86_CC_NA, ins->dreg, FALSE);
+                       amd64_patch (unordered_check, code);
+                       break;
+               }
+               
                case OP_FCLT_MEMBASE:
                case OP_FCGT_MEMBASE:
                case OP_FCLT_UN_MEMBASE:
@@ -5564,19 +5670,16 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                }
                case OP_TLS_GET_REG:
-#ifdef TARGET_OSX
-                       // FIXME: tls_gs_offset can change too, do these when calculating the tls offset
-                       if (ins->dreg != ins->sreg1)
-                               amd64_mov_reg_reg (code, ins->dreg, ins->sreg1, sizeof (gpointer));
-                       amd64_shift_reg_imm (code, X86_SHL, ins->dreg, 3);
-                       if (tls_gs_offset)
-                               amd64_alu_reg_imm (code, X86_ADD, ins->dreg, tls_gs_offset);
-                       x86_prefix (code, X86_GS_PREFIX);
-                       amd64_mov_reg_membase (code, ins->dreg, ins->dreg, 0, sizeof (gpointer));
-#else
-                       g_assert_not_reached ();
-#endif
+                       code = emit_tls_get_reg (code, ins->dreg, ins->sreg1);
+                       break;
+               case OP_TLS_SET: {
+                       code = amd64_emit_tls_set (code, ins->sreg1, ins->inst_offset);
                        break;
+               }
+               case OP_TLS_SET_REG: {
+                       code = amd64_emit_tls_set_reg (code, ins->sreg1, ins->sreg2);
+                       break;
+               }
                case OP_MEMORY_BARRIER: {
                        switch (ins->backend.memory_barrier_kind) {
                        case StoreLoadBarrier:
@@ -6562,7 +6665,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        int alloc_size, pos, i, cfa_offset, quad, max_epilog_size;
        guint8 *code;
        CallInfo *cinfo;
-       MonoInst *lmf_var = cfg->arch.lmf_var;
+       MonoInst *lmf_var = cfg->lmf_var;
        gboolean args_clobbered = FALSE;
        gboolean trace = FALSE;
 #ifdef __native_client_codegen__
@@ -6639,23 +6742,6 @@ mono_arch_emit_prolog (MonoCompile *cfg)
 #endif
        }
 
-       /* Save callee saved registers */
-       if (!cfg->arch.omit_fp && !method->save_lmf) {
-               int offset = cfa_offset;
-
-               for (i = 0; i < AMD64_NREG; ++i)
-                       if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                               amd64_push_reg (code, i);
-                               pos += 8; /* AMD64 push inst is always 8 bytes, no way to change it */
-                               offset += 8;
-                               mono_emit_unwind_op_offset (cfg, code, i, - offset);
-                               async_exc_point (code);
-
-                               /* These are handled automatically by the stack marking code */
-                               mini_gc_set_slot_type_from_cfa (cfg, - offset, SLOT_NOREF);
-                       }
-       }
-
        /* The param area is always at offset 0 from sp */
        /* This needs to be allocated here, since it has to come after the spill area */
        if (cfg->arch.no_pushes && cfg->param_area) {
@@ -6792,19 +6878,31 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        }
 
        /* Save callee saved registers */
-       if (cfg->arch.omit_fp && !method->save_lmf) {
-               gint32 save_area_offset = cfg->arch.reg_save_area_offset;
+       if (!method->save_lmf) {
+               gint32 save_area_offset;
+
+               if (cfg->arch.omit_fp) {
+                       save_area_offset = cfg->arch.reg_save_area_offset;
+                       /* Save caller saved registers after sp is adjusted */
+                       /* The registers are saved at the bottom of the frame */
+                       /* FIXME: Optimize this so the regs are saved at the end of the frame in increasing order */
+               } else {
+                       /* The registers are saved just below the saved rbp */
+                       save_area_offset = cfg->arch.reg_save_area_offset;
+               }
 
-               /* Save caller saved registers after sp is adjusted */
-               /* The registers are saved at the bottom of the frame */
-               /* FIXME: Optimize this so the regs are saved at the end of the frame in increasing order */
                for (i = 0; i < AMD64_NREG; ++i)
                        if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                               amd64_mov_membase_reg (code, AMD64_RSP, save_area_offset, i, 8);
-                               mono_emit_unwind_op_offset (cfg, code, i, - (cfa_offset - save_area_offset));
+                               amd64_mov_membase_reg (code, cfg->frame_reg, save_area_offset, i, 8);
 
-                               /* These are handled automatically by the stack marking code */
-                               mini_gc_set_slot_type_from_cfa (cfg, - (cfa_offset - save_area_offset), SLOT_NOREF);
+                               if (cfg->arch.omit_fp) {
+                                       mono_emit_unwind_op_offset (cfg, code, i, - (cfa_offset - save_area_offset));
+                                       /* These are handled automatically by the stack marking code */
+                                       mini_gc_set_slot_type_from_cfa (cfg, - (cfa_offset - save_area_offset), SLOT_NOREF);
+                               } else {
+                                       mono_emit_unwind_op_offset (cfg, code, i, - (-save_area_offset + (2 * 8)));
+                                       // FIXME: GC
+                               }
 
                                save_area_offset += 8;
                                async_exc_point (code);
@@ -7005,9 +7103,13 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                }
        }
 
+#ifdef HOST_WIN32
        if (method->save_lmf) {
-               code = emit_save_lmf (cfg, code, lmf_var->inst_offset, &args_clobbered);
+               code = emit_push_lmf (cfg, code, lmf_var->inst_offset, &args_clobbered);
        }
+#else
+       args_clobbered = TRUE;
+#endif
 
        if (trace) {
                args_clobbered = TRUE;
@@ -7126,7 +7228,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        guint8 *code;
        int max_epilog_size;
        CallInfo *cinfo;
-       gint32 lmf_offset = cfg->arch.lmf_var ? ((MonoInst*)cfg->arch.lmf_var)->inst_offset : -1;
+       gint32 lmf_offset = cfg->lmf_var ? ((MonoInst*)cfg->lmf_var)->inst_offset : -1;
        
        max_epilog_size = get_max_epilog_size (cfg);
 
@@ -7141,10 +7243,14 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
                code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, code, TRUE);
 
-       /* the code restoring the registers must be kept in sync with OP_JMP */
+       /* the code restoring the registers must be kept in sync with OP_TAILCALL */
        pos = 0;
        
        if (method->save_lmf) {
+#ifdef HOST_WIN32
+               code = emit_pop_lmf (cfg, code, lmf_offset);
+#endif
+
                /* check if we need to restore protection of the stack after a stack overflow */
                if (mono_get_jit_tls_offset () != -1) {
                        guint8 *patch;
@@ -7163,8 +7269,6 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                        /* FIXME: maybe save the jit tls in the prolog */
                }
 
-               code = emit_restore_lmf (cfg, code, lmf_offset);
-
                /* Restore caller saved regs */
                if (cfg->used_int_regs & (1 << AMD64_RBP)) {
                        amd64_mov_reg_membase (code, AMD64_RBP, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rbp), 8);
@@ -7197,40 +7301,13 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                }
 #endif
        } else {
+               gint32 save_area_offset = cfg->arch.reg_save_area_offset;
 
-               if (cfg->arch.omit_fp) {
-                       gint32 save_area_offset = cfg->arch.reg_save_area_offset;
-
-                       for (i = 0; i < AMD64_NREG; ++i)
-                               if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                                       amd64_mov_reg_membase (code, i, AMD64_RSP, save_area_offset, 8);
-                                       save_area_offset += 8;
-                               }
-               }
-               else {
-                       for (i = 0; i < AMD64_NREG; ++i)
-                               if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i)))
-                                       pos -= sizeof(mgreg_t);
-
-                       if (pos) {
-                               if (pos == - sizeof(mgreg_t)) {
-                                       /* Only one register, so avoid lea */
-                                       for (i = AMD64_NREG - 1; i > 0; --i)
-                                               if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                                                       amd64_mov_reg_membase (code, i, AMD64_RBP, pos, 8);
-                                               }
-                               }
-                               else {
-                                       amd64_lea_membase (code, AMD64_RSP, AMD64_RBP, pos);
-
-                                       /* Pop registers in reverse order */
-                                       for (i = AMD64_NREG - 1; i > 0; --i)
-                                               if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
-                                                       amd64_pop_reg (code, i);
-                                               }
-                               }
+               for (i = 0; i < AMD64_NREG; ++i)
+                       if (AMD64_IS_CALLEE_SAVED_REG (i) && (cfg->used_int_regs & (1 << i))) {
+                               amd64_mov_reg_membase (code, i, cfg->frame_reg, save_area_offset, 8);
+                               save_area_offset += 8;
                        }
-               }
        }
 
        /* Load returned vtypes into registers if needed */
@@ -7953,7 +8030,7 @@ mono_arch_get_delegate_invoke_impl (MonoMethodSignature *sig, gboolean has_targe
                return NULL;
 
        /* FIXME: Support more cases */
-       if (MONO_TYPE_ISSTRUCT (sig->ret))
+       if (MONO_TYPE_ISSTRUCT (mini_type_get_underlying_type (NULL, sig->ret)))
                return NULL;
 
        if (has_target) {
@@ -8005,24 +8082,15 @@ mono_arch_finish_init (void)
         * We need to init this multiple times, since when we are first called, the key might not
         * be initialized yet.
         */
-       appdomain_tls_offset = mono_domain_get_tls_key ();
-       lmf_tls_offset = mono_get_jit_tls_key ();
-       lmf_addr_tls_offset = mono_get_jit_tls_key ();
+       jit_tls_offset = mono_get_jit_tls_key ();
 
        /* Only 64 tls entries can be accessed using inline code */
-       if (appdomain_tls_offset >= 64)
-               appdomain_tls_offset = -1;
-       if (lmf_tls_offset >= 64)
-               lmf_tls_offset = -1;
-       if (lmf_addr_tls_offset >= 64)
-               lmf_addr_tls_offset = -1;
+       if (jit_tls_offset >= 64)
+               jit_tls_offset = -1;
 #else
 #ifdef MONO_XEN_OPT
        optimize_for_xen = access ("/proc/xen", F_OK) == 0;
 #endif
-       appdomain_tls_offset = mono_domain_get_tls_offset ();
-       lmf_tls_offset = mono_get_lmf_tls_offset ();
-       lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
 #endif
 }
 
@@ -8335,18 +8403,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
        return 0;
 }
 
-MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       MonoInst* ins;
-       
-       if (appdomain_tls_offset == -1)
-               return NULL;
-       
-       MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-       ins->inst_offset = appdomain_tls_offset;
-       return ins;
-}
-
 #define _CTX_REG(ctx,fld,i) ((&ctx->fld)[i])
 
 mgreg_t
@@ -8359,12 +8415,7 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
        case AMD64_RBP: return ctx->rbp;
        case AMD64_RSP: return ctx->rsp;
        default:
-               if (reg < 8)
-                       return _CTX_REG (ctx, rax, reg);
-               else if (reg >= 12)
-                       return _CTX_REG (ctx, r12, reg - 12);
-               else
-                       g_assert_not_reached ();
+               return _CTX_REG (ctx, rax, reg);
        }
 }
 
@@ -8388,12 +8439,7 @@ mono_arch_context_set_int_reg (MonoContext *ctx, int reg, mgreg_t val)
                ctx->rsp = val;
                break;
        default:
-               if (reg < 8)
-                       _CTX_REG (ctx, rax, reg) = val;
-               else if (reg >= 12)
-                       _CTX_REG (ctx, r12, reg - 12) = val;
-               else
-                       g_assert_not_reached ();
+               _CTX_REG (ctx, rax, reg) = val;
        }
 }
 
@@ -8671,4 +8717,13 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return info;
 }
 
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.rsp = (gssize)ext;
+}
+
 #endif
index fd84eab37980bca3d71852d67c18a20f1bdfbc50..b523d9981cd5df64e67e02d64ef9bac4b83c81a6 100644 (file)
@@ -47,7 +47,7 @@ struct sigcontext {
        guint64 eip;
 };
 
-typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_RECORD *info, void *context);
+typedef void (* MonoW32ExceptionHandler) (int _dummy, EXCEPTION_POINTERS *info, void *context);
 void win32_seh_init(void);
 void win32_seh_cleanup(void);
 void win32_seh_set_handler(int type, MonoW32ExceptionHandler handler);
@@ -159,16 +159,17 @@ struct sigcontext {
 
 struct MonoLMF {
        /* 
-        * If the lowest bit is set to 1, then this LMF has the rip field set. Otherwise,
+        * If the lowest bit is set, then this LMF has the rip field set. Otherwise,
         * the rip field is not set, and the rsp field points to the stack location where
         * the caller ip is saved.
-        * If the second lowest bit is set to 1, then this is a MonoLMFExt structure, and
+        * If the second lowest bit is set, then this is a MonoLMFExt structure, and
         * the other fields are not valid.
+        * If the third lowest bit is set, then this is a MonoLMFTramp structure.
         */
        gpointer    previous_lmf;
+#ifdef HOST_WIN32
        gpointer    lmf_addr;
-       /* This is only set in trampoline LMF frames */
-       MonoMethod *method;
+#endif
 #if defined(__default_codegen__) || defined(HOST_WIN32)
        guint64     rip;
 #elif defined(__native_client_codegen__)
@@ -189,6 +190,13 @@ struct MonoLMF {
 #endif
 };
 
+/* LMF structure used by the JIT trampolines */
+typedef struct {
+       struct MonoLMF lmf;
+       guint64 *regs;
+       gpointer lmf_addr;
+} MonoLMFTramp;
+
 typedef struct MonoCompileArch {
        gint32 localloc_offset;
        gint32 reg_save_area_offset;
@@ -334,9 +342,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_HAVE_IS_INT_OVERFLOW 1
 
 #define MONO_ARCH_ENABLE_REGALLOC_IN_EH_BLOCKS 1
-#if !defined(__APPLE__)
 #define MONO_ARCH_ENABLE_MONO_LMF_VAR 1
-#endif
 #define MONO_ARCH_HAVE_INVALIDATE_METHOD 1
 #define MONO_ARCH_HAVE_CREATE_DELEGATE_TRAMPOLINE 1
 #define MONO_ARCH_HAVE_ATOMIC_ADD 1
@@ -396,16 +402,13 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1
 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
 #define MONO_ARCH_HAVE_CREATE_LLVM_NATIVE_THUNK 1
+#define MONO_ARCH_HAVE_OP_TAIL_CALL 1
+#define MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET 1
 
-#ifdef TARGET_OSX
+#if defined(TARGET_OSX) || defined(__linux__)
 #define MONO_ARCH_HAVE_TLS_GET_REG 1
 #endif
 
-gboolean
-mono_amd64_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) MONO_INTERNAL;
-
-#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_amd64_tail_call_supported (caller_sig, callee_sig)
-
 /* Used for optimization, not complete */
 #define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE)
 
@@ -446,6 +449,9 @@ mono_amd64_have_tls_get (void) MONO_INTERNAL;
 GSList*
 mono_amd64_get_exception_trampolines (gboolean aot) MONO_INTERNAL;
 
+int
+mono_amd64_get_tls_gs_offset (void) MONO_INTERNAL;
+
 typedef struct {
        guint8 *address;
        guint8 saved_byte;
index 8e69537f14d96097ac12b5eb8b44b3150a321b31..9ced34a709f7c53d17af7c53693c176114ebb909 100644 (file)
 #error "ARM_FPU_NONE is defined while one of ARM_FPU_VFP/ARM_FPU_VFP_HARD is defined"
 #endif
 
-#if defined(MONO_ARCH_SOFT_FLOAT_FALLBACK)
+/*
+ * IS_SOFT_FLOAT: Is full software floating point used?
+ * IS_HARD_FLOAT: Is full hardware floating point used?
+ * IS_VFP: Is hardware floating point with software ABI used?
+ *
+ * These are not necessarily constants, e.g. IS_SOFT_FLOAT and
+ * IS_VFP may delegate to mono_arch_is_soft_float ().
+ */
+
+#if defined(ARM_FPU_VFP_HARD)
+#define IS_SOFT_FLOAT (FALSE)
+#define IS_HARD_FLOAT (TRUE)
+#define IS_VFP (TRUE)
+#elif defined(ARM_FPU_NONE)
 #define IS_SOFT_FLOAT (mono_arch_is_soft_float ())
+#define IS_HARD_FLOAT (FALSE)
 #define IS_VFP (!mono_arch_is_soft_float ())
 #else
 #define IS_SOFT_FLOAT (FALSE)
+#define IS_HARD_FLOAT (FALSE)
 #define IS_VFP (TRUE)
 #endif
 
@@ -105,6 +120,9 @@ static gboolean iphone_abi = FALSE;
  */
 static MonoArmFPU arm_fpu;
 
+static int vfp_scratch1 = ARM_VFP_F28;
+static int vfp_scratch2 = ARM_VFP_F30;
+
 static int i8_align;
 
 static volatile int ss_trigger_var = 0;
@@ -154,7 +172,7 @@ int mono_exc_esp_offset = 0;
 
 #define ADD_LR_PC_4 ((ARMCOND_AL << ARMCOND_SHIFT) | (1 << 25) | (1 << 23) | (ARMREG_PC << 16) | (ARMREG_LR << 12) | 4)
 #define MOV_LR_PC ((ARMCOND_AL << ARMCOND_SHIFT) | (1 << 24) | (0xa << 20) |  (ARMREG_LR << 12) | ARMREG_PC)
-#define DEBUG_IMT 0
+//#define DEBUG_IMT 0
  
 /* A variant of ARM_LDR_IMM which can handle large offsets */
 #define ARM_LDR_IMM_GENERAL(code, dreg, basereg, offset, scratch_reg) do { \
@@ -354,7 +372,6 @@ mono_arm_load_jumptable_entry (guint8 *code, gpointer* jte, ARMReg reg)
 }
 #endif
 
-
 static guint8*
 emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
 {
@@ -364,10 +381,18 @@ emit_move_return_value (MonoCompile *cfg, MonoInst *ins, guint8 *code)
        case OP_FCALL_MEMBASE:
                if (IS_VFP) {
                        if (((MonoCallInst*)ins)->signature->ret->type == MONO_TYPE_R4) {
-                               ARM_FMSR (code, ins->dreg, ARMREG_R0);
-                               ARM_CVTS (code, ins->dreg, ins->dreg);
+                               if (IS_HARD_FLOAT) {
+                                       ARM_CVTS (code, ins->dreg, ARM_VFP_F0);
+                               } else {
+                                       ARM_FMSR (code, ins->dreg, ARMREG_R0);
+                                       ARM_CVTS (code, ins->dreg, ins->dreg);
+                               }
                        } else {
-                               ARM_FMDRR (code, ARMREG_R0, ARMREG_R1, ins->dreg);
+                               if (IS_HARD_FLOAT) {
+                                       ARM_CPYD (code, ins->dreg, ARM_VFP_D0);
+                               } else {
+                                       ARM_FMDRR (code, ARMREG_R0, ARMREG_R1, ins->dreg);
+                               }
                        }
                }
                break;
@@ -465,6 +490,37 @@ emit_save_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
        return code;
 }
 
+typedef struct {
+       gint32 vreg;
+       gint32 hreg;
+} FloatArgData;
+
+static guint8 *
+emit_float_args (MonoCompile *cfg, MonoCallInst *inst, guint8 *code, int *max_len, guint *offset)
+{
+       GSList *list;
+
+       for (list = inst->float_args; list; list = list->next) {
+               FloatArgData *fad = list->data;
+               MonoInst *var = get_vreg_to_inst (cfg, fad->vreg);
+
+               *max_len += 4;
+
+               if (*offset + *max_len > cfg->code_size) {
+                       cfg->code_size += *max_len;
+                       cfg->native_code = g_realloc (cfg->native_code, cfg->code_size);
+
+                       code = cfg->native_code + *offset;
+               }
+
+               ARM_FLDS (code, fad->hreg, var->inst_basereg, var->inst_offset);
+
+               *offset = code - cfg->native_code;
+       }
+
+       return code;
+}
+
 /*
  * emit_save_lmf:
  *
@@ -904,6 +960,12 @@ mono_arch_is_soft_float (void)
 }
 #endif
 
+gboolean
+mono_arm_is_hard_float (void)
+{
+       return arm_fpu == MONO_ARM_FPU_VFP_HARD;
+}
+
 static gboolean
 is_regsize_var (MonoGenericSharingContext *gsctx, MonoType *t) {
        if (t->byref)
@@ -1152,10 +1214,97 @@ add_general (guint *gr, guint *stack_size, ArgInfo *ainfo, gboolean simple)
        (*gr) ++;
 }
 
+static void inline
+add_float (guint *fpr, guint *stack_size, ArgInfo *ainfo, gboolean is_double, gint *float_spare)
+{
+       /*
+        * If we're calling a function like this:
+        *
+        * void foo(float a, double b, float c)
+        *
+        * We pass a in s0 and b in d1. That leaves us
+        * with s1 being unused. The armhf ABI recognizes
+        * this and requires register assignment to then
+        * use that for the next single-precision arg,
+        * i.e. c in this example. So float_spare either
+        * tells us which reg to use for the next single-
+        * precision arg, or it's -1, meaning use *fpr.
+        *
+        * Note that even though most of the JIT speaks
+        * double-precision, fpr represents single-
+        * precision registers.
+        *
+        * See parts 5.5 and 6.1.2 of the AAPCS for how
+        * this all works.
+        */
+
+       if (*fpr < ARM_VFP_F16 || (!is_double && *float_spare >= 0)) {
+               ainfo->storage = RegTypeFP;
+
+               if (is_double) {
+                       /*
+                        * If we're passing a double-precision value
+                        * and *fpr is odd (e.g. it's s1, s3, ...)
+                        * we need to use the next even register. So
+                        * we mark the current *fpr as a spare that
+                        * can be used for the next single-precision
+                        * value.
+                        */
+                       if (*fpr % 2) {
+                               *float_spare = *fpr;
+                               (*fpr)++;
+                       }
+
+                       /*
+                        * At this point, we have an even register
+                        * so we assign that and move along.
+                        */
+                       ainfo->reg = *fpr;
+                       *fpr += 2;
+               } else if (*float_spare >= 0) {
+                       /*
+                        * We're passing a single-precision value
+                        * and it looks like a spare single-
+                        * precision register is available. Let's
+                        * use it.
+                        */
+
+                       ainfo->reg = *float_spare;
+                       *float_spare = -1;
+               } else {
+                       /*
+                        * If we hit this branch, we're passing a
+                        * single-precision value and we can simply
+                        * use the next available register.
+                        */
+
+                       ainfo->reg = *fpr;
+                       (*fpr)++;
+               }
+       } else {
+               /*
+                * We've exhausted available floating point
+                * regs, so pass the rest on the stack.
+                */
+
+               if (is_double) {
+                       *stack_size += 7;
+                       *stack_size &= ~7;
+               }
+
+               ainfo->offset = *stack_size;
+               ainfo->reg = ARMREG_SP;
+               ainfo->storage = RegTypeBase;
+
+               *stack_size += 8;
+       }
+}
+
 static CallInfo*
 get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSignature *sig)
 {
-       guint i, gr, pstart;
+       guint i, gr, fpr, pstart;
+       gint float_spare;
        int n = sig->hasthis + sig->param_count;
        MonoType *simpletype;
        guint32 stack_size = 0;
@@ -1170,6 +1319,8 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
 
        cinfo->nargs = n;
        gr = ARMREG_R0;
+       fpr = ARM_VFP_F0;
+       float_spare = -1;
 
        t = mini_type_get_underlying_type (gsctx, sig->ret);
        if (MONO_TYPE_ISSTRUCT (t)) {
@@ -1222,6 +1373,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                        /* Prevent implicit arguments and sig_cookie from
                           being passed in registers */
                        gr = ARMREG_R3 + 1;
+                       fpr = ARM_VFP_F16;
                        /* Emit the signature cookie just before the implicit arguments */
                        add_general (&gr, &stack_size, &cinfo->sig_cookie, TRUE);
                }
@@ -1263,7 +1415,6 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                case MONO_TYPE_STRING:
                case MONO_TYPE_SZARRAY:
                case MONO_TYPE_ARRAY:
-               case MONO_TYPE_R4:
                        cinfo->args [n].size = sizeof (gpointer);
                        add_general (&gr, &stack_size, ainfo, TRUE);
                        n++;
@@ -1344,11 +1495,30 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                }
                case MONO_TYPE_U8:
                case MONO_TYPE_I8:
-               case MONO_TYPE_R8:
                        ainfo->size = 8;
                        add_general (&gr, &stack_size, ainfo, FALSE);
                        n++;
                        break;
+               case MONO_TYPE_R4:
+                       ainfo->size = 4;
+
+                       if (IS_HARD_FLOAT)
+                               add_float (&fpr, &stack_size, ainfo, FALSE, &float_spare);
+                       else
+                               add_general (&gr, &stack_size, ainfo, TRUE);
+
+                       n++;
+                       break;
+               case MONO_TYPE_R8:
+                       ainfo->size = 8;
+
+                       if (IS_HARD_FLOAT)
+                               add_float (&fpr, &stack_size, ainfo, TRUE, &float_spare);
+                       else
+                               add_general (&gr, &stack_size, ainfo, FALSE);
+
+                       n++;
+                       break;
                case MONO_TYPE_VAR:
                case MONO_TYPE_MVAR:
                        /* gsharedvt arguments are passed by ref */
@@ -1376,6 +1546,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                /* Prevent implicit arguments and sig_cookie from
                   being passed in registers */
                gr = ARMREG_R3 + 1;
+               fpr = ARM_VFP_F16;
                /* Emit the signature cookie just before the implicit arguments */
                add_general (&gr, &stack_size, &cinfo->sig_cookie, TRUE);
        }
@@ -1411,9 +1582,13 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMemPool *mp, MonoMethodSign
                case MONO_TYPE_R4:
                case MONO_TYPE_R8:
                        cinfo->ret.storage = RegTypeFP;
-                       cinfo->ret.reg = ARMREG_R0;
-                       /* FIXME: cinfo->ret.reg = ???;
-                       cinfo->ret.storage = RegTypeFP;*/
+
+                       if (IS_HARD_FLOAT) {
+                               cinfo->ret.reg = ARM_VFP_F0;
+                       } else {
+                               cinfo->ret.reg = ARMREG_R0;
+                       }
+
                        break;
                case MONO_TYPE_GENERICINST:
                        if (!mono_type_generic_inst_is_valuetype (simpletype)) {
@@ -2104,19 +2279,50 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                        }
                        break;
                case RegTypeFP: {
-                       /* FIXME: */
-                       NOT_IMPLEMENTED;
-#if 0
-                       arg->backend.reg3 = ainfo->reg;
-                       /* FP args are passed in int regs */
-                       call->used_iregs |= 1 << ainfo->reg;
+                       int fdreg = mono_alloc_freg (cfg);
+
                        if (ainfo->size == 8) {
-                               arg->opcode = OP_OUTARG_R8;
-                               call->used_iregs |= 1 << (ainfo->reg + 1);
+                               MONO_INST_NEW (cfg, ins, OP_FMOVE);
+                               ins->sreg1 = in->dreg;
+                               ins->dreg = fdreg;
+                               MONO_ADD_INS (cfg->cbb, ins);
+
+                               mono_call_inst_add_outarg_reg (cfg, call, ins->dreg, ainfo->reg, TRUE);
                        } else {
-                               arg->opcode = OP_OUTARG_R4;
+                               FloatArgData *fad;
+
+                               /*
+                                * Mono's register allocator doesn't speak single-precision registers that
+                                * overlap double-precision registers (i.e. armhf). So we have to work around
+                                * the register allocator and load the value from memory manually.
+                                *
+                                * So we create a variable for the float argument and an instruction to store
+                                * the argument into the variable. We then store the list of these arguments
+                                * in cfg->float_args. This list is then used by emit_float_args later to
+                                * pass the arguments in the various call opcodes.
+                                *
+                                * This is not very nice, and we should really try to fix the allocator.
+                                */
+
+                               MonoInst *float_arg = mono_compile_create_var (cfg, &mono_defaults.single_class->byval_arg, OP_LOCAL);
+
+                               /* Make sure the instruction isn't seen as pointless and removed.
+                                */
+                               float_arg->flags |= MONO_INST_VOLATILE;
+
+                               MONO_EMIT_NEW_UNALU (cfg, OP_MOVE, float_arg->dreg, in->dreg);
+
+                               /* We use the dreg to look up the instruction later. The hreg is used to
+                                * emit the instruction that loads the value into the FP reg.
+                                */
+                               fad = mono_mempool_alloc0 (cfg->mempool, sizeof (FloatArgData));
+                               fad->vreg = float_arg->dreg;
+                               fad->hreg = ainfo->reg;
+
+                               call->float_args = g_slist_append_mempool (cfg->mempool, call->float_args, fad);
                        }
-#endif
+
+                       call->used_iregs |= 1 << ainfo->reg;
                        cfg->flags |= MONO_CFG_HAS_FPOUT;
                        break;
                }
@@ -2238,6 +2444,7 @@ mono_arch_emit_setret (MonoCompile *cfg, MonoMethod *method, MonoInst *val)
                        }
                        break;
                case MONO_ARM_FPU_VFP:
+               case MONO_ARM_FPU_VFP_HARD:
                        if (ret->type == MONO_TYPE_R8 || ret->type == MONO_TYPE_R4) {
                                MonoInst *ins;
 
@@ -3209,10 +3416,10 @@ emit_float_to_int (MonoCompile *cfg, guchar *code, int dreg, int sreg, int size,
        /* sreg is a float, dreg is an integer reg  */
        if (IS_VFP) {
                if (is_signed)
-                       ARM_TOSIZD (code, ARM_VFP_F0, sreg);
+                       ARM_TOSIZD (code, vfp_scratch1, sreg);
                else
-                       ARM_TOUIZD (code, ARM_VFP_F0, sreg);
-               ARM_FMRS (code, dreg, ARM_VFP_F0);
+                       ARM_TOUIZD (code, vfp_scratch1, sreg);
+               ARM_FMRS (code, dreg, vfp_scratch1);
        }
        if (!is_signed) {
                if (size == 1)
@@ -4364,6 +4571,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_VOIDCALL:
                case OP_CALL:
                        call = (MonoCallInst*)ins;
+
+                       if (IS_HARD_FLOAT)
+                               code = emit_float_args (cfg, call, code, &max_len, &offset);
+
                        if (ins->flags & MONO_INST_HAS_METHOD)
                                mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD, call->method);
                        else
@@ -4379,6 +4590,9 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_VCALL2_REG:
                case OP_VOIDCALL_REG:
                case OP_CALL_REG:
+                       if (IS_HARD_FLOAT)
+                               code = emit_float_args (cfg, (MonoCallInst *)ins, code, &max_len, &offset);
+
                        code = emit_call_reg (code, ins->sreg1);
                        ins->flags |= MONO_INST_GC_CALLSITE;
                        ins->backend.pc_offset = code - cfg->native_code;
@@ -4394,6 +4608,10 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        g_assert (ins->sreg1 != ARMREG_LR);
                        call = (MonoCallInst*)ins;
+
+                       if (IS_HARD_FLOAT)
+                               code = emit_float_args (cfg, call, code, &max_len, &offset);
+
                        if (call->dynamic_imt_arg || call->method->klass->flags & TYPE_ATTRIBUTE_INTERFACE)
                                imt_arg = TRUE;
                        if (!arm_is_imm12 (ins->inst_offset))
@@ -4770,34 +4988,41 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                case OP_STORER4_MEMBASE_REG:
                        g_assert (arm_is_fpimm8 (ins->inst_offset));
-                       ARM_CVTD (code, ARM_VFP_F0, ins->sreg1);
-                       ARM_FSTS (code, ARM_VFP_F0, ins->inst_destbasereg, ins->inst_offset);
+                       ARM_CVTD (code, vfp_scratch1, ins->sreg1);
+                       ARM_FSTS (code, vfp_scratch1, ins->inst_destbasereg, ins->inst_offset);
                        break;
                case OP_LOADR4_MEMBASE:
                        g_assert (arm_is_fpimm8 (ins->inst_offset));
-                       ARM_FLDS (code, ARM_VFP_F0, ins->inst_basereg, ins->inst_offset);
-                       ARM_CVTS (code, ins->dreg, ARM_VFP_F0);
+                       ARM_FLDS (code, vfp_scratch1, ins->inst_basereg, ins->inst_offset);
+                       ARM_CVTS (code, ins->dreg, vfp_scratch1);
                        break;
                case OP_ICONV_TO_R_UN: {
                        g_assert_not_reached ();
                        break;
                }
                case OP_ICONV_TO_R4:
-                       ARM_FMSR (code, ARM_VFP_F0, ins->sreg1);
-                       ARM_FSITOS (code, ARM_VFP_F0, ARM_VFP_F0);
-                       ARM_CVTS (code, ins->dreg, ARM_VFP_F0);
+                       ARM_FMSR (code, vfp_scratch1, ins->sreg1);
+                       ARM_FSITOS (code, vfp_scratch1, vfp_scratch1);
+                       ARM_CVTS (code, ins->dreg, vfp_scratch1);
                        break;
                case OP_ICONV_TO_R8:
-                       ARM_FMSR (code, ARM_VFP_F0, ins->sreg1);
-                       ARM_FSITOD (code, ins->dreg, ARM_VFP_F0);
+                       ARM_FMSR (code, vfp_scratch1, ins->sreg1);
+                       ARM_FSITOD (code, ins->dreg, vfp_scratch1);
                        break;
 
                case OP_SETFRET:
                        if (mono_method_signature (cfg->method)->ret->type == MONO_TYPE_R4) {
                                ARM_CVTD (code, ARM_VFP_F0, ins->sreg1);
-                               ARM_FMRS (code, ARMREG_R0, ARM_VFP_F0);
+
+                               if (!IS_HARD_FLOAT) {
+                                       ARM_FMRS (code, ARMREG_R0, ARM_VFP_F0);
+                               }
                        } else {
-                               ARM_FMRRD (code, ARMREG_R0, ARMREG_R1, ins->sreg1);
+                               if (IS_HARD_FLOAT) {
+                                       ARM_CPYD (code, ARM_VFP_D0, ins->sreg1);
+                               } else {
+                                       ARM_FMRRD (code, ARMREG_R0, ARMREG_R1, ins->sreg1);
+                               }
                        }
                        break;
                case OP_FCONV_TO_I1:
@@ -4975,18 +5200,18 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                        jte [0] = GUINT_TO_POINTER (0xffffffff);
                                        jte [1] = GUINT_TO_POINTER (0x7fefffff);
                                        code = mono_arm_load_jumptable_entry_addr (code, jte, ARMREG_IP);
-                                       ARM_FLDD (code, ARM_VFP_D0, ARMREG_IP, 0);
+                                       ARM_FLDD (code, vfp_scratch1, ARMREG_IP, 0);
                                }
 #else
-                               ARM_ABSD (code, ARM_VFP_D1, ins->sreg1);
-                               ARM_FLDD (code, ARM_VFP_D0, ARMREG_PC, 0);
+                               ARM_ABSD (code, vfp_scratch2, ins->sreg1);
+                               ARM_FLDD (code, vfp_scratch1, ARMREG_PC, 0);
                                ARM_B (code, 1);
                                *(guint32*)code = 0xffffffff;
                                code += 4;
                                *(guint32*)code = 0x7fefffff;
                                code += 4;
 #endif
-                               ARM_CMPD (code, ARM_VFP_D1, ARM_VFP_D0);
+                               ARM_CMPD (code, vfp_scratch2, vfp_scratch1);
                                ARM_FMSTAT (code);
                                EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_GT, "ArithmeticException");
                                ARM_CMPD (code, ins->sreg1, ins->sreg1);
@@ -5457,7 +5682,13 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                                        break;
                                }
                        } else if (ainfo->storage == RegTypeFP) {
-                               g_assert_not_reached ();
+                               code = mono_arm_emit_load_imm (code, ARMREG_IP, inst->inst_offset);
+                               ARM_ADD_REG_REG (code, ARMREG_IP, ARMREG_IP, inst->inst_basereg);
+
+                               if (ainfo->size == 8)
+                                       ARM_FSTD (code, ainfo->reg, ARMREG_IP, 0);
+                               else
+                                       ARM_FSTS (code, ainfo->reg, ARMREG_IP, 0);
                        } else if (ainfo->storage == RegTypeStructByVal) {
                                int doffset = inst->inst_offset;
                                int soffset = 0;
@@ -5814,12 +6045,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
 
 #ifndef DISABLE_JIT
 
-MonoInst*
-mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       return mono_get_domain_intrinsic (cfg);
-}
-
 #endif
 
 guint32
@@ -5923,13 +6148,13 @@ mono_arch_find_static_call_vtable (mgreg_t *regs, guint8 *code)
        return (MonoVTable*) regs [MONO_ARCH_RGCTX_REG];
 }
 
-#define ENABLE_WRONG_METHOD_CHECK 0
+/* #define ENABLE_WRONG_METHOD_CHECK 1 */
 #define BASE_SIZE (6 * 4)
 #define BSEARCH_ENTRY_SIZE (4 * 4)
 #define CMP_SIZE (3 * 4)
 #define BRANCH_SIZE (1 * 4)
 #define CALL_SIZE (2 * 4)
-#define WMC_SIZE (5 * 4)
+#define WMC_SIZE (8 * 4)
 #define DISTANCE(A, B) (((gint32)(B)) - ((gint32)(A)))
 
 #ifdef USE_JUMP_TABLES
@@ -5965,6 +6190,15 @@ arm_emit_value_and_patch_ldr (arminstr_t *code, arminstr_t *target, guint32 valu
 }
 #endif
 
+#ifdef ENABLE_WRONG_METHOD_CHECK
+static void
+mini_dump_bad_imt (int input_imt, int compared_imt, int pc)
+{
+       g_print ("BAD IMT comparing %x with expected %x at ip %x", input_imt, compared_imt, pc);
+       g_assert (0);
+}
+#endif
+
 gpointer
 mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckItem **imt_entries, int count,
        gpointer fail_tramp)
@@ -5979,6 +6213,9 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
        arminstr_t *vtable_target = NULL;
        int extra_space = 0;
 #endif
+#ifdef ENABLE_WRONG_METHOD_CHECK
+       char * cond;
+#endif
 
        size = BASE_SIZE;
 #ifdef USE_JUMP_TABLES
@@ -6007,7 +6244,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                        item->chunk_size += CMP_SIZE;
                                item->chunk_size += BRANCH_SIZE;
                        } else {
-#if ENABLE_WRONG_METHOD_CHECK
+#ifdef ENABLE_WRONG_METHOD_CHECK
                                item->chunk_size += WMC_SIZE;
 #endif
                        }
@@ -6033,11 +6270,11 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                code = mono_domain_code_reserve (domain, size);
        start = code;
 
-#if DEBUG_IMT
-       printf ("building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable);
+#ifdef DEBUG_IMT
+       g_print ("Building IMT thunk for class %s %s entries %d code size %d code at %p end %p vtable %p fail_tramp %p\n", vtable->klass->name_space, vtable->klass->name, count, size, start, ((guint8*)start) + size, vtable, fail_tramp);
        for (i = 0; i < count; ++i) {
                MonoIMTCheckItem *item = imt_entries [i];
-               printf ("method %d (%p) %s vtable slot %p is_equals %d chunk size %d\n", i, item->key, item->key->name, &vtable->vtable [item->value.vtable_slot], item->is_equals, item->chunk_size);
+               g_print ("method %d (%p) %s vtable slot %p is_equals %d chunk size %d\n", i, item->key, ((MonoMethod*)item->key)->name, &vtable->vtable [item->value.vtable_slot], item->is_equals, item->chunk_size);
        }
 #endif
 
@@ -6112,7 +6349,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 #endif
                        } else {
                                /*Enable the commented code to assert on wrong method*/
-#if ENABLE_WRONG_METHOD_CHECK
+#ifdef ENABLE_WRONG_METHOD_CHECK
 #ifdef USE_JUMP_TABLES
                                imt_method_jti = IMT_METHOD_JTI (i);
                                code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, imt_method_jti, ARMCOND_AL);
@@ -6121,9 +6358,18 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                                ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
 #endif
                                ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
-                               ARM_B_COND (code, ARMCOND_NE, 1);
-
+                               cond = code;
+                               ARM_B_COND (code, ARMCOND_EQ, 0);
+
+/* Define this if your system is so bad that gdb is failing. */
+#ifdef BROKEN_DEV_ENV
+                               ARM_MOV_REG_REG (code, ARMREG_R2, ARMREG_PC);
+                               ARM_BL (code, 0);
+                               arm_patch (code - 1, mini_dump_bad_imt);
+#else
                                ARM_DBRK (code);
+#endif
+                               arm_patch (cond, code);
 #endif
                        }
 
@@ -6243,15 +6489,15 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
 #ifdef USE_JUMP_TABLES
                        code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, IMT_METHOD_JTI (i), ARMCOND_AL);
                        ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
-                       code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, JUMP_CODE_JTI (i), ARMCOND_GE);
-                       ARM_BX_COND (code, ARMCOND_GE, ARMREG_R1);
+                       code = load_element_with_regbase_cond (code, ARMREG_R1, ARMREG_R2, JUMP_CODE_JTI (i), ARMCOND_HS);
+                       ARM_BX_COND (code, ARMCOND_HS, ARMREG_R1);
                        item->jmp_code = GUINT_TO_POINTER (JUMP_CODE_JTI (i));
 #else
                        ARM_LDR_IMM (code, ARMREG_R1, ARMREG_PC, 0);
                        ARM_CMP_REG_REG (code, ARMREG_R0, ARMREG_R1);
 
                        item->jmp_code = (guint8*)code;
-                       ARM_B_COND (code, ARMCOND_GE, 0);
+                       ARM_B_COND (code, ARMCOND_HS, 0);
                        ++extra_space;
 #endif
                }
@@ -6281,7 +6527,7 @@ mono_arch_build_imt_thunk (MonoVTable *vtable, MonoDomain *domain, MonoIMTCheckI
                }
        }
 
-#if DEBUG_IMT
+#ifdef DEBUG_IMT
        {
                char *buff = g_strdup_printf ("thunk_for_class_%s_%s_entries_%d", vtable->klass->name_space, vtable->klass->name, count);
                mono_disassemble_code (NULL, (guint8*)start, size, buff);
@@ -6552,6 +6798,15 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return info;
 }
 
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.sp = (gssize)ext;
+}
+
 /*
  * mono_arch_set_target:
  *
index 93a256b56329708045ada86d42417a32cabb3663..c1f21f8995ad9b794a8bb50646965dfb5c53709e 100644 (file)
 #define MONO_ARCH_SOFT_FLOAT_FALLBACK 1
 #endif
 
-#ifdef ARM_FPU_VFP_HARD
-#error "hardfp-abi not yet supported."
-#endif
-
 #if defined(__ARM_EABI__)
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
 #define ARM_ARCHITECTURE "armel"
 #endif
 
 #define MONO_MAX_IREGS 16
-#define MONO_MAX_FREGS 16
+#define MONO_MAX_FREGS 32
 
 #define MONO_SAVED_GREGS 10 /* r4-r11, ip, lr */
-#define MONO_SAVED_FREGS 8
 
 /* r4-r11, ip, lr: registers saved in the LMF  */
 #define MONO_ARM_REGSAVE_MASK 0x5ff0
 #define MONO_ARCH_CALLEE_REGS ((1<<ARMREG_R0) | (1<<ARMREG_R1) | (1<<ARMREG_R2) | (1<<ARMREG_R3) | (1<<ARMREG_IP))
 #define MONO_ARCH_CALLEE_SAVED_REGS ((1<<ARMREG_V1) | (1<<ARMREG_V2) | (1<<ARMREG_V3) | (1<<ARMREG_V4) | (1<<ARMREG_V5) | (1<<ARMREG_V6) | (1<<ARMREG_V7))
 
-/* Every double precision vfp register, d0/d1 is reserved for a scratch reg */
-#define MONO_ARCH_CALLEE_FREGS 0x55555550
-#define MONO_ARCH_CALLEE_SAVED_FREGS 0
+/*
+ * TODO: Make use of VFP v3 registers d16-d31.
+ */
+
+/*
+ * TODO: We can't use registers d8-d15 in hard float mode because the
+ * register allocator doesn't allocate floating point registers globally.
+ */
+
+#if defined(ARM_FPU_VFP_HARD)
+#define MONO_SAVED_FREGS 16
+/*
+ * d8-d15 must be preserved across function calls. We use d14-d15 as
+ * scratch registers in the JIT. The rest have no meaning tied to them.
+ */
+#define MONO_ARCH_CALLEE_FREGS 0x00005555
+#define MONO_ARCH_CALLEE_SAVED_FREGS 0x55550000
+#else
+#define MONO_SAVED_FREGS 0
+/*
+ * No registers need to be preserved across function calls. We use d14-d15
+ * as scratch registers in the JIT. The rest have no meaning tied to them.
+ */
+#define MONO_ARCH_CALLEE_FREGS 0x05555555
+#define MONO_ARCH_CALLEE_SAVED_FREGS 0x00000000
+#endif
 
 #define MONO_ARCH_USE_FPSTACK FALSE
 #define MONO_ARCH_FPSTACK_SIZE 0
@@ -164,6 +182,10 @@ struct MonoLMF {
        mgreg_t    sp;
        mgreg_t    ip;
        mgreg_t    fp;
+       /* Currently only used in trampolines on armhf to hold d0-d15. We don't really
+        * need to put d0-d7 in the LMF, but it simplifies the trampoline code.
+        */
+       double     fregs [16];
        /* all but sp and pc: matches the PUSH instruction layout in the trampolines
         * 0-4 should be considered undefined (execpt in the magic tramp)
         * sp is saved at IP.
@@ -291,4 +313,7 @@ guint8*
 mono_arm_load_jumptable_entry (guint8 *code, gpointer *jte, ARMReg reg) MONO_INTERNAL;
 #endif
 
+gboolean
+mono_arm_is_hard_float (void) MONO_INTERNAL;
+
 #endif /* __MONO_MINI_ARM_H__ */
index e82c07974ef469948bd4ee8cf9df501da79a5db1..8214be4db75717fc6a8ddd34a2fed3cdd4d6debd 100644 (file)
@@ -453,9 +453,22 @@ mono_print_ins_index (int i, MonoInst *ins)
        else
                printf (" %s", mono_inst_name (ins->opcode));
        if (spec == MONO_ARCH_CPU_SPEC) {
+               gboolean dest_base = FALSE;
+               switch (ins->opcode) {
+               case OP_STOREV_MEMBASE:
+                       dest_base = TRUE;
+                       break;
+               default:
+                       break;
+               }
+
                /* This is a lowered opcode */
-               if (ins->dreg != -1)
-                       printf (" R%d <-", ins->dreg);
+               if (ins->dreg != -1) {
+                       if (dest_base)
+                               printf (" [R%d + 0x%lx] <-", ins->dreg, (long)ins->inst_offset);
+                       else
+                               printf (" R%d <-", ins->dreg);
+               }
                if (ins->sreg1 != -1)
                        printf (" R%d", ins->sreg1);
                if (ins->sreg2 != -1)
@@ -584,11 +597,8 @@ mono_print_ins_index (int i, MonoInst *ins)
        case OP_CALL_MEMBASE:
        case OP_CALL_REG:
        case OP_FCALL:
-       case OP_FCALLVIRT:
        case OP_LCALL:
-       case OP_LCALLVIRT:
        case OP_VCALL:
-       case OP_VCALLVIRT:
        case OP_VCALL_REG:
        case OP_VCALL_MEMBASE:
        case OP_VCALL2:
@@ -596,7 +606,6 @@ mono_print_ins_index (int i, MonoInst *ins)
        case OP_VCALL2_MEMBASE:
        case OP_VOIDCALL:
        case OP_VOIDCALL_MEMBASE:
-       case OP_VOIDCALLVIRT:
        case OP_TAILCALL: {
                MonoCallInst *call = (MonoCallInst*)ins;
                GSList *list;
@@ -2341,6 +2350,8 @@ mono_opcode_to_cond (int opcode)
        case OP_CMOV_IEQ:
        case OP_CMOV_LEQ:
                return CMP_EQ;
+       case OP_FCNEQ:
+       case OP_ICNEQ:
        case OP_IBNE_UN:
        case OP_LBNE_UN:
        case OP_FBNE_UN:
@@ -2349,12 +2360,16 @@ mono_opcode_to_cond (int opcode)
        case OP_CMOV_INE_UN:
        case OP_CMOV_LNE_UN:
                return CMP_NE;
+       case OP_FCLE:
+       case OP_ICLE:
        case OP_IBLE:
        case OP_LBLE:
        case OP_FBLE:
        case OP_CMOV_ILE:
        case OP_CMOV_LLE:
                return CMP_LE;
+       case OP_FCGE:
+       case OP_ICGE:
        case OP_IBGE:
        case OP_LBGE:
        case OP_FBGE:
@@ -2386,6 +2401,7 @@ mono_opcode_to_cond (int opcode)
        case OP_CMOV_LGT:
                return CMP_GT;
 
+       case OP_ICLE_UN:
        case OP_IBLE_UN:
        case OP_LBLE_UN:
        case OP_FBLE_UN:
@@ -2394,6 +2410,8 @@ mono_opcode_to_cond (int opcode)
        case OP_CMOV_ILE_UN:
        case OP_CMOV_LLE_UN:
                return CMP_LE_UN;
+
+       case OP_ICGE_UN:
        case OP_IBGE_UN:
        case OP_LBGE_UN:
        case OP_FBGE_UN:
index a689cba79a7a02d94e6de6ab08ef63958d0f424d..fcdb5405990a20023dd6415ef61cfafbe0efc9fe 100644 (file)
@@ -50,7 +50,6 @@
 #include <mono/utils/mono-logger-internal.h>
 
 #include "mini.h"
-#include "debug-mini.h"
 #include "trace.h"
 #include "debugger-agent.h"
 
@@ -878,7 +877,7 @@ ves_icall_get_frame_info (gint32 skip, MonoBoolean need_file_info,
        MonoJitInfo *ji = NULL;
        MonoContext ctx, new_ctx;
        MonoDebugSourceLocation *location;
-       MonoMethod *jmethod, *actual_method;
+       MonoMethod *jmethod = NULL, *actual_method;
        StackFrameInfo frame;
        gboolean res;
 
@@ -1434,8 +1433,6 @@ mono_handle_exception_internal_first_pass (MonoContext *ctx, gpointer obj, gint3
 #ifndef DISABLE_PERFCOUNTERS
                                        mono_perfcounters->exceptions_filters++;
 #endif
-                                       mono_debugger_call_exception_handler (ei->data.filter, MONO_CONTEXT_GET_SP (ctx), ex_obj);
-
                                        /*
                                        Here's the thing, if this is a filter clause done by a wrapper like runtime invoke, we don't want to
                                        trim the stackframe since if it returns FALSE we lose information.
@@ -1512,7 +1509,7 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
        MonoContext initial_ctx;
        MonoMethod *method;
        int frame_count = 0;
-       gint32 filter_idx, first_filter_idx;
+       gint32 filter_idx, first_filter_idx = 0;
        int i;
        MonoObject *ex_obj;
        MonoObject *non_exception = NULL;
@@ -1796,7 +1793,6 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
                                        jit_tls->orig_ex_ctx_set = TRUE;
                                        mono_profiler_exception_clause_handler (method, ei->flags, i);
                                        jit_tls->orig_ex_ctx_set = FALSE;
-                                       mono_debugger_call_exception_handler (ei->handler_start, MONO_CONTEXT_GET_SP (ctx), ex_obj);
                                        MONO_CONTEXT_SET_IP (ctx, ei->handler_start);
                                        *(mono_get_lmf_addr ()) = lmf;
 #ifndef DISABLE_PERFCOUNTERS
@@ -1814,7 +1810,6 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
                                        jit_tls->orig_ex_ctx_set = TRUE;
                                        mono_profiler_exception_clause_handler (method, ei->flags, i);
                                        jit_tls->orig_ex_ctx_set = FALSE;
-                                       mono_debugger_call_exception_handler (ei->handler_start, MONO_CONTEXT_GET_SP (ctx), ex_obj);
                                        call_filter (ctx, ei->handler_start);
                                }
                                if (is_address_protected (ji, ei, MONO_CONTEXT_GET_IP (ctx)) &&
@@ -1824,7 +1819,6 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
                                        jit_tls->orig_ex_ctx_set = TRUE;
                                        mono_profiler_exception_clause_handler (method, ei->flags, i);
                                        jit_tls->orig_ex_ctx_set = FALSE;
-                                       mono_debugger_call_exception_handler (ei->handler_start, MONO_CONTEXT_GET_SP (ctx), ex_obj);
 #ifndef DISABLE_PERFCOUNTERS
                                        mono_perfcounters->exceptions_finallys++;
 #endif
@@ -1865,72 +1859,6 @@ mono_handle_exception_internal (MonoContext *ctx, gpointer obj, gboolean resume,
        g_assert_not_reached ();
 }
 
-/*
- * mono_debugger_handle_exception:
- *
- *  Notify the debugger about exceptions.  Returns TRUE if the debugger wants us to stop
- *  at the exception and FALSE to resume with the normal exception handling.
- *
- *  The arch code is responsible to setup @ctx in a way that MONO_CONTEXT_GET_IP () and
- *  MONO_CONTEXT_GET_SP () point to the throw instruction; ie. before executing the
- *  `callq throw' instruction.
- */
-gboolean
-mono_debugger_handle_exception (MonoContext *ctx, MonoObject *obj)
-{
-       MonoDebuggerExceptionAction action;
-
-       if (!mono_debug_using_mono_debugger ())
-               return FALSE;
-
-       if (!obj) {
-               MonoException *ex = mono_get_exception_null_reference ();
-               MONO_OBJECT_SETREF (ex, message, mono_string_new (mono_domain_get (), "Object reference not set to an instance of an object"));
-               obj = (MonoObject *)ex;
-       }
-
-       action = _mono_debugger_throw_exception (MONO_CONTEXT_GET_IP (ctx), MONO_CONTEXT_GET_SP (ctx), obj);
-
-       if (action == MONO_DEBUGGER_EXCEPTION_ACTION_STOP) {
-               /*
-                * The debugger wants us to stop on the `throw' instruction.
-                * By the time we get here, it already inserted a breakpoint there.
-                */
-               return TRUE;
-       } else if (action == MONO_DEBUGGER_EXCEPTION_ACTION_STOP_UNHANDLED) {
-               MonoContext ctx_cp = *ctx;
-               MonoJitInfo *ji = NULL;
-               gboolean ret;
-
-               /*
-                * The debugger wants us to stop only if this exception is user-unhandled.
-                */
-
-               ret = mono_handle_exception_internal_first_pass (&ctx_cp, obj, NULL, &ji, NULL, NULL);
-               if (ret && (ji != NULL) && (jinfo_get_method (ji)->wrapper_type == MONO_WRAPPER_RUNTIME_INVOKE)) {
-                       /*
-                        * The exception is handled in a runtime-invoke wrapper, that means that it's unhandled
-                        * inside the method being invoked, so we handle it like a user-unhandled exception.
-                        */
-                       ret = FALSE;
-               }
-
-               if (!ret) {
-                       /*
-                        * The exception is user-unhandled - tell the debugger to stop.
-                        */
-                       return _mono_debugger_unhandled_exception (MONO_CONTEXT_GET_IP (ctx), MONO_CONTEXT_GET_SP (ctx), obj);
-               }
-
-               /*
-                * The exception is catched somewhere - resume with the normal exception handling and don't
-                * stop in the debugger.
-                */
-       }
-
-       return FALSE;
-}
-
 /**
  * mono_debugger_run_finally:
  * @start_ctx: saved processor state
@@ -2180,6 +2108,7 @@ typedef struct {
        int count;
 } PrintOverflowUserData;
 
+#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
 static gboolean
 print_overflow_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer data)
 {
@@ -2218,12 +2147,15 @@ print_overflow_stack_frame (StackFrameInfo *frame, MonoContext *ctx, gpointer da
 
        return FALSE;
 }
+#endif
 
 void
 mono_handle_hard_stack_ovf (MonoJitTlsData *jit_tls, MonoJitInfo *ji, void *ctx, guint8* fault_addr)
 {
+#ifdef MONO_ARCH_HAVE_SIGCTX_TO_MONOCTX
        PrintOverflowUserData ud;
        MonoContext mctx;
+#endif
 
        /* we don't do much now, but we can warn the user with a useful message */
        mono_runtime_printf_err ("Stack overflow: IP: %p, fault addr: %p", mono_arch_ip_from_context (ctx), fault_addr);
@@ -2305,8 +2237,14 @@ mono_handle_native_sigsegv (int signal, void *ctx)
 
        if (mini_get_debug_options ()->suspend_on_sigsegv) {
                mono_runtime_printf_err ("Received SIGSEGV, suspending...");
+#ifdef HOST_WIN32
                while (1)
                        ;
+#else
+               while (1) {
+                       sleep (0);
+               }
+#endif
        }
 
        /* To prevent infinite loops when the stack walk causes a crash */
@@ -2337,7 +2275,7 @@ mono_handle_native_sigsegv (int signal, void *ctx)
        /* Try to get more meaningful information using gdb */
 
 #if !defined(HOST_WIN32) && defined(HAVE_SYS_SYSCALL_H) && defined(SYS_fork)
-       if (!mini_get_debug_options ()->no_gdb_backtrace && !mono_debug_using_mono_debugger ()) {
+       if (!mini_get_debug_options ()->no_gdb_backtrace) {
                /* From g_spawn_command_line_sync () in eglib */
                pid_t pid;
                int status;
index 113d4a1fcdea9cd25f29667375cddf72e1ea3922..17cc1f9f2f7f50c8ce62031fde85e2ef3bc19bfb 100644 (file)
@@ -4748,12 +4748,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
        return 0;
 }
 
-MonoInst*
-mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       return mono_get_domain_intrinsic (cfg);
-}
-
 mgreg_t
 mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
 {
index aa89217904bac00baf1c6b979ddc326c7ab982d6..0d2ada820747391bfb75bcc2b827c63d6f7a3a74 100644 (file)
@@ -123,14 +123,15 @@ public:
        virtual void deallocateExceptionTable(void*) {
        }
 
-       virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment,
-                                                                                unsigned SectionID) {
+       virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
+                                                                                StringRef SectionName) {
                // FIXME:
                assert(0);
                return NULL;
        }
 
-       virtual uint8_t* allocateDataSection(uintptr_t, unsigned int, unsigned int, bool) {
+       virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID,
+                                                                                StringRef SectionName, bool IsReadOnly) {
                // FIXME:
                assert(0);
                return NULL;
@@ -142,6 +143,12 @@ public:
                return false;
        }
 
+       virtual bool finalizeMemory(std::string *ErrMsg = 0) {
+               // FIXME:
+               assert(0);
+               return false;
+       }
+
        virtual void* getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure) {
                void *res;
                char *err;
@@ -262,17 +269,8 @@ public:
                 * install a profiler hook and reset the code model here.
                 * This should be inside an ifdef, but we can't include our config.h either,
                 * since its definitions conflict with LLVM's config.h.
-                *
+                * The LLVM mono branch contains a workaround.
                 */
-               //#if defined(TARGET_X86) || defined(TARGET_AMD64)
-#ifndef LLVM_MONO_BRANCH
-               /* The LLVM mono branch contains a workaround, so this is not needed */
-               if (Details.MF->getTarget ().getCodeModel () == CodeModel::Large) {
-                       Details.MF->getTarget ().setCodeModel (CodeModel::Default);
-               }
-#endif
-               //#endif
-
                emitted_cb (wrap (&F), Code, (char*)Code + Size);
        }
 };
@@ -287,7 +285,10 @@ static FunctionPassManager *fpm;
 void
 mono_llvm_optimize_method (LLVMValueRef method)
 {
-       verifyFunction (*(unwrap<Function> (method)));
+       /*
+        * The verifier does some checks on the whole module, leading to quadratic behavior.
+        */
+       //verifyFunction (*(unwrap<Function> (method)));
        fpm->run (*unwrap<Function> (method));
 }
 
@@ -417,7 +418,7 @@ force_pass_linking (void)
       (void) llvm::createBasicAliasAnalysisPass();
       (void) llvm::createLibCallAliasAnalysisPass(0);
       (void) llvm::createScalarEvolutionAliasAnalysisPass();
-      (void) llvm::createBlockPlacementPass();
+      //(void) llvm::createBlockPlacementPass();
       (void) llvm::createBreakCriticalEdgesPass();
       (void) llvm::createCFGSimplificationPass();
          /*
@@ -487,7 +488,7 @@ force_pass_linking (void)
       (void) llvm::createReassociatePass();
       (void) llvm::createSCCPPass();
       (void) llvm::createScalarReplAggregatesPass();
-      (void) llvm::createSimplifyLibCallsPass();
+      //(void) llvm::createSimplifyLibCallsPass();
          /*
       (void) llvm::createSingleLoopExtractorPass();
       (void) llvm::createStripSymbolsPass();
@@ -547,10 +548,6 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
   mono_mm->alloc_cb = alloc_cb;
   mono_mm->dlsym_cb = dlsym_cb;
 
-  //JITExceptionHandling = true;
-  // PrettyStackTrace installs signal handlers which trip up libgc
-  DisablePrettyStackTrace = true;
-
   /*
    * The Default code model doesn't seem to work on amd64,
    * test_0_fields_with_big_offsets (among others) crashes, because LLVM tries to call
@@ -568,14 +565,6 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
 #endif
   g_assert (EE);
 
-#if 0
-  ExecutionEngine *EE = ExecutionEngine::createJIT (unwrap (MP), &Error, mono_mm, CodeGenOpt::Default, true, Reloc::Default, CodeModel::Large);
-  if (!EE) {
-         errs () << "Unable to create LLVM ExecutionEngine: " << Error << "\n";
-         g_assert_not_reached ();
-  }
-#endif
-
   EE->InstallExceptionTableRegister (exception_cb);
   mono_event_listener = new MonoJITEventListener (emitted_cb);
   EE->RegisterJITEventListener (mono_event_listener);
@@ -587,12 +576,10 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
   PassRegistry &Registry = *PassRegistry::getPassRegistry();
   initializeCore(Registry);
   initializeScalarOpts(Registry);
-  //initializeIPO(Registry);
   initializeAnalysis(Registry);
   initializeIPA(Registry);
   initializeTransformUtils(Registry);
   initializeInstCombine(Registry);
-  //initializeInstrumentation(Registry);
   initializeTarget(Registry);
 
   llvm::cl::ParseEnvironmentOptions("mono", "MONO_LLVM", "");
@@ -610,7 +597,7 @@ mono_llvm_create_ee (LLVMModuleProviderRef MP, AllocCodeMemoryCb *alloc_cb, Func
          }
   } else {
          /* Use the same passes used by 'opt' by default, without the ipo passes */
-         const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -simplify-libcalls -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg -preverify -domtree -verify";
+         const char *opts = "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -simplifycfg -instcombine -simplifycfg -reassociate -domtree -loops -loop-simplify -domfrontier -loop-simplify -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -loop-simplify -lcssa -iv-users -indvars -loop-deletion -loop-simplify -lcssa -loop-unroll -instcombine -memdep -gvn -memdep -memcpyopt -sccp -instcombine -domtree -memdep -dse -adce -gvn -simplifycfg";
          char **args;
          int i;
 
index ce2e50d536914d605f5fe8b4a8951cb9b5bb0921..1cc990039f8b64812b2ecf94faf0ef70b8fabdfa 100644 (file)
@@ -35,6 +35,9 @@ typedef struct {
        LLVMValueRef got_var;
        const char *got_symbol;
        GHashTable *plt_entries;
+       char **bb_names;
+       GPtrArray *used;
+       LLVMTypeRef ptr_type;
 } MonoLLVMModule;
 
 /*
@@ -145,6 +148,12 @@ llvm_ins_info[] = {
 #define IS_TARGET_X86 0
 #endif
 
+#ifdef TARGET_AMD64
+#define IS_TARGET_AMD64 1
+#else
+#define IS_TARGET_AMD64 0
+#endif
+
 #define LLVM_FAILURE(ctx, reason) do { \
        TRACE_FAILURE (reason); \
        (ctx)->cfg->exception_message = g_strdup (reason); \
@@ -205,6 +214,18 @@ IntPtrType (void)
        return sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type ();
 }
 
+static LLVMTypeRef
+ObjRefType (void)
+{
+       return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
+}
+
+static LLVMTypeRef
+ThisType (void)
+{
+       return sizeof (gpointer) == 8 ? LLVMPointerType (LLVMInt64Type (), 0) : LLVMPointerType (LLVMInt32Type (), 0);
+}
+
 /*
  * get_vtype_size:
  *
@@ -326,14 +347,14 @@ type_to_llvm_type (EmitContext *ctx, MonoType *t)
        case MONO_TYPE_SZARRAY:
        case MONO_TYPE_STRING:
        case MONO_TYPE_PTR:
-               return IntPtrType ();
+               return ObjRefType ();
        case MONO_TYPE_VAR:
        case MONO_TYPE_MVAR:
                /* Because of generic sharing */
-               return IntPtrType ();
+               return ObjRefType ();
        case MONO_TYPE_GENERICINST:
                if (!mono_type_generic_inst_is_valuetype (t))
-                       return IntPtrType ();
+                       return ObjRefType ();
                /* Fall through */
        case MONO_TYPE_VALUETYPE:
        case MONO_TYPE_TYPEDBYREF: {
@@ -833,14 +854,28 @@ simd_op_to_llvm_type (int opcode)
 static LLVMBasicBlockRef
 get_bb (EmitContext *ctx, MonoBasicBlock *bb)
 {
-       char bb_name [128];
+       char bb_name_buf [128];
+       char *bb_name;
 
        if (ctx->bblocks [bb->block_num].bblock == NULL) {
                if (bb->flags & BB_EXCEPTION_HANDLER) {
                        int clause_index = (mono_get_block_region_notry (ctx->cfg, bb->region) >> 8) - 1;
-                       sprintf (bb_name, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
+                       sprintf (bb_name_buf, "EH_CLAUSE%d_BB%d", clause_index, bb->block_num);
+                       bb_name = bb_name_buf;
+               } else if (bb->block_num < 256) {
+                       if (!ctx->lmodule->bb_names)
+                               ctx->lmodule->bb_names = g_new0 (char*, 256);
+                       if (!ctx->lmodule->bb_names [bb->block_num]) {
+                               char *n;
+
+                               n = g_strdup_printf ("BB%d", bb->block_num);
+                               mono_memory_barrier ();
+                               ctx->lmodule->bb_names [bb->block_num] = n;
+                       }
+                       bb_name = ctx->lmodule->bb_names [bb->block_num];
                } else {
-                       sprintf (bb_name, "BB%d", bb->block_num);
+                       sprintf (bb_name_buf, "BB%d", bb->block_num);
+                       bb_name = bb_name_buf;
                }
 
                ctx->bblocks [bb->block_num].bblock = LLVMAppendBasicBlock (ctx->lmethod, bb_name);
@@ -1056,13 +1091,13 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
        if (cinfo && cinfo->rgctx_arg) {
                if (sinfo)
                        sinfo->rgctx_arg_pindex = pindex;
-               param_types [pindex] = IntPtrType ();
+               param_types [pindex] = ctx->lmodule->ptr_type;
                pindex ++;
        }
        if (cinfo && cinfo->imt_arg) {
                if (sinfo)
                        sinfo->imt_arg_pindex = pindex;
-               param_types [pindex] = IntPtrType ();
+               param_types [pindex] = ctx->lmodule->ptr_type;
                pindex ++;
        }
        if (vretaddr) {
@@ -1092,7 +1127,7 @@ sig_to_llvm_sig_full (EmitContext *ctx, MonoMethodSignature *sig, LLVMCallInfo *
        if (sig->hasthis) {
                if (sinfo)
                        sinfo->this_arg_pindex = pindex;
-               param_types [pindex ++] = IntPtrType ();
+               param_types [pindex ++] = ThisType ();
        }
        if (vretaddr && vret_arg_pindex == pindex)
                param_types [pindex ++] = IntPtrType ();
@@ -1274,12 +1309,26 @@ set_metadata_flag (LLVMValueRef v, const char *flag_name)
 {
        LLVMValueRef md_arg;
        int md_kind;
-       
+
        md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
        md_arg = LLVMMDString ("mono", 4);
        LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
 }
 
+static void
+set_invariant_load_flag (LLVMValueRef v)
+{
+       LLVMValueRef md_arg;
+       int md_kind;
+       const char *flag_name;
+
+       // FIXME: Cache this
+       flag_name = "invariant.load";
+       md_kind = LLVMGetMDKindID (flag_name, strlen (flag_name));
+       md_arg = LLVMMDString ("<index>", strlen ("<index>"));
+       LLVMSetMetadata (v, md_kind, LLVMMDNode (&md_arg, 1));
+}
+
 /*
  * emit_call:
  *
@@ -1475,7 +1524,8 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                throw_sig->ret = &mono_get_void_class ()->byval_arg;
                throw_sig->params [0] = &mono_get_int32_class ()->byval_arg;
                icall_name = "llvm_throw_corlib_exception_abs_trampoline";
-               throw_sig->params [1] = &mono_get_intptr_class ()->byval_arg;
+               /* This will become i8* */
+               throw_sig->params [1] = &mono_get_byte_class ()->this_arg;
                sig = sig_to_llvm_sig (ctx, throw_sig);
 
                if (ctx->cfg->compile_aot) {
@@ -1486,8 +1536,7 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                        /*
                         * Differences between the LLVM/non-LLVM throw corlib exception trampoline:
                         * - On x86, LLVM generated code doesn't push the arguments
-                        * - When using the LLVM mono branch, the trampoline takes the throw address as an
-                        *   arguments, not a pc offset.
+                        * - The trampoline takes the throw address as an arguments, not a pc offset.
                         */
                        LLVMAddGlobalMapping (ee, callee, resolve_patch (ctx->cfg, MONO_PATCH_INFO_INTERNAL_METHOD, icall_name));
                }
@@ -1496,7 +1545,7 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
                ctx->lmodule->throw_corlib_exception = callee;
        }
 
-       if (IS_TARGET_X86)
+       if (IS_TARGET_X86 || IS_TARGET_AMD64)
                args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token - MONO_TOKEN_TYPE_DEF, FALSE);
        else
                args [0] = LLVMConstInt (LLVMInt32Type (), exc_class->type_token, FALSE);
@@ -1505,7 +1554,7 @@ emit_cond_system_exception (EmitContext *ctx, MonoBasicBlock *bb, const char *ex
         * The LLVM mono branch contains changes so a block address can be passed as an
         * argument to a call.
         */
-       args [1] = LLVMBuildPtrToInt (builder, LLVMBlockAddress (ctx->lmethod, ex_bb), IntPtrType (), "");
+       args [1] = LLVMBlockAddress (ctx->lmethod, ex_bb);
        emit_call (ctx, bb, &builder, ctx->lmodule->throw_corlib_exception, args, 2);
 
        LLVMBuildUnreachable (builder);
@@ -1643,15 +1692,30 @@ build_alloca (EmitContext *ctx, MonoType *t)
  * Put the global into the 'llvm.used' array to prevent it from being optimized away.
  */
 static void
-mark_as_used (LLVMModuleRef module, LLVMValueRef global)
+mark_as_used (MonoLLVMModule *lmodule, LLVMValueRef global)
 {
+       if (!lmodule->used)
+               lmodule->used = g_ptr_array_sized_new (16);
+       g_ptr_array_add (lmodule->used, global);
+}
+
+static void
+emit_llvm_used (MonoLLVMModule *lmodule)
+{
+       LLVMModuleRef module = lmodule->module;
        LLVMTypeRef used_type;
-       LLVMValueRef used, used_elem;
+       LLVMValueRef used, *used_elem;
+       int i;
                
-       used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), 1);
+       if (!lmodule->used)
+               return;
+
+       used_type = LLVMArrayType (LLVMPointerType (LLVMInt8Type (), 0), lmodule->used->len);
        used = LLVMAddGlobal (module, used_type, "llvm.used");
-       used_elem = LLVMConstBitCast (global, LLVMPointerType (LLVMInt8Type (), 0));
-       LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), &used_elem, 1));
+       used_elem = g_new0 (LLVMValueRef, lmodule->used->len);
+       for (i = 0; i < lmodule->used->len; ++i)
+               used_elem [i] = LLVMConstBitCast (g_ptr_array_index (lmodule->used, i), LLVMPointerType (LLVMInt8Type (), 0));
+       LLVMSetInitializer (used, LLVMConstArray (LLVMPointerType (LLVMInt8Type (), 0), used_elem, lmodule->used->len));
        LLVMSetLinkage (used, LLVMAppendingLinkage);
        LLVMSetSection (used, "llvm.metadata");
 }
@@ -1745,7 +1809,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
                 * with the "mono.this" custom metadata to tell llvm that it needs to save its
                 * location into the LSDA.
                 */
-               this_alloc = mono_llvm_build_alloca (builder, IntPtrType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
+               this_alloc = mono_llvm_build_alloca (builder, ThisType (), LLVMConstInt (LLVMInt32Type (), 1, FALSE), 0, "");
                /* This volatile store will keep the alloca alive */
                mono_llvm_build_store (builder, ctx->values [cfg->args [0]->dreg], this_alloc, TRUE);
 
@@ -1761,7 +1825,7 @@ emit_entry_bb (EmitContext *ctx, LLVMBuilderRef builder)
                g_assert (ctx->addresses [cfg->rgctx_var->dreg]);
                rgctx_alloc = ctx->addresses [cfg->rgctx_var->dreg];
                /* This volatile store will keep the alloca alive */
-               store = mono_llvm_build_store (builder, ctx->rgctx_arg, rgctx_alloc, TRUE);
+               store = mono_llvm_build_store (builder, convert (ctx, ctx->rgctx_arg, IntPtrType ()), rgctx_alloc, TRUE);
 
                set_metadata_flag (rgctx_alloc, "mono.this");
        }
@@ -1956,12 +2020,12 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
        if (call->rgctx_arg_reg) {
                g_assert (values [call->rgctx_arg_reg]);
                g_assert (sinfo.rgctx_arg_pindex < nargs);
-               args [sinfo.rgctx_arg_pindex] = values [call->rgctx_arg_reg];
+               args [sinfo.rgctx_arg_pindex] = convert (ctx, values [call->rgctx_arg_reg], ctx->lmodule->ptr_type);
        }
        if (call->imt_arg_reg) {
                g_assert (values [call->imt_arg_reg]);
                g_assert (sinfo.imt_arg_pindex < nargs);
-               args [sinfo.imt_arg_pindex] = values [call->imt_arg_reg];
+               args [sinfo.imt_arg_pindex] = convert (ctx, values [call->imt_arg_reg], ctx->lmodule->ptr_type);
        }
 
        if (vretaddr) {
@@ -2009,7 +2073,7 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                } else {
                        g_assert (args [pindex]);
                        if (i == 0 && sig->hasthis)
-                               args [pindex] = convert (ctx, args [pindex], IntPtrType ());
+                               args [pindex] = convert (ctx, args [pindex], ThisType ());
                        else
                                args [pindex] = convert (ctx, args [pindex], type_to_llvm_arg_type (ctx, sig->params [i - sig->hasthis]));
                }
@@ -2025,7 +2089,6 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
 
        lcall = emit_call (ctx, bb, &builder, callee, args, LLVMCountParamTypes (llvm_sig));
 
-#ifdef LLVM_MONO_BRANCH
        /*
         * Modify cconv and parameter attributes to pass rgctx/imt correctly.
         */
@@ -2041,7 +2104,6 @@ process_call (EmitContext *ctx, MonoBasicBlock *bb, LLVMBuilderRef *builder_ref,
                LLVMAddInstrAttribute (lcall, 1 + sinfo.rgctx_arg_pindex, LLVMInRegAttribute);
        if (call->imt_arg_reg)
                LLVMAddInstrAttribute (lcall, 1 + sinfo.imt_arg_pindex, LLVMInRegAttribute);
-#endif
 
        /* Add byval attributes if needed */
        for (i = 0; i < sig->param_count; ++i) {
@@ -2417,9 +2479,12 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        /* We use COMPARE+SETcc/Bcc, llvm uses SETcc+br cond */
                        if (ins->opcode == OP_FCOMPARE)
                                cmp = LLVMBuildFCmp (builder, fpcond_to_llvm_cond [rel], convert (ctx, lhs, LLVMDoubleType ()), convert (ctx, rhs, LLVMDoubleType ()), "");
-                       else if (ins->opcode == OP_COMPARE_IMM)
-                               cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
-                       else if (ins->opcode == OP_LCOMPARE_IMM) {
+                       else if (ins->opcode == OP_COMPARE_IMM) {
+                               if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && ins->inst_imm == 0)
+                                       cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, LLVMConstNull (LLVMTypeOf (lhs)), "");
+                               else
+                                       cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), LLVMConstInt (IntPtrType (), ins->inst_imm, FALSE), "");
+                       } else if (ins->opcode == OP_LCOMPARE_IMM) {
                                if (SIZEOF_REGISTER == 4 && COMPILE_LLVM (cfg))  {
                                        /* The immediate is encoded in two fields */
                                        guint64 l = ((guint64)(guint32)ins->inst_offset << 32) | ((guint32)ins->inst_imm);
@@ -2428,9 +2493,12 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                        cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, LLVMInt64Type ()), LLVMConstInt (LLVMInt64Type (), ins->inst_imm, FALSE), "");
                                }
                        }
-                       else if (ins->opcode == OP_COMPARE)
-                               cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
-                       else
+                       else if (ins->opcode == OP_COMPARE) {
+                               if (LLVMGetTypeKind (LLVMTypeOf (lhs)) == LLVMPointerTypeKind && LLVMTypeOf (lhs) == LLVMTypeOf (rhs))
+                                       cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
+                               else
+                                       cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], convert (ctx, lhs, IntPtrType ()), convert (ctx, rhs, IntPtrType ()), "");
+                       } else
                                cmp = LLVMBuildICmp (builder, cond_to_llvm_cond [rel], lhs, rhs, "");
 
                        if (MONO_IS_COND_BRANCH_OP (ins->next)) {
@@ -2685,7 +2753,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                case OP_AND_IMM:
                case OP_MUL_IMM:
                case OP_SHL_IMM:
-               case OP_SHR_IMM: {
+               case OP_SHR_IMM:
+               case OP_SHR_UN_IMM: {
                        LLVMValueRef imm;
 
                        if (spec [MONO_INST_SRC1] == 'l') {
@@ -2761,6 +2830,7 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                                values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
                                break;
                        case OP_LSHR_UN_IMM:
+                       case OP_SHR_UN_IMM:
                                values [ins->dreg] = LLVMBuildLShr (builder, lhs, imm, dname);
                                break;
                        default:
@@ -2972,12 +3042,12 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        values [ins->dreg] = emit_load (ctx, bb, &builder, size, addr, dname, is_volatile);
 
-                       if (!is_volatile && (ins->flags & MONO_INST_CONSTANT_LOAD)) {
+                       if (!is_volatile && (ins->flags & MONO_INST_INVARIANT_LOAD)) {
                                /*
                                 * These will signal LLVM that these loads do not alias any stores, and
                                 * they can't fail, allowing them to be hoisted out of loops.
                                 */
-                               set_metadata_flag (values [ins->dreg], "mono.noalias");
+                               set_invariant_load_flag (values [ins->dreg]);
                                set_metadata_flag (values [ins->dreg], "mono.nofail.load");
                        }
 
@@ -3095,23 +3165,8 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        indexes [1] = LLVMConstInt (LLVMInt32Type (), (gssize)got_offset, FALSE);
                        got_entry_addr = LLVMBuildGEP (builder, ctx->lmodule->got_var, indexes, 2, "");
 
-                       // FIXME: This doesn't work right now, because it must be
-                       // paired with an invariant.end, and even then, its only in effect
-                       // inside its basic block
-#if 0
-                       {
-                               LLVMValueRef args [3];
-                               LLVMValueRef ptr, val;
-
-                               ptr = LLVMBuildBitCast (builder, got_entry_addr, LLVMPointerType (LLVMInt8Type (), 0), "ptr");
-
-                               args [0] = LLVMConstInt (LLVMInt64Type (), sizeof (gpointer), FALSE);
-                               args [1] = ptr;
-                               val = LLVMBuildCall (builder, LLVMGetNamedFunction (module, "llvm.invariant.start"), args, 2, "");
-                       }
-#endif
-
                        values [ins->dreg] = LLVMBuildLoad (builder, got_entry_addr, dname);
+                       set_invariant_load_flag (values [ins->dreg]);
                        break;
                }
                case OP_NOT_REACHED:
@@ -3210,44 +3265,38 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        values [ins->dreg] = LLVMBuildSelect (builder, v, lhs, rhs, dname);
                        break;
                }
-               case OP_ATOMIC_EXCHANGE_I4: {
-                       LLVMValueRef args [2];
-
-                       g_assert (ins->inst_offset == 0);
-
-                       args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
-                       args [1] = rhs;
-
-                       values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
-                       break;
-               }
+               case OP_ATOMIC_EXCHANGE_I4:
                case OP_ATOMIC_EXCHANGE_I8: {
                        LLVMValueRef args [2];
+                       LLVMTypeRef t;
+                               
+                       if (ins->opcode == OP_ATOMIC_EXCHANGE_I4)
+                               t = LLVMInt32Type ();
+                       else
+                               t = LLVMInt64Type ();
 
                        g_assert (ins->inst_offset == 0);
 
-                       args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
-                       args [1] = convert (ctx, rhs, LLVMInt64Type ());
-                       values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
-                       break;
-               }
-               case OP_ATOMIC_ADD_NEW_I4: {
-                       LLVMValueRef args [2];
-
-                       g_assert (ins->inst_offset == 0);
+                       args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
+                       args [1] = convert (ctx, rhs, t);
 
-                       args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt32Type (), 0));
-                       args [1] = rhs;
-                       values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
+                       values [ins->dreg] = mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_XCHG, args [0], args [1]);
                        break;
                }
+               case OP_ATOMIC_ADD_NEW_I4:
                case OP_ATOMIC_ADD_NEW_I8: {
                        LLVMValueRef args [2];
+                       LLVMTypeRef t;
+                               
+                       if (ins->opcode == OP_ATOMIC_ADD_NEW_I4)
+                               t = LLVMInt32Type ();
+                       else
+                               t = LLVMInt64Type ();
 
                        g_assert (ins->inst_offset == 0);
 
-                       args [0] = convert (ctx, lhs, LLVMPointerType (LLVMInt64Type (), 0));
-                       args [1] = convert (ctx, rhs, LLVMInt64Type ());
+                       args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
+                       args [1] = convert (ctx, rhs, t);
                        values [ins->dreg] = LLVMBuildAdd (builder, mono_llvm_build_atomic_rmw (builder, LLVM_ATOMICRMW_OP_ADD, args [0], args [1]), args [1], dname);
                        break;
                }
@@ -3256,11 +3305,10 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        LLVMValueRef args [3];
                        LLVMTypeRef t;
                                
-                       if (ins->opcode == OP_ATOMIC_CAS_I4) {
+                       if (ins->opcode == OP_ATOMIC_CAS_I4)
                                t = LLVMInt32Type ();
-                       } else {
+                       else
                                t = LLVMInt64Type ();
-                       }
 
                        args [0] = convert (ctx, lhs, LLVMPointerType (t, 0));
                        /* comparand */
@@ -3291,15 +3339,32 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
                        // 256 == GS segment register
                        LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
 #endif
-
                        // FIXME: XEN
                        values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), ins->inst_offset, TRUE), ptrtype, ""), "");
+#elif defined(TARGET_AMD64) && defined(TARGET_OSX)
+                       /* See mono_amd64_emit_tls_get () */
+                       int offset = mono_amd64_get_tls_gs_offset () + (ins->inst_offset * 8);
+
+                       // 256 == GS segment register
+                       LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
+                       values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, LLVMConstInt (IntPtrType (), offset, TRUE), ptrtype, ""), "");
 #else
                        LLVM_FAILURE (ctx, "opcode tls-get");
 #endif
 
                        break;
                }
+               case OP_TLS_GET_REG: {
+#if defined(TARGET_AMD64) && defined(TARGET_OSX)
+                       /* See emit_tls_get_reg () */
+                       // 256 == GS segment register
+                       LLVMTypeRef ptrtype = LLVMPointerType (IntPtrType (), 256);
+                       values [ins->dreg] = LLVMBuildLoad (builder, LLVMBuildIntToPtr (builder, convert (ctx, lhs, LLVMInt32Type ()), ptrtype, ""), "");
+#else
+                       LLVM_FAILURE (ctx, "opcode tls-get");
+#endif
+                       break;
+               }
 
                        /*
                         * Overflow opcodes.
@@ -3384,9 +3449,10 @@ process_bb (EmitContext *ctx, MonoBasicBlock *bb)
 
                        switch (ins->opcode) {
                        case OP_STOREV_MEMBASE:
-                               if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg) {
-                                       /* FIXME: Emit write barriers like in mini_emit_stobj () */
-                                       LLVM_FAILURE (ctx, "storev_membase + write barriers");
+                               if (cfg->gen_write_barriers && klass->has_references && ins->inst_destbasereg != cfg->frame_reg &&
+                                       LLVMGetInstructionOpcode (values [ins->inst_destbasereg]) != LLVMAlloca) {
+                                       /* Decomposed earlier */
+                                       g_assert_not_reached ();
                                        break;
                                }
                                if (!addresses [ins->sreg1]) {
@@ -4140,7 +4206,7 @@ mono_llvm_check_method_supported (MonoCompile *cfg)
 #if 1
        for (i = 0; i < header->num_clauses; ++i) {
                clause = &header->clauses [i];
-               
+
                if (i > 0 && clause->try_offset <= header->clauses [i - 1].handler_offset + header->clauses [i - 1].handler_len) {
                        /*
                         * FIXME: Some tests still fail with nested clauses.
@@ -4207,7 +4273,7 @@ mono_llvm_emit_method (MonoCompile *cfg)
        ctx->addresses = g_new0 (LLVMValueRef, cfg->next_vreg);
        ctx->vreg_types = g_new0 (LLVMTypeRef, cfg->next_vreg);
        ctx->vreg_cli_types = g_new0 (MonoType*, cfg->next_vreg);
-       phi_values = g_ptr_array_new ();
+       phi_values = g_ptr_array_sized_new (256);
        /* 
         * This signals whenever the vreg was defined by a phi node with no input vars
         * (i.e. all its input bblocks end with NOT_REACHABLE).
@@ -4216,7 +4282,7 @@ mono_llvm_emit_method (MonoCompile *cfg)
        /* Whenever the bblock is unreachable */
        ctx->unreachable = g_new0 (gboolean, cfg->max_block_num);
 
-       bblock_list = g_ptr_array_new ();
+       bblock_list = g_ptr_array_sized_new (256);
 
        ctx->values = values;
        ctx->region_to_handler = g_hash_table_new (NULL, NULL);
@@ -4274,9 +4340,7 @@ mono_llvm_emit_method (MonoCompile *cfg)
        method = LLVMAddFunction (module, method_name, method_type);
        ctx->lmethod = method;
 
-#ifdef LLVM_MONO_BRANCH
        LLVMSetFunctionCallConv (method, LLVMMono1CallConv);
-#endif
        LLVMSetLinkage (method, LLVMPrivateLinkage);
 
        LLVMAddFunctionAttr (method, LLVMUWTable);
@@ -4509,7 +4573,8 @@ mono_llvm_emit_method (MonoCompile *cfg)
        if (cfg->verbose_level > 1)
                mono_llvm_dump_value (method);
 
-       mark_as_used (module, method);
+       if (cfg->compile_aot)
+               mark_as_used (ctx->lmodule, method);
 
        if (cfg->compile_aot) {
                LLVMValueRef md_args [16];
@@ -4707,6 +4772,8 @@ exception_cb (void *data)
         * with it.
         */
        cfg->encoded_unwind_ops = mono_unwind_decode_fde ((guint8*)data, &cfg->encoded_unwind_ops_len, NULL, &ei, &ei_len, &type_info, &this_reg, &this_offset);
+       if (cfg->verbose_level > 1)
+               mono_print_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
 
        /* Count nested clauses */
        nested_len = 0;
@@ -4869,16 +4936,6 @@ add_intrinsics (LLVMModuleRef module)
                LLVMAddFunction (module, "llvm.umul.with.overflow.i64", LLVMFunctionType (LLVMStructType (ovf_res_i64, 2, FALSE), ovf_params_i64, 2, FALSE));
        }
 
-       {
-               LLVMTypeRef struct_ptr = LLVMPointerType (LLVMStructType (NULL, 0, FALSE), 0);
-               LLVMTypeRef invariant_start_params [] = { LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
-               LLVMTypeRef invariant_end_params [] = { struct_ptr, LLVMInt64Type (), LLVMPointerType (LLVMInt8Type (), 0) };
-
-               LLVMAddFunction (module, "llvm.invariant.start", LLVMFunctionType (struct_ptr, invariant_start_params, 2, FALSE));
-
-               LLVMAddFunction (module, "llvm.invariant.end", LLVMFunctionType (LLVMVoidType (), invariant_end_params, 3, FALSE));
-       }
-
        /* EH intrinsics */
        {
                LLVMTypeRef arg_types [2];
@@ -4894,6 +4951,7 @@ add_intrinsics (LLVMModuleRef module)
        }
 
        /* SSE intrinsics */
+#if defined(TARGET_X86) || defined(TARGET_AMD64)
        {
                LLVMTypeRef ret_type, arg_types [16];
 
@@ -5038,6 +5096,7 @@ add_intrinsics (LLVMModuleRef module)
        }
 
        AddFunc (module, "llvm.x86.sse2.pause", LLVMVoidType (), NULL, 0);
+#endif
 
        /* Load/Store intrinsics */
        {
@@ -5062,6 +5121,12 @@ add_intrinsics (LLVMModuleRef module)
        }
 }
 
+static void
+add_types (MonoLLVMModule *lmodule)
+{
+       lmodule->ptr_type = LLVMPointerType (sizeof (gpointer) == 8 ? LLVMInt64Type () : LLVMInt32Type (), 0);
+}
+
 void
 mono_llvm_init (void)
 {
@@ -5088,6 +5153,7 @@ init_jit_module (void)
        ee = mono_llvm_create_ee (LLVMCreateModuleProviderForExistingModule (jit_module.module), alloc_cb, emitted_cb, exception_cb, dlsym_cb);
 
        add_intrinsics (jit_module.module);
+       add_types (&jit_module);
 
        jit_module.llvm_types = g_hash_table_new (NULL, NULL);
 
@@ -5130,6 +5196,7 @@ mono_llvm_create_aot_module (const char *got_symbol)
        aot_module.got_symbol = got_symbol;
 
        add_intrinsics (aot_module.module);
+       add_types (&aot_module);
 
        /* Add GOT */
        /*
@@ -5139,7 +5206,7 @@ mono_llvm_create_aot_module (const char *got_symbol)
         * its size is known in mono_llvm_emit_aot_module ().
         */
        {
-               LLVMTypeRef got_type = LLVMArrayType (IntPtrType (), 0);
+               LLVMTypeRef got_type = LLVMArrayType (aot_module.ptr_type, 0);
 
                aot_module.got_var = LLVMAddGlobal (aot_module.module, got_type, "mono_dummy_got");
                LLVMSetInitializer (aot_module.got_var, LLVMConstNull (got_type));
@@ -5176,18 +5243,20 @@ mono_llvm_emit_aot_module (const char *filename, int got_size)
         * Create the real got variable and replace all uses of the dummy variable with
         * the real one.
         */
-       got_type = LLVMArrayType (IntPtrType (), got_size);
+       got_type = LLVMArrayType (aot_module.ptr_type, got_size);
        real_got = LLVMAddGlobal (aot_module.module, got_type, aot_module.got_symbol);
        LLVMSetInitializer (real_got, LLVMConstNull (got_type));
        LLVMSetLinkage (real_got, LLVMInternalLinkage);
 
        mono_llvm_replace_uses_of (aot_module.got_var, real_got);
 
-       mark_as_used (aot_module.module, real_got);
+       mark_as_used (&aot_module, real_got);
 
        /* Delete the dummy got so it doesn't become a global */
        LLVMDeleteGlobal (aot_module.got_var);
 
+       emit_llvm_used (&aot_module);
+
 #if 0
        {
                char *verifier_err;
index c219458d67983c591a23d7465fff81b7857ea083..235fd33a449b15e2c2d8b4e2f8c0f2f900d8871b 100644 (file)
@@ -64,7 +64,6 @@ int mono_exc_esp_offset = 0;
 static int tls_mode = TLS_MODE_DETECT;
 static int lmf_pthread_key = -1;
 static int monothread_key = -1;
-static int monodomain_key = -1;
 
 /* Whenever the host is little-endian */
 static int little_endian;
@@ -5756,11 +5755,6 @@ setup_tls_access (void)
                }
 #endif
        }
-       if (monodomain_key == -1) {
-               ptk = mono_domain_get_tls_key ();
-               if (ptk < 1024)
-                       monodomain_key = ptk;
-       }
        if (lmf_pthread_key == -1) {
                ptk = mono_jit_tls_id;
                if (ptk < 1024) {
@@ -5844,19 +5838,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
        return 0;
 }
 
-MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       MonoInst* ins;
-
-       setup_tls_access ();
-       if (monodomain_key == -1)
-               return NULL;
-       
-       MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-       ins->inst_offset = monodomain_key;
-       return ins;
-}
-
 mgreg_t
 mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
 {
@@ -6151,4 +6132,13 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return NULL;
 }
 
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.iregs [mips_sp] = (gssize)ext;
+}
+
 #endif /* MONO_ARCH_SOFT_DEBUG_SUPPORTED */
index f6c8c64d53b8ac0252766a028d334b08f86dbadc..e7a7844a0f84adc91075bb98bcf7c0706e0478d2 100644 (file)
@@ -40,23 +40,18 @@ MINI_OP(OP_SEQ_POINT, "seq_point", NONE, NONE, NONE)
 MINI_OP(OP_IMPLICIT_EXCEPTION, "implicit_exception", NONE, NONE, NONE)
 
 MINI_OP(OP_VOIDCALL,   "voidcall", NONE, NONE, NONE)
-MINI_OP(OP_VOIDCALLVIRT,       "voidcallvirt", NONE, NONE, NONE)
 MINI_OP(OP_VOIDCALL_REG,       "voidcall_reg", NONE, IREG, NONE)
 MINI_OP(OP_VOIDCALL_MEMBASE,   "voidcall_membase", NONE, IREG, NONE)
 MINI_OP(OP_CALL,        "call", IREG, NONE, NONE)
 MINI_OP(OP_CALL_REG,   "call_reg", IREG, IREG, NONE)
 MINI_OP(OP_CALL_MEMBASE,       "call_membase", IREG, IREG, NONE)
-MINI_OP(OP_CALLVIRT, "callvirt", IREG, NONE, NONE)
 MINI_OP(OP_FCALL,      "fcall", FREG, NONE, NONE)
-MINI_OP(OP_FCALLVIRT,  "fcallvirt", FREG, NONE, NONE)
 MINI_OP(OP_FCALL_REG,  "fcall_reg", FREG, IREG, NONE)
 MINI_OP(OP_FCALL_MEMBASE,      "fcall_membase", FREG, IREG, NONE)
 MINI_OP(OP_LCALL,      "lcall", LREG, NONE, NONE)
-MINI_OP(OP_LCALLVIRT,  "lcallvirt", LREG, NONE, NONE)
 MINI_OP(OP_LCALL_REG,  "lcall_reg", LREG, IREG, NONE)
 MINI_OP(OP_LCALL_MEMBASE,      "lcall_membase", LREG, IREG, NONE)
 MINI_OP(OP_VCALL,      "vcall", VREG, NONE, NONE)
-MINI_OP(OP_VCALLVIRT,  "vcallvirt", VREG, NONE, NONE)
 MINI_OP(OP_VCALL_REG,  "vcall_reg", VREG, IREG, NONE)
 MINI_OP(OP_VCALL_MEMBASE,      "vcall_membase", VREG, IREG, NONE)
 /* Represents the decomposed vcall which doesn't return a vtype no more */
@@ -426,6 +421,12 @@ MINI_OP(OP_ICGT_UN,"int_cgt_un", IREG, NONE, NONE)
 MINI_OP(OP_ICLT,   "int_clt", IREG, NONE, NONE)
 MINI_OP(OP_ICLT_UN,"int_clt_un", IREG, NONE, NONE)
 
+MINI_OP(OP_ICNEQ,  "int_cneq", IREG, NONE, NONE)
+MINI_OP(OP_ICGE,   "int_cge", IREG, NONE, NONE)
+MINI_OP(OP_ICLE,   "int_cle", IREG, NONE, NONE)
+MINI_OP(OP_ICGE_UN,"int_cge_un", IREG, NONE, NONE)
+MINI_OP(OP_ICLE_UN,"int_cle_un", IREG, NONE, NONE)
+
 MINI_OP(OP_IBEQ,    "int_beq", NONE, NONE, NONE)
 MINI_OP(OP_IBGE,    "int_bge", NONE, NONE, NONE)
 MINI_OP(OP_IBGT,    "int_bgt", NONE, NONE, NONE)
@@ -509,6 +510,10 @@ MINI_OP(OP_FCGT_UN,"float_cgt_un", IREG, FREG, FREG)
 MINI_OP(OP_FCLT,   "float_clt", IREG, FREG, FREG)
 MINI_OP(OP_FCLT_UN,"float_clt_un", IREG, FREG, FREG)
 
+MINI_OP(OP_FCNEQ,  "float_cneq", IREG, FREG, FREG)
+MINI_OP(OP_FCGE,   "float_cge", IREG, FREG, FREG)
+MINI_OP(OP_FCLE,   "float_cle", IREG, FREG, FREG)
+
 MINI_OP(OP_FCEQ_MEMBASE,   "float_ceq_membase", IREG, FREG, IREG)
 MINI_OP(OP_FCGT_MEMBASE,   "float_cgt_membase", IREG, FREG, IREG)
 MINI_OP(OP_FCGT_UN_MEMBASE,"float_cgt_un_membase", IREG, FREG, IREG)
@@ -608,7 +613,10 @@ MINI_OP(OP_CARD_TABLE_WBARRIER, "card_table_wbarrier", NONE, IREG, IREG)
 
 /* arch-dep tls access */
 MINI_OP(OP_TLS_GET,            "tls_get", IREG, NONE, NONE)
-MINI_OP(OP_TLS_GET_REG,            "tls_get_reg", IREG, IREG, NONE)
+MINI_OP(OP_TLS_GET_REG,        "tls_get_reg", IREG, IREG, NONE)
+/* inst_offset contains the TLS offset */
+MINI_OP(OP_TLS_SET,            "tls_set", NONE, IREG, NONE)
+MINI_OP(OP_TLS_SET_REG,        "tls_set_reg", NONE, IREG, IREG)
 
 MINI_OP(OP_LOAD_GOTADDR, "load_gotaddr", IREG, NONE, NONE)
 MINI_OP(OP_DUMMY_USE, "dummy_use", NONE, IREG, NONE)
index d8c3367214f7c232b6af94d10c0adcedb3ec8b71..34dd19f59abc0be2435c035cfac8f65a8c40693e 100644 (file)
@@ -68,7 +68,6 @@ static CRITICAL_SECTION mini_arch_mutex;
 int mono_exc_esp_offset = 0;
 static int tls_mode = TLS_MODE_DETECT;
 static int lmf_pthread_key = -1;
-static int monodomain_key = -1;
 
 /*
  * The code generated for sequence points reads from this location, which is
@@ -1255,7 +1254,7 @@ get_call_info (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig)
 }
 
 gboolean
-mono_ppc_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
+mono_arch_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
 {
        CallInfo *c1, *c2;
        gboolean res;
@@ -4575,6 +4574,7 @@ mono_arch_patch_code (MonoMethod *method, MonoDomain *domain, guint8 *code, Mono
                case MONO_PATCH_INFO_ABS:
                case MONO_PATCH_INFO_CLASS_INIT:
                case MONO_PATCH_INFO_RGCTX_FETCH:
+               case MONO_PATCH_INFO_JIT_ICALL_ADDR:
                        is_fd = TRUE;
                        break;
 #endif
@@ -5396,8 +5396,6 @@ try_offset_access (void *value, guint32 idx)
 static void
 setup_tls_access (void)
 {
-       guint32 ptk;
-
 #if defined(__linux__) && defined(_CS_GNU_LIBPTHREAD_VERSION)
        size_t conf_size = 0;
        char confbuf[128];
@@ -5447,6 +5445,7 @@ setup_tls_access (void)
                ppc_blr (code);
                if (*ins == cmplwi_1023) {
                        int found_lwz_284 = 0;
+                       guint32 ptk;
                        for (ptk = 0; ptk < 20; ++ptk) {
                                ++ins;
                                if (!*ins || *ins == blr_ins)
@@ -5504,17 +5503,6 @@ setup_tls_access (void)
                tls_mode = TLS_MODE_FAILED;
        if (tls_mode == TLS_MODE_FAILED)
                return;
-       if ((monodomain_key == -1) && (tls_mode == TLS_MODE_NPTL)) {
-               monodomain_key = mono_domain_get_tls_offset();
-       }
-       /* if not TLS_MODE_NPTL or local dynamic (as indicated by
-          mono_domain_get_tls_offset returning -1) then use keyed access. */
-       if (monodomain_key == -1) {
-               ptk = mono_domain_get_tls_key ();
-               if (ptk < 1024)
-                   monodomain_key = ptk;
-       }
-
        if ((lmf_pthread_key == -1) && (tls_mode == TLS_MODE_NPTL)) {
                lmf_pthread_key = mono_get_lmf_addr_tls_offset();
        }
@@ -5523,7 +5511,7 @@ setup_tls_access (void)
        /* if not TLS_MODE_NPTL or local dynamic (as indicated by
           mono_get_lmf_addr_tls_offset returning -1) then use keyed access. */
        if (lmf_pthread_key == -1) {
-               ptk = mono_jit_tls_id;
+               guint32 ptk = mono_jit_tls_id;
                if (ptk < 1024) {
                        /*g_print ("MonoLMF at: %d\n", ptk);*/
                        /*if (!try_offset_access (mono_get_lmf_addr (), ptk)) {
@@ -5739,19 +5727,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
        return 0;
 }
 
-MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       MonoInst* ins;
-
-       setup_tls_access ();
-       if (monodomain_key == -1)
-               return NULL;
-       
-       MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-       ins->inst_offset = monodomain_key;
-       return ins;
-}
-
 mgreg_t
 mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
 {
@@ -5956,4 +5931,13 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return NULL;
 }
 
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.ebp = (gssize)ext;
+}
+
 #endif
index e3d5b055b969242d724004ed7896e5b400e1dcb0..13b6adb5376fccf0bc1957d16eb5fdc27b8de21c 100644 (file)
@@ -195,6 +195,7 @@ typedef struct MonoCompileArch {
 #define MONO_ARCH_SOFT_DEBUG_SUPPORTED 1
 #endif
 #define MONO_ARCH_THIS_AS_FIRST_ARG 1
+#define MONO_ARCH_HAVE_OP_TAIL_CALL 1
 
 #define PPC_NUM_REG_ARGS (PPC_LAST_ARG_REG-PPC_FIRST_ARG_REG+1)
 #define PPC_NUM_REG_FPARGS (PPC_LAST_FPARG_REG-PPC_FIRST_FPARG_REG+1)
@@ -304,8 +305,6 @@ extern guint8* mono_ppc_create_pre_code_ftnptr (guint8 *code) MONO_INTERNAL;
 gboolean
 mono_ppc_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) MONO_INTERNAL;
 
-#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_ppc_tail_call_supported (caller_sig, callee_sig)
-
 void
 mono_ppc_patch (guchar *code, const guchar *target) MONO_INTERNAL;
 
index cc2a055e78d6ad6181fa3147fdc4cbe656f6aa4c..5374adc8b029f1c637417f777d1560339a3186e2 100644 (file)
@@ -1227,7 +1227,7 @@ handle_enum:
                        mono_method_signature (method)->ret->type);
        }
 
-       ip = ((gint64) __builtin_return_address (0));
+       ip = ((gint64) __builtin_extract_return_addr (__builtin_return_address (0)));
        printf (" ip: %p\n", (gpointer) ip);
 }
 
@@ -5714,31 +5714,6 @@ mono_arch_regalloc_cost (MonoCompile *cfg, MonoMethodVar *vmv)
 
 /*========================= End of Function ========================*/
 
-/*------------------------------------------------------------------*/
-/*                                                                  */
-/* Name                - mono_arch_get_domain_intrinsic                    */
-/*                                                                  */
-/* Function    -                                                   */
-/*                                                                 */
-/* Returns     -                                                   */
-/*                                                                  */
-/*------------------------------------------------------------------*/
-
-MonoInst * 
-mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       MonoInst *ins;
-
-       if (appdomain_tls_offset == -1)
-               return NULL;
-       
-       MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-       ins->inst_offset = appdomain_tls_offset;
-       return (ins);
-}
-
-/*========================= End of Function ========================*/
-
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_flush_register_windows                  */
@@ -6384,6 +6359,23 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return NULL;
 }
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_init_lmf_ext.                               */
+/*                                                                  */
+/* Function -                                                       */
+/*                                                                  */
+/*------------------------------------------------------------------*/
+
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.ebp = (gssize)ext;
+}
+
 /*========================= End of Function ========================*/
 
 #endif
index 9a0e4ec1508d9cccd85f6678f7387f2870833132..ec65fb5c6b9abf2b5f4d6d986f1f0995b5842a57 100644 (file)
@@ -4424,11 +4424,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
        return 0;
 }
 
-MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       return NULL;
-}
-
 mgreg_t
 mono_arch_context_get_int_reg (MonoContext *ctx, int reg)
 {
index bc1c4639d2b40a456768cb5847aecea9d99e0607..b95ccf557c24c6aa6198cfd45e8c87b4cb256228 100644 (file)
@@ -15,7 +15,6 @@
 #include <mono/utils/mono-membar.h>
 
 #include "mini.h"
-#include "debug-mini.h"
 
 /*
  * Address of the trampoline code.  This is used by the debugger to check
@@ -577,8 +576,6 @@ common_call_trampoline (mgreg_t *regs, guint8 *code, MonoMethod *m, guint8* tram
        addr = compiled_method = mono_compile_method (m);
        g_assert (addr);
 
-       mono_debugger_trampoline_compiled (code, m, addr);
-
        if (generic_virtual || variant_iface) {
                if (vt->klass->valuetype) /*FIXME is this required variant iface?*/
                        need_unbox_tramp = TRUE;
@@ -809,8 +806,6 @@ mono_generic_virtual_remoting_trampoline (mgreg_t *regs, guint8 *code, MonoMetho
        addr = mono_compile_method (m);
        g_assert (addr);
 
-       mono_debugger_trampoline_compiled (NULL, m, addr);
-
        return addr;
 }
 #endif
@@ -1068,7 +1063,6 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, gui
                        delegate->method_ptr = addr;
                        if (enable_caching && delegate->method_code)
                                *delegate->method_code = delegate->method_ptr;
-                       mono_debugger_trampoline_compiled (NULL, method, delegate->method_ptr);
                }
        } else {
                if (need_rgctx_tramp)
@@ -1094,7 +1088,6 @@ mono_delegate_trampoline (mgreg_t *regs, guint8 *code, gpointer *tramp_data, gui
        code = mono_compile_method (m);
        code = mini_add_method_trampoline (NULL, m, code, mono_method_needs_static_rgctx_invoke (m, FALSE), FALSE);
        delegate->invoke_impl = mono_get_addr_from_ftnptr (code);
-       mono_debugger_trampoline_compiled (NULL, m, delegate->invoke_impl);
 
        return code;
 }
index 1d5be3190da6ae669686d365b8226e45ef936234..a8641f7cddb379473011af739a52b7c4ef26d5ca 100644 (file)
@@ -158,4 +158,6 @@ mono_unwind_decode_llvm_mono_fde (guint8 *fde, int fde_len, guint8 *cie, guint8
 
 GSList* mono_unwind_get_cie_program (void) MONO_INTERNAL;
 
+void mono_print_unwind_info (guint8 *unwind_info, int unwind_info_len) MONO_INTERNAL;
+
 #endif
index 999fe2077443bf94325d9ae25d5f96388d5621ef..78748d4d8be66a2b64868972cbb3fd6ddd4cdb8f 100755 (executable)
 #include "mini-gc.h"
 
 /* On windows, these hold the key returned by TlsAlloc () */
-static gint lmf_tls_offset = -1;
 #ifdef TARGET_WIN32
 static gint jit_tls_offset = -1;
 #else
 static gint lmf_addr_tls_offset = -1;
 #endif
-static gint appdomain_tls_offset = -1;
 
 #ifdef MONO_XEN_OPT
 static gboolean optimize_for_xen = TRUE;
@@ -50,12 +48,6 @@ static gboolean optimize_for_xen = TRUE;
 #define optimize_for_xen 0
 #endif
 
-#ifdef TARGET_WIN32
-static gboolean is_win32 = TRUE;
-#else
-static gboolean is_win32 = FALSE;
-#endif
-
 /* This mutex protects architecture specific caches */
 #define mono_mini_arch_lock() EnterCriticalSection (&mini_arch_mutex)
 #define mono_mini_arch_unlock() LeaveCriticalSection (&mini_arch_mutex)
@@ -77,6 +69,8 @@ static CRITICAL_SECTION mini_arch_mutex;
 MonoBreakpointInfo
 mono_breakpoint_info [MONO_BREAKPOINT_ARRAY_SIZE];
 
+static guint8*
+emit_load_aotconst (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji, int dreg, int tramp_type, gconstpointer target);
 
 #ifdef __native_client_codegen__
 
@@ -331,16 +325,19 @@ add_valuetype (MonoGenericSharingContext *gsctx, MonoMethodSignature *sig, ArgIn
                ainfo->pair_storage [0] = ainfo->pair_storage [1] = ArgNone;
 
                /* Special case structs with only a float member */
-               if ((info->native_size == 8) && (info->num_fields == 1) && (info->fields [0].field->type->type == MONO_TYPE_R8)) {
-                       ainfo->storage = ArgValuetypeInReg;
-                       ainfo->pair_storage [0] = ArgOnDoubleFpStack;
-                       return;
+               if (info->num_fields == 1) {
+                       int ftype = mini_type_get_underlying_type (NULL, info->fields [0].field->type)->type;
+                       if ((info->native_size == 8) && (ftype == MONO_TYPE_R8)) {
+                               ainfo->storage = ArgValuetypeInReg;
+                               ainfo->pair_storage [0] = ArgOnDoubleFpStack;
+                               return;
+                       }
+                       if ((info->native_size == 4) && (ftype == MONO_TYPE_R4)) {
+                               ainfo->storage = ArgValuetypeInReg;
+                               ainfo->pair_storage [0] = ArgOnFloatFpStack;
+                               return;
+                       }
                }
-               if ((info->native_size == 4) && (info->num_fields == 1) && (info->fields [0].field->type->type == MONO_TYPE_R4)) {
-                       ainfo->storage = ArgValuetypeInReg;
-                       ainfo->pair_storage [0] = ArgOnFloatFpStack;
-                       return;
-               }               
                if ((info->native_size == 1) || (info->native_size == 2) || (info->native_size == 4) || (info->native_size == 8)) {
                        ainfo->storage = ArgValuetypeInReg;
                        ainfo->pair_storage [0] = ArgInIReg;
@@ -445,7 +442,7 @@ get_call_info_internal (MonoGenericSharingContext *gsctx, CallInfo *cinfo, MonoM
                case MONO_TYPE_TYPEDBYREF: {
                        guint32 tmp_gr = 0, tmp_fr = 0, tmp_stacksize = 0;
 
-                       add_valuetype (gsctx, sig, &cinfo->ret, sig->ret, TRUE, &tmp_gr, NULL, &tmp_fr, &tmp_stacksize);
+                       add_valuetype (gsctx, sig, &cinfo->ret, ret_type, TRUE, &tmp_gr, NULL, &tmp_fr, &tmp_stacksize);
                        if (cinfo->ret.storage == ArgOnStack) {
                                cinfo->vtype_retaddr = TRUE;
                                /* The caller passes the address where the value is stored */
@@ -462,7 +459,7 @@ get_call_info_internal (MonoGenericSharingContext *gsctx, CallInfo *cinfo, MonoM
                        cinfo->ret.storage = ArgNone;
                        break;
                default:
-                       g_error ("Can't handle as return value 0x%x", sig->ret->type);
+                       g_error ("Can't handle as return value 0x%x", ret_type->type);
                }
        }
 
@@ -704,15 +701,21 @@ mono_arch_get_argument_info (MonoGenericSharingContext *gsctx, MonoMethodSignatu
 }
 
 gboolean
-mono_x86_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
+mono_arch_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig)
 {
+       MonoType *callee_ret;
        CallInfo *c1, *c2;
        gboolean res;
 
        c1 = get_call_info (NULL, NULL, caller_sig);
        c2 = get_call_info (NULL, NULL, callee_sig);
+       /*
+        * Tail calls with more callee stack usage than the caller cannot be supported, since
+        * the extra stack space would be left on the stack after the tail call.
+        */
        res = c1->stack_usage >= c2->stack_usage;
-       if (callee_sig->ret && MONO_TYPE_ISSTRUCT (callee_sig->ret) && c2->ret.storage != ArgValuetypeInReg)
+       callee_ret = mini_type_get_underlying_type (NULL, callee_sig->ret);
+       if (callee_ret && MONO_TYPE_ISSTRUCT (callee_ret) && c2->ret.storage != ArgValuetypeInReg)
                /* An address on the callee's stack is passed as the first argument */
                res = FALSE;
 
@@ -1059,7 +1062,7 @@ mono_arch_allocate_vars (MonoCompile *cfg)
        /* Reserve space to save LMF and caller saved registers */
 
        if (cfg->method->save_lmf) {
-               offset += sizeof (MonoLMF);
+               /* The LMF var is allocated normally */
        } else {
                if (cfg->used_int_regs & (1 << X86_EBX)) {
                        offset += 4;
@@ -1187,19 +1190,31 @@ mono_arch_allocate_vars (MonoCompile *cfg)
 void
 mono_arch_create_vars (MonoCompile *cfg)
 {
+       MonoType *sig_ret;
        MonoMethodSignature *sig;
        CallInfo *cinfo;
 
        sig = mono_method_signature (cfg->method);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
        if (cinfo->ret.storage == ArgValuetypeInReg)
                cfg->ret_var_is_local = TRUE;
-       if ((cinfo->ret.storage != ArgValuetypeInReg) && (MONO_TYPE_ISSTRUCT (sig->ret) || mini_is_gsharedvt_variable_type (cfg, sig->ret))) {
+       if ((cinfo->ret.storage != ArgValuetypeInReg) && (MONO_TYPE_ISSTRUCT (sig_ret) || mini_is_gsharedvt_variable_type (cfg, sig_ret))) {
                cfg->vret_addr = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_ARG);
        }
 
+       if (cfg->method->save_lmf) {
+               cfg->create_lmf_var = TRUE;
+#ifndef HOST_WIN32
+               if (!optimize_for_xen) {
+                       cfg->lmf_ir = TRUE;
+                       cfg->lmf_ir_mono_lmf = TRUE;
+               }
+#endif
+       }
+
        cfg->arch_eh_jit_info = 1;
 }
 
@@ -1264,11 +1279,12 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
        CallInfo *cinfo;
        ArgInfo *ainfo;
        LLVMCallInfo *linfo;
-       MonoType *t;
+       MonoType *t, *sig_ret;
 
        n = sig->param_count + sig->hasthis;
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
+       sig_ret = sig->ret;
 
        linfo = mono_mempool_alloc0 (cfg->mempool, sizeof (LLVMCallInfo) + (sizeof (LLVMArgInfo) * n));
 
@@ -1294,13 +1310,13 @@ mono_arch_get_llvm_call_info (MonoCompile *cfg, MonoMethodSignature *sig)
                */
        }
 
-       if (mini_type_is_vtype (cfg, sig->ret) && cinfo->ret.storage == ArgInIReg) {
+       if (mini_type_is_vtype (cfg, sig_ret) && cinfo->ret.storage == ArgInIReg) {
                /* Vtype returned using a hidden argument */
                linfo->ret.storage = LLVMArgVtypeRetAddr;
                linfo->vret_arg_index = cinfo->vret_arg_index;
        }
 
-       if (mini_type_is_vtype (cfg, sig->ret) && cinfo->ret.storage != ArgInIReg) {
+       if (mini_type_is_vtype (cfg, sig_ret) && cinfo->ret.storage != ArgInIReg) {
                // FIXME:
                cfg->exception_message = g_strdup ("vtype ret in call");
                cfg->disable_llvm = TRUE;
@@ -1386,6 +1402,7 @@ emit_gc_param_slot_def (MonoCompile *cfg, int sp_offset, MonoType *t)
 void
 mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
 {
+       MonoType *sig_ret;
        MonoInst *arg, *in;
        MonoMethodSignature *sig;
        int i, j, n;
@@ -1394,6 +1411,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
 
        sig = call->signature;
        n = sig->param_count + sig->hasthis;
+       sig_ret = mini_type_get_underlying_type (NULL, sig->ret);
 
        cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
 
@@ -1413,7 +1431,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                }
        }
 
-       if (sig->ret && MONO_TYPE_ISSTRUCT (sig->ret)) {
+       if (sig_ret && MONO_TYPE_ISSTRUCT (sig_ret)) {
                if (cinfo->ret.storage == ArgValuetypeInReg) {
                        /*
                         * Tell the JIT to use a more efficient calling convention: call using
@@ -1472,6 +1490,8 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                        arg->opcode = OP_OUTARG_VT;
                        arg->sreg1 = in->dreg;
                        arg->klass = in->klass;
+                       arg->inst_p1 = mono_mempool_alloc (cfg->mempool, sizeof (ArgInfo));
+                       memcpy (arg->inst_p1, ainfo, sizeof (ArgInfo));
                        sp_offset += 4;
                        MONO_ADD_INS (cfg->cbb, arg);
                } else if ((i >= sig->hasthis) && (MONO_TYPE_ISSTRUCT(t))) {
@@ -1571,7 +1591,7 @@ mono_arch_emit_call (MonoCompile *cfg, MonoCallInst *call)
                }
        }
 
-       if (sig->ret && (MONO_TYPE_ISSTRUCT (sig->ret) || cinfo->vtype_retaddr)) {
+       if (sig_ret && (MONO_TYPE_ISSTRUCT (sig_ret) || cinfo->vtype_retaddr)) {
                MonoInst *vtarg;
 
                if (cinfo->ret.storage == ArgValuetypeInReg) {
@@ -2368,50 +2388,170 @@ mono_x86_emit_tls_get (guint8* code, int dreg, int tls_offset)
        return code;
 }
 
+static guint8*
+emit_tls_get_reg (guint8* code, int dreg, int offset_reg)
+{
+       /* offset_reg contains a value translated by mono_arch_translate_tls_offset () */
+#if defined(__APPLE__) || defined(__linux__)
+       if (dreg != offset_reg)
+               x86_mov_reg_reg (code, dreg, offset_reg, sizeof (mgreg_t));
+       x86_prefix (code, X86_GS_PREFIX);
+       x86_mov_reg_membase (code, dreg, dreg, 0, sizeof (mgreg_t));
+#else
+       g_assert_not_reached ();
+#endif
+       return code;
+}
+
+static guint8*
+emit_tls_set_reg (guint8* code, int sreg, int offset_reg)
+{
+       /* offset_reg contains a value translated by mono_arch_translate_tls_offset () */
+#ifdef HOST_WIN32
+       g_assert_not_reached ();
+#elif defined(__APPLE__) || defined(__linux__)
+       x86_prefix (code, X86_GS_PREFIX);
+       x86_mov_membase_reg (code, offset_reg, 0, sreg, sizeof (mgreg_t));
+#else
+       g_assert_not_reached ();
+#endif
+       return code;
+}
+ /*
+ * mono_arch_translate_tls_offset:
+ *
+ *   Translate the TLS offset OFFSET computed by MONO_THREAD_VAR_OFFSET () into a format usable by OP_TLS_GET_REG/OP_TLS_SET_REG.
+ */
+int
+mono_arch_translate_tls_offset (int offset)
+{
+#ifdef __APPLE__
+       return tls_gs_offset + (offset * 4);
+#else
+       return offset;
+#endif
+}
+
 /*
- * emit_load_volatile_arguments:
+ * emit_setup_lmf:
  *
- *  Load volatile arguments from the stack to the original input registers.
- * Required before a tail call.
+ *   Emit code to initialize an LMF structure at LMF_OFFSET.
  */
 static guint8*
-emit_load_volatile_arguments (MonoCompile *cfg, guint8 *code)
+emit_setup_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset, int cfa_offset)
 {
-       MonoMethod *method = cfg->method;
-       MonoMethodSignature *sig;
-       MonoInst *inst;
-       CallInfo *cinfo;
-       guint32 i;
+       /* save all caller saved regs */
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebx), X86_EBX, sizeof (mgreg_t));
+       mono_emit_unwind_op_offset (cfg, code, X86_EBX, - cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebx));
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, edi), X86_EDI, sizeof (mgreg_t));
+       mono_emit_unwind_op_offset (cfg, code, X86_EDI, - cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, edi));
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, esi), X86_ESI, sizeof (mgreg_t));
+       mono_emit_unwind_op_offset (cfg, code, X86_ESI, - cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, esi));
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebp), X86_EBP, sizeof (mgreg_t));
+
+       /* save the current IP */
+       if (cfg->compile_aot) {
+               /* This pushes the current ip */
+               x86_call_imm (code, 0);
+               x86_pop_reg (code, X86_EAX);
+       } else {
+               mono_add_patch_info (cfg, code + 1 - cfg->native_code, MONO_PATCH_INFO_IP, NULL);
+               x86_mov_reg_imm (code, X86_EAX, 0);
+       }
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, eip), X86_EAX, sizeof (mgreg_t));
+
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, eip), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebp), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, esi), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, edi), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebx), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, esp), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, method), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), SLOT_NOREF);
+       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), SLOT_NOREF);
 
-       /* FIXME: Generate intermediate code instead */
+       return code;
+}
 
-       sig = mono_method_signature (method);
+/*
+ * emit_push_lmf:
+ *
+ *   Emit code to push an LMF structure on the LMF stack.
+ */
+static guint8*
+emit_push_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
+{
+       /* get the address of lmf for the current thread */
+       /* 
+        * This is performance critical so we try to use some tricks to make
+        * it fast.
+        */
+       gboolean have_fastpath = FALSE;
 
-       cinfo = get_call_info (cfg->generic_sharing_context, cfg->mempool, sig);
-       
-       /* This is the opposite of the code in emit_prolog */
+#ifdef TARGET_WIN32
+       if (jit_tls_offset != -1) {
+               code = mono_x86_emit_tls_get (code, X86_EAX, jit_tls_offset);                           
+               x86_alu_reg_imm (code, X86_ADD, X86_EAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
+               have_fastpath = TRUE;
+       }
+#else
+       if (!cfg->compile_aot && lmf_addr_tls_offset != -1) {
+               code = mono_x86_emit_tls_get (code, X86_EAX, lmf_addr_tls_offset);
+               have_fastpath = TRUE;
+       }
+#endif
+       if (!have_fastpath) {
+               if (cfg->compile_aot)
+                       code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL);
+               code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_get_lmf_addr");
+       }
 
-       for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
-               ArgInfo *ainfo = cinfo->args + i;
-               MonoType *arg_type;
-               inst = cfg->args [i];
+       /* save lmf_addr */
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), X86_EAX, sizeof (mgreg_t));
+       /* save previous_lmf */
+       x86_mov_reg_membase (code, X86_ECX, X86_EAX, 0, sizeof (mgreg_t));
+       x86_mov_membase_reg (code, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), X86_ECX, sizeof (mgreg_t));
+       /* set new LMF */
+       x86_lea_membase (code, X86_ECX, cfg->frame_reg, lmf_offset);
+       x86_mov_membase_reg (code, X86_EAX, 0, X86_ECX, sizeof (mgreg_t));
 
-               if (sig->hasthis && (i == 0))
-                       arg_type = &mono_defaults.object_class->byval_arg;
-               else
-                       arg_type = sig->params [i - sig->hasthis];
+       return code;
+}
 
-               /*
-                * On x86, the arguments are either in their original stack locations, or in
-                * global regs.
-                */
-               if (inst->opcode == OP_REGVAR) {
-                       g_assert (ainfo->storage == ArgOnStack);
-                       
-                       x86_mov_membase_reg (code, X86_EBP, inst->inst_offset, inst->dreg, 4);
-               }
+/*
+ * emit_pop_lmf:
+ *
+ *   Emit code to pop an LMF structure from the LMF stack.
+ * Preserves the return registers.
+ */
+static guint8*
+emit_pop_lmf (MonoCompile *cfg, guint8 *code, gint32 lmf_offset)
+{
+       MonoMethodSignature *sig = mono_method_signature (cfg->method);
+       int prev_lmf_reg;
+
+       /* Find a spare register */
+       switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) {
+       case MONO_TYPE_I8:
+       case MONO_TYPE_U8:
+               prev_lmf_reg = X86_EDI;
+               cfg->used_int_regs |= (1 << X86_EDI);
+               break;
+       default:
+               prev_lmf_reg = X86_EDX;
+               break;
        }
 
+       /* reg = previous_lmf */
+       x86_mov_reg_membase (code, prev_lmf_reg, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), 4);
+
+       /* ecx = lmf */
+       x86_mov_reg_membase (code, X86_ECX, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), 4);
+
+       /* *(lmf) = previous_lmf */
+       x86_mov_membase_reg (code, X86_ECX, 0, prev_lmf_reg, 4);
+
        return code;
 }
 
@@ -3110,48 +3250,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_MOVE:
                        x86_mov_reg_reg (code, ins->dreg, ins->sreg1, 4);
                        break;
-               case OP_JMP: {
-                       /*
-                        * Note: this 'frame destruction' logic is useful for tail calls, too.
-                        * Keep in sync with the code in emit_epilog.
-                        */
-                       int pos = 0;
-
-                       /* FIXME: no tracing support... */
-                       if (cfg->prof_options & MONO_PROFILE_ENTER_LEAVE)
-                               code = mono_arch_instrument_epilog (cfg, mono_profiler_method_leave, code, FALSE);
-                       /* reset offset to make max_len work */
-                       offset = code - cfg->native_code;
-
-                       g_assert (!cfg->method->save_lmf);
-
-                       code = emit_load_volatile_arguments (cfg, code);
-
-                       if (cfg->used_int_regs & (1 << X86_EBX))
-                               pos -= 4;
-                       if (cfg->used_int_regs & (1 << X86_EDI))
-                               pos -= 4;
-                       if (cfg->used_int_regs & (1 << X86_ESI))
-                               pos -= 4;
-                       if (pos)
-                               x86_lea_membase (code, X86_ESP, X86_EBP, pos);
-       
-                       if (cfg->used_int_regs & (1 << X86_ESI))
-                               x86_pop_reg (code, X86_ESI);
-                       if (cfg->used_int_regs & (1 << X86_EDI))
-                               x86_pop_reg (code, X86_EDI);
-                       if (cfg->used_int_regs & (1 << X86_EBX))
-                               x86_pop_reg (code, X86_EBX);
-       
-                       /* restore ESP/EBP */
-                       x86_leave (code);
-                       offset = code - cfg->native_code;
-                       mono_add_patch_info (cfg, offset, MONO_PATCH_INFO_METHOD_JUMP, ins->inst_p0);
-                       x86_jump32 (code, 0);
-
-                       cfg->disable_aot = TRUE;
-                       break;
-               }
                case OP_TAILCALL: {
                        MonoCallInst *call = (MonoCallInst*)ins;
                        int pos = 0, i;
@@ -3167,8 +3265,6 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
 
                        g_assert (!cfg->method->save_lmf);
 
-                       //code = emit_load_volatile_arguments (cfg, code);
-
                        /* restore callee saved registers */
                        for (i = 0; i < X86_NREG; ++i)
                                if (X86_IS_CALLEE_SAVED_REG (i) && cfg->used_int_regs & (1 << i))
@@ -3413,6 +3509,12 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_BR_REG:
                        x86_jump_reg (code, ins->sreg1);
                        break;
+               case OP_ICNEQ:
+               case OP_ICGE:
+               case OP_ICLE:
+               case OP_ICGE_UN:
+               case OP_ICLE_UN:
+
                case OP_CEQ:
                case OP_CLT:
                case OP_CLT_UN:
@@ -3847,6 +3949,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
                        break;
                case OP_FCEQ:
+               case OP_FCNEQ:
                        if (cfg->opt & MONO_OPT_FCMOV) {
                                /* zeroing the register at the start results in 
                                 * shorter and faster code (we can also remove the widening op)
@@ -3857,8 +3960,19 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                                x86_fstp (code, 0);
                                unordered_check = code;
                                x86_branch8 (code, X86_CC_P, 0, FALSE);
-                               x86_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
-                               x86_patch (unordered_check, code);
+                               if (ins->opcode == OP_FCEQ) {
+                                       x86_set_reg (code, X86_CC_EQ, ins->dreg, FALSE);
+                                       x86_patch (unordered_check, code);
+                               } else {
+                                       guchar *jump_to_end;
+                                       x86_set_reg (code, X86_CC_NE, ins->dreg, FALSE);
+                                       jump_to_end = code;
+                                       x86_jump8 (code, 0);
+                                       x86_patch (unordered_check, code);
+                                       x86_inc_reg (code, ins->dreg);
+                                       x86_patch (jump_to_end, code);
+                               }
+
                                break;
                        }
                        if (ins->dreg != X86_EAX) 
@@ -3867,7 +3981,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        EMIT_FPCOMPARE(code);
                        x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
                        x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4000);
-                       x86_set_reg (code, X86_CC_EQ, ins->dreg, TRUE);
+                       x86_set_reg (code, ins->opcode == OP_FCEQ ? X86_CC_EQ : X86_CC_NE, ins->dreg, TRUE);
                        x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
 
                        if (ins->dreg != X86_EAX) 
@@ -3919,6 +4033,44 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (ins->dreg != X86_EAX) 
                                x86_pop_reg (code, X86_EAX);
                        break;
+               case OP_FCLE: {
+                       guchar *unordered_check;
+                       guchar *jump_to_end;
+                       if (cfg->opt & MONO_OPT_FCMOV) {
+                               /* zeroing the register at the start results in
+                                * shorter and faster code (we can also remove the widening op)
+                                */
+                               x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                               x86_fcomip (code, 1);
+                               x86_fstp (code, 0);
+                               unordered_check = code;
+                               x86_branch8 (code, X86_CC_P, 0, FALSE);
+                               x86_set_reg (code, X86_CC_NB, ins->dreg, FALSE);
+                               x86_patch (unordered_check, code);
+                               break;
+                       }
+                       if (ins->dreg != X86_EAX)
+                               x86_push_reg (code, X86_EAX);
+
+                       EMIT_FPCOMPARE(code);
+                       x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
+                       x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+                       unordered_check = code;
+                       x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+
+                       x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
+                       x86_set_reg (code, X86_CC_NE, ins->dreg, TRUE);
+                       x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
+                       jump_to_end = code;
+                       x86_jump8 (code, 0);
+                       x86_patch (unordered_check, code);
+                       x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                       x86_patch (jump_to_end, code);
+
+                       if (ins->dreg != X86_EAX)
+                               x86_pop_reg (code, X86_EAX);
+                       break;
+               }
                case OP_FCGT:
                case OP_FCGT_UN:
                        if (cfg->opt & MONO_OPT_FCMOV) {
@@ -3962,6 +4114,44 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        if (ins->dreg != X86_EAX) 
                                x86_pop_reg (code, X86_EAX);
                        break;
+               case OP_FCGE: {
+                       guchar *unordered_check;
+                       guchar *jump_to_end;
+                       if (cfg->opt & MONO_OPT_FCMOV) {
+                               /* zeroing the register at the start results in
+                                * shorter and faster code (we can also remove the widening op)
+                                */
+                               x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                               x86_fcomip (code, 1);
+                               x86_fstp (code, 0);
+                               unordered_check = code;
+                               x86_branch8 (code, X86_CC_P, 0, FALSE);
+                               x86_set_reg (code, X86_CC_NA, ins->dreg, FALSE);
+                               x86_patch (unordered_check, code);
+                               break;
+                       }
+                       if (ins->dreg != X86_EAX)
+                               x86_push_reg (code, X86_EAX);
+
+                       EMIT_FPCOMPARE(code);
+                       x86_alu_reg_imm (code, X86_AND, X86_EAX, X86_FP_CC_MASK);
+                       x86_alu_reg_imm (code, X86_CMP, X86_EAX, 0x4500);
+                       unordered_check = code;
+                       x86_branch8 (code, X86_CC_EQ, 0, FALSE);
+
+                       x86_alu_reg_imm (code, X86_CMP, X86_EAX, X86_FP_C0);
+                       x86_set_reg (code, X86_CC_GE, ins->dreg, TRUE);
+                       x86_widen_reg (code, ins->dreg, ins->dreg, FALSE, FALSE);
+                       jump_to_end = code;
+                       x86_jump8 (code, 0);
+                       x86_patch (unordered_check, code);
+                       x86_alu_reg_reg (code, X86_XOR, ins->dreg, ins->dreg);
+                       x86_patch (jump_to_end, code);
+
+                       if (ins->dreg != X86_EAX)
+                               x86_pop_reg (code, X86_EAX);
+                       break;
+               }
                case OP_FBEQ:
                        if (cfg->opt & MONO_OPT_FCMOV) {
                                guchar *jump = code;
@@ -4119,18 +4309,15 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                        break;
                }
                case OP_TLS_GET_REG: {
-#ifdef __APPLE__
-                       // FIXME: tls_gs_offset can change too, do these when calculating the tls offset
-                       if (ins->dreg != ins->sreg1)
-                               x86_mov_reg_reg (code, ins->dreg, ins->sreg1, sizeof (gpointer));
-                       x86_shift_reg_imm (code, X86_SHL, ins->dreg, 2);
-                       if (tls_gs_offset)
-                               x86_alu_reg_imm (code, X86_ADD, ins->dreg, tls_gs_offset);
-                       x86_prefix (code, X86_GS_PREFIX);
-                       x86_mov_reg_membase (code, ins->dreg, ins->dreg, 0, sizeof (gpointer));
-#else
-                       g_assert_not_reached ();
-#endif
+                       code = emit_tls_get_reg (code, ins->dreg, ins->sreg1);
+                       break;
+               }
+               case OP_TLS_SET: {
+                       code = mono_x86_emit_tls_set (code, ins->sreg1, ins->inst_offset);
+                       break;
+               }
+               case OP_TLS_SET_REG: {
+                       code = emit_tls_set_reg (code, ins->sreg1, ins->sreg2);
                        break;
                }
                case OP_MEMORY_BARRIER: {
@@ -4261,7 +4448,7 @@ mono_arch_output_basic_block (MonoCompile *cfg, MonoBasicBlock *bb)
                case OP_CARD_TABLE_WBARRIER: {
                        int ptr = ins->sreg1;
                        int value = ins->sreg2;
-                       guchar *br;
+                       guchar *br = NULL;
                        int nursery_shift, card_table_shift;
                        gpointer card_table_mask;
                        size_t nursery_size;
@@ -5126,94 +5313,7 @@ mono_arch_emit_prolog (MonoCompile *cfg)
        alloc_size = cfg->stack_offset;
        pos = 0;
 
-       if (method->save_lmf) {
-               pos += sizeof (MonoLMF);
-
-               /* save the current IP */
-               if (cfg->compile_aot) {
-                       /* This pushes the current ip */
-                       x86_call_imm (code, 0);
-               } else {
-                       mono_add_patch_info (cfg, code + 1 - cfg->native_code, MONO_PATCH_INFO_IP, NULL);
-                       x86_push_imm_template (code);
-               }
-               cfa_offset += sizeof (gpointer);
-               mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-
-               /* save all caller saved regs */
-               x86_push_reg (code, X86_EBP);
-               cfa_offset += sizeof (gpointer);
-               mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-               x86_push_reg (code, X86_ESI);
-               cfa_offset += sizeof (gpointer);
-               mono_emit_unwind_op_offset (cfg, code, X86_ESI, - cfa_offset);
-               mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-               x86_push_reg (code, X86_EDI);
-               cfa_offset += sizeof (gpointer);
-               mono_emit_unwind_op_offset (cfg, code, X86_EDI, - cfa_offset);
-               mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-               x86_push_reg (code, X86_EBX);
-               cfa_offset += sizeof (gpointer);
-               mono_emit_unwind_op_offset (cfg, code, X86_EBX, - cfa_offset);
-               mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-
-               if ((lmf_tls_offset != -1) && !is_win32 && !optimize_for_xen) {
-                       /*
-                        * Optimized version which uses the mono_lmf TLS variable instead of indirection
-                        * through the mono_lmf_addr TLS variable.
-                        */
-                       /* %eax = previous_lmf */
-                       code = mono_x86_emit_tls_get (code, X86_EAX, lmf_tls_offset);
-                       /* skip esp + method_info + lmf */
-                       x86_alu_reg_imm (code, X86_SUB, X86_ESP, 12);
-                       cfa_offset += 12;
-                       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-                       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + 4, SLOT_NOREF);
-                       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset + 8, SLOT_NOREF);
-                       /* push previous_lmf */
-                       x86_push_reg (code, X86_EAX);
-                       cfa_offset += 4;
-                       mini_gc_set_slot_type_from_cfa (cfg, -cfa_offset, SLOT_NOREF);
-                       /* new lmf = ESP */
-                       code = mono_x86_emit_tls_set (code, X86_ESP, lmf_tls_offset);
-               } else {
-                       /* get the address of lmf for the current thread */
-                       /* 
-                        * This is performance critical so we try to use some tricks to make
-                        * it fast.
-                        */                                                                        
-                       gboolean have_fastpath = FALSE;
-
-#ifdef TARGET_WIN32
-                       if (jit_tls_offset != -1) {
-                               code = mono_x86_emit_tls_get (code, X86_EAX, jit_tls_offset);                           
-                               x86_alu_reg_imm (code, X86_ADD, X86_EAX, G_STRUCT_OFFSET (MonoJitTlsData, lmf));
-                               have_fastpath = TRUE;
-                       }
-#else
-                       if (lmf_addr_tls_offset != -1) {
-                               code = mono_x86_emit_tls_get (code, X86_EAX, lmf_addr_tls_offset);
-                               have_fastpath = TRUE;
-                       }
-#endif
-                       if (!have_fastpath) {
-                               if (cfg->compile_aot)
-                                       code = mono_arch_emit_load_got_addr (cfg->native_code, code, cfg, NULL);
-                               code = emit_call (cfg, code, MONO_PATCH_INFO_INTERNAL_METHOD, (gpointer)"mono_get_lmf_addr");
-                       }
-
-                       /* Skip esp + method info */
-                       x86_alu_reg_imm (code, X86_SUB, X86_ESP, 8);
-
-                       /* push lmf */
-                       x86_push_reg (code, X86_EAX); 
-                       /* push *lfm (previous_lmf) */
-                       x86_push_membase (code, X86_EAX, 0);
-                       /* *(lmf) = ESP */
-                       x86_mov_membase_reg (code, X86_EAX, 0, X86_ESP, 4);
-               }
-       } else {
-
+       if (!method->save_lmf) {
                if (cfg->used_int_regs & (1 << X86_EBX)) {
                        x86_push_reg (code, X86_EBX);
                        pos += 4;
@@ -5361,6 +5461,12 @@ mono_arch_emit_prolog (MonoCompile *cfg)
                x86_mov_membase_reg (code, X86_EBP, cfg->rgctx_var->inst_offset, MONO_ARCH_RGCTX_REG, 4);
        }
 
+       if (method->save_lmf) {
+               code = emit_setup_lmf (cfg, code, cfg->lmf_var->inst_offset, cfa_offset);
+               if (!cfg->lmf_ir)
+                       code = emit_push_lmf (cfg, code, cfg->lmf_var->inst_offset);
+       }
+
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
                code = mono_arch_instrument_prolog (cfg, mono_trace_enter_method, code, TRUE);
 
@@ -5391,7 +5497,7 @@ mono_arch_emit_epilog (MonoCompile *cfg)
 {
        MonoMethod *method = cfg->method;
        MonoMethodSignature *sig = mono_method_signature (method);
-       int quad, pos;
+       int i, quad, pos;
        guint32 stack_to_pop;
        guint8 *code;
        int max_epilog_size = 16;
@@ -5412,17 +5518,32 @@ mono_arch_emit_epilog (MonoCompile *cfg)
        if (mono_jit_trace_calls != NULL && mono_trace_eval (method))
                code = mono_arch_instrument_epilog (cfg, mono_trace_leave_method, code, TRUE);
 
-       /* the code restoring the registers must be kept in sync with OP_JMP */
+       /* the code restoring the registers must be kept in sync with OP_TAILCALL */
        pos = 0;
        
        if (method->save_lmf) {
-               gint32 prev_lmf_reg;
-               gint32 lmf_offset = -sizeof (MonoLMF);
+               gint32 lmf_offset = cfg->lmf_var->inst_offset;
+               guint8 *patch;
+               gboolean supported = FALSE;
+
+               if (cfg->compile_aot) {
+#if defined(__APPLE__) || defined(__linux__)
+                       supported = TRUE;
+#endif
+               } else if (mono_get_jit_tls_offset () != -1) {
+                       supported = TRUE;
+               }
 
                /* check if we need to restore protection of the stack after a stack overflow */
-               if (mono_get_jit_tls_offset () != -1) {
-                       guint8 *patch;
-                       code = mono_x86_emit_tls_get (code, X86_ECX, mono_get_jit_tls_offset ());
+               if (supported) {
+                       if (cfg->compile_aot) {
+                               code = emit_load_aotconst (NULL, code, cfg, NULL, X86_ECX, MONO_PATCH_INFO_TLS_OFFSET, GINT_TO_POINTER (TLS_KEY_JIT_TLS));
+
+                               code = emit_tls_get_reg (code, X86_ECX, X86_ECX);
+                       } else {
+                               code = mono_x86_emit_tls_get (code, X86_ECX, mono_get_jit_tls_offset ());
+                       }
+
                        /* we load the value in a separate instruction: this mechanism may be
                         * used later as a safer way to do thread interruption
                         */
@@ -5436,61 +5557,33 @@ mono_arch_emit_epilog (MonoCompile *cfg)
                } else {
                        /* FIXME: maybe save the jit tls in the prolog */
                }
-               if ((lmf_tls_offset != -1) && !is_win32 && !optimize_for_xen) {
-                       /*
-                        * Optimized version which uses the mono_lmf TLS variable instead of indirection
-                        * through the mono_lmf_addr TLS variable.
-                        */
-                       /* reg = previous_lmf */
-                       x86_mov_reg_membase (code, X86_ECX, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), 4);
-
-                       /* lmf = previous_lmf */
-                       code = mono_x86_emit_tls_set (code, X86_ECX, lmf_tls_offset);
-               } else {
-                       /* Find a spare register */
-                       switch (mini_type_get_underlying_type (cfg->generic_sharing_context, sig->ret)->type) {
-                       case MONO_TYPE_I8:
-                       case MONO_TYPE_U8:
-                               prev_lmf_reg = X86_EDI;
-                               cfg->used_int_regs |= (1 << X86_EDI);
-                               break;
-                       default:
-                               prev_lmf_reg = X86_EDX;
-                               break;
-                       }
-
-                       /* reg = previous_lmf */
-                       x86_mov_reg_membase (code, prev_lmf_reg, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), 4);
 
-                       /* ecx = lmf */
-                       x86_mov_reg_membase (code, X86_ECX, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), 4);
-
-                       /* *(lmf) = previous_lmf */
-                       x86_mov_membase_reg (code, X86_ECX, 0, prev_lmf_reg, 4);
-               }
+               if (!cfg->lmf_ir)
+                       code = emit_pop_lmf (cfg, code, lmf_offset);
 
                /* restore caller saved regs */
                if (cfg->used_int_regs & (1 << X86_EBX)) {
-                       x86_mov_reg_membase (code, X86_EBX, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebx), 4);
+                       x86_mov_reg_membase (code, X86_EBX, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, ebx), 4);
                }
 
                if (cfg->used_int_regs & (1 << X86_EDI)) {
-                       x86_mov_reg_membase (code, X86_EDI, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, edi), 4);
+                       x86_mov_reg_membase (code, X86_EDI, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, edi), 4);
                }
                if (cfg->used_int_regs & (1 << X86_ESI)) {
-                       x86_mov_reg_membase (code, X86_ESI, X86_EBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, esi), 4);
+                       x86_mov_reg_membase (code, X86_ESI, cfg->frame_reg, lmf_offset + G_STRUCT_OFFSET (MonoLMF, esi), 4);
                }
 
                /* EBP is restored by LEAVE */
        } else {
-               if (cfg->used_int_regs & (1 << X86_EBX)) {
-                       pos -= 4;
-               }
-               if (cfg->used_int_regs & (1 << X86_EDI)) {
-                       pos -= 4;
+               for (i = 0; i < X86_NREG; ++i) {
+                       if ((cfg->used_int_regs & X86_CALLER_REGS & (1 << i)) && (i != X86_EBP)) {
+                               pos -= 4;
+                       }
                }
-               if (cfg->used_int_regs & (1 << X86_ESI)) {
-                       pos -= 4;
+
+               if (pos) {
+                       g_assert (need_stack_frame);
+                       x86_lea_membase (code, X86_ESP, X86_EBP, pos);
                }
 
                if (pos) {
@@ -5693,20 +5786,15 @@ mono_arch_finish_init (void)
                 * We need to init this multiple times, since when we are first called, the key might not
                 * be initialized yet.
                 */
-               appdomain_tls_offset = mono_domain_get_tls_key ();
                jit_tls_offset = mono_get_jit_tls_key ();
 
                /* Only 64 tls entries can be accessed using inline code */
-               if (appdomain_tls_offset >= 64)
-                       appdomain_tls_offset = -1;
                if (jit_tls_offset >= 64)
                        jit_tls_offset = -1;
 #else
 #if MONO_XEN_OPT
                optimize_for_xen = access ("/proc/xen", F_OK) == 0;
 #endif
-               appdomain_tls_offset = mono_domain_get_tls_offset ();
-               lmf_tls_offset = mono_get_lmf_tls_offset ();
                lmf_addr_tls_offset = mono_get_lmf_addr_tls_offset ();
 #endif
        }               
@@ -5977,20 +6065,6 @@ mono_arch_print_tree (MonoInst *tree, int arity)
        return 0;
 }
 
-MonoInst* mono_arch_get_domain_intrinsic (MonoCompile* cfg)
-{
-       MonoInst* ins;
-
-       return NULL;
-
-       if (appdomain_tls_offset == -1)
-               return NULL;
-
-       MONO_INST_NEW (cfg, ins, OP_TLS_GET);
-       ins->inst_offset = appdomain_tls_offset;
-       return ins;
-}
-
 guint32
 mono_arch_get_patch_offset (guint8 *code)
 {
@@ -6554,8 +6628,19 @@ mono_arch_emit_load_got_addr (guint8 *start, guint8 *code, MonoCompile *cfg, Mon
        return code;
 }
 
+static guint8*
+emit_load_aotconst (guint8 *start, guint8 *code, MonoCompile *cfg, MonoJumpInfo **ji, int dreg, int tramp_type, gconstpointer target)
+{
+       if (cfg)
+               mono_add_patch_info (cfg, code - cfg->native_code, tramp_type, target);
+       else
+               g_assert_not_reached ();
+       x86_mov_reg_membase (code, dreg, MONO_ARCH_GOT_REG, 0xf0f0f0f0, 4);
+       return code;
+}
+
 /*
- * mono_ppc_emit_load_aotconst:
+ * mono_arch_emit_load_aotconst:
  *
  *   Emit code to load the contents of the GOT slot identified by TRAMP_TYPE and
  * TARGET from the mscorlib GOT in full-aot code.
@@ -6739,6 +6824,15 @@ mono_arch_get_seq_point_info (MonoDomain *domain, guint8 *code)
        return NULL;
 }
 
+void
+mono_arch_init_lmf_ext (MonoLMFExt *ext, gpointer prev_lmf)
+{
+       ext->lmf.previous_lmf = (gsize)prev_lmf;
+       /* Mark that this is a MonoLMFExt */
+       ext->lmf.previous_lmf = (gsize)(gpointer)(((gssize)ext->lmf.previous_lmf) | 2);
+       ext->lmf.ebp = (gssize)ext;
+}
+
 #endif
 
 #if defined(MONOTOUCH) || defined(MONO_EXTENSIONS)
index 20d2eeb329a793e67a9fab9100b97b40cb6b5cf1..1b7341b5aff58485c988a5387bbe7bcaaaef14ea 100644 (file)
@@ -262,15 +262,9 @@ typedef struct {
 #define MONO_ARCH_HAVE_CONTEXT_SET_INT_REG 1
 #define MONO_ARCH_HAVE_SETUP_ASYNC_CALLBACK 1
 #define MONO_ARCH_GSHAREDVT_SUPPORTED 1
-
-#ifdef TARGET_OSX
+#define MONO_ARCH_HAVE_OP_TAIL_CALL 1
+#define MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET 1
 #define MONO_ARCH_HAVE_TLS_GET_REG 1
-#endif
-
-gboolean
-mono_x86_tail_call_supported (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) MONO_INTERNAL;
-
-#define MONO_ARCH_USE_OP_TAIL_CALL(caller_sig, callee_sig) mono_x86_tail_call_supported (caller_sig, callee_sig)
 
 /* Used for optimization, not complete */
 #define MONO_ARCH_IS_OP_MEMBASE(opcode) ((opcode) == OP_X86_PUSH_MEMBASE)
index 6d7de6f3b8104b13d468a9d77a090ab9513a4fee..b8daf5b0cb2ed1d7ce6d1a7dff6b6748479c0523 100644 (file)
@@ -49,6 +49,7 @@
 #include <mono/metadata/mempool-internals.h>
 #include <mono/metadata/attach.h>
 #include <mono/metadata/runtime.h>
+#include <mono/metadata/mono-debug-debugger.h>
 #include <mono/utils/mono-math.h>
 #include <mono/utils/mono-compiler.h>
 #include <mono/utils/mono-counters.h>
 
 #include "jit-icalls.h"
 
-#include "debug-mini.h"
 #include "mini-gc.h"
 #include "debugger-agent.h"
 
-/* this macro is used for a runtime check done in mini_init () */
-#ifdef MONO_ARCH_EMULATE_MUL_DIV
-#define EMUL_MUL_DIV 1
-#else
-#define EMUL_MUL_DIV 0
-#endif
-
 static gpointer mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException **ex);
 
 
@@ -94,20 +87,12 @@ MonoNativeTlsKey mono_jit_tls_id;
 MONO_FAST_TLS_DECLARE(mono_jit_tls);
 #endif
 
-#ifndef MONO_ARCH_MONITOR_ENTER_ADJUSTMENT
-#define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT 1
-#endif
-
 MonoTraceSpec *mono_jit_trace_calls = NULL;
 gboolean mono_compile_aot = FALSE;
 /* If this is set, no code is generated dynamically, everything is taken from AOT files */
 gboolean mono_aot_only = FALSE;
 /* Whenever to use IMT */
-#ifdef MONO_ARCH_HAVE_IMT
-gboolean mono_use_imt = TRUE;
-#else
-gboolean mono_use_imt = FALSE;
-#endif
+gboolean mono_use_imt = ARCH_HAVE_IMT;
 MonoMethodDesc *mono_inject_async_exc_method = NULL;
 int mono_inject_async_exc_pos;
 MonoMethodDesc *mono_break_at_bb_method = NULL;
@@ -912,6 +897,8 @@ mono_type_to_store_membase (MonoCompile *cfg, MonoType *type)
        if (type->byref)
                return OP_STORE_MEMBASE_REG;
 
+       type = mini_type_get_underlying_type (NULL, type);
+
 handle_enum:
        switch (type->type) {
        case MONO_TYPE_I1:
@@ -974,7 +961,7 @@ mono_type_to_load_membase (MonoCompile *cfg, MonoType *type)
        if (type->byref)
                return OP_LOAD_MEMBASE;
 
-       type = mono_type_get_underlying_type (type);
+       type = mini_type_get_underlying_type (NULL, type);
 
        switch (type->type) {
        case MONO_TYPE_I1:
@@ -1052,6 +1039,8 @@ mini_type_to_ldind (MonoCompile* cfg, MonoType *type)
 guint
 mini_type_to_stind (MonoCompile* cfg, MonoType *type)
 {
+       type = mini_type_get_underlying_type (NULL, type);
+
        if (cfg->generic_sharing_context && !type->byref) {
                if (type->type == MONO_TYPE_VAR || type->type == MONO_TYPE_MVAR) {
                        if (mini_type_var_is_vt (cfg, type))
@@ -1231,6 +1220,8 @@ mono_compile_create_var_for_vreg (MonoCompile *cfg, MonoType *type, int opcode,
        int num = cfg->num_varinfo;
        gboolean regpair;
 
+       type = mini_type_get_underlying_type (NULL, type);
+
        if ((num + 1) >= cfg->varinfo_count) {
                int orig_count = cfg->varinfo_count;
                cfg->varinfo_count = cfg->varinfo_count ? (cfg->varinfo_count * 2) : 64;
@@ -1339,6 +1330,7 @@ MonoInst*
 mono_compile_create_var (MonoCompile *cfg, MonoType *type, int opcode)
 {
        int dreg;
+       type = mini_type_get_underlying_type (NULL, type);
 
        if (mono_type_is_long (type))
                dreg = mono_alloc_dreg (cfg, STACK_I8);
@@ -1535,10 +1527,9 @@ mono_get_array_new_va_signature (int arity)
        res = mono_metadata_signature_alloc (mono_defaults.corlib, arity + 1);
 
        res->pinvoke = 1;
-#ifdef MONO_ARCH_VARARG_ICALLS
-       /* Only set this only some archs since not all backends can handle varargs+pinvoke */
-       res->call_convention = MONO_CALL_VARARG;
-#endif
+       if (ARCH_VARARG_ICALLS)
+               /* Only set this only some archs since not all backends can handle varargs+pinvoke */
+               res->call_convention = MONO_CALL_VARARG;
 
 #ifdef TARGET_WIN32
        res->call_convention = MONO_CALL_C;
@@ -2854,7 +2845,6 @@ mono_thread_start_cb (intptr_t tid, gpointer stack_start, gpointer func)
        MonoInternalThread *thread;
        void *jit_tls = setup_jit_tls_data (stack_start, mono_thread_abort);
        thread = mono_thread_internal_current ();
-       mono_debugger_thread_created (tid, thread->root_domain_thread, jit_tls, func);
        if (thread)
                thread->jit_data = jit_tls;
 
@@ -2878,7 +2868,6 @@ mono_thread_attach_cb (intptr_t tid, gpointer stack_start)
        MonoInternalThread *thread;
        void *jit_tls = setup_jit_tls_data (stack_start, mono_thread_abort_dummy);
        thread = mono_thread_internal_current ();
-       mono_debugger_thread_created (tid, thread->root_domain_thread, (MonoJitTlsData *) jit_tls, NULL);
        if (thread)
                thread->jit_data = jit_tls;
        if (mono_profiler_get_events () & MONO_PROFILE_STATISTICAL)
@@ -2893,8 +2882,6 @@ mini_thread_cleanup (MonoInternalThread *thread)
        MonoJitTlsData *jit_tls = thread->jit_data;
 
        if (jit_tls) {
-               mono_debugger_thread_cleanup (jit_tls);
-
                /* We can't clean up tls information if we are on another thread, it will clean up the wrong stuff
                 * It would be nice to issue a warning when this happens outside of the shutdown sequence. but it's
                 * not a trivial thing.
@@ -2942,6 +2929,7 @@ mini_get_tls_offset (MonoTlsKey key)
                g_assert (offset != -1);
                break;
        }
+
        return offset;
 }
 
@@ -2964,6 +2952,18 @@ mono_create_tls_get_offset (MonoCompile *cfg, int offset)
        return ins;
 }
 
+gboolean
+mini_tls_get_supported (MonoCompile *cfg, MonoTlsKey key)
+{
+       if (!MONO_ARCH_HAVE_TLS_GET)
+               return FALSE;
+
+       if (cfg->compile_aot)
+               return ARCH_HAVE_TLS_GET_REG;
+       else
+               return mini_get_tls_offset (key) != -1;
+}
+
 MonoInst*
 mono_create_tls_get (MonoCompile *cfg, MonoTlsKey key)
 {
@@ -3012,6 +3012,12 @@ mono_get_lmf_intrinsic (MonoCompile* cfg)
        return mono_create_tls_get (cfg, TLS_KEY_LMF);
 }
 
+MonoInst*
+mono_get_lmf_addr_intrinsic (MonoCompile* cfg)
+{
+       return mono_create_tls_get (cfg, TLS_KEY_LMF_ADDR);
+}
+
 #endif /* !DISABLE_JIT */
 
 void
@@ -3166,6 +3172,7 @@ mono_patch_info_hash (gconstpointer data)
        case MONO_PATCH_INFO_DELEGATE_TRAMPOLINE:
        case MONO_PATCH_INFO_SIGNATURE:
        case MONO_PATCH_INFO_TLS_OFFSET:
+       case MONO_PATCH_INFO_METHOD_CODE_SLOT:
                return (ji->type << 8) | (gssize)ji->data.target;
        case MONO_PATCH_INFO_GSHAREDVT_CALL:
                return (ji->type << 8) | (gssize)ji->data.gsharedvt->method;
@@ -3330,6 +3337,21 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                }
 #endif
                break;
+       case MONO_PATCH_INFO_METHOD_CODE_SLOT: {
+               gpointer code_slot;
+
+               mono_domain_lock (domain);
+               if (!domain_jit_info (domain)->method_code_hash)
+                       domain_jit_info (domain)->method_code_hash = g_hash_table_new (NULL, NULL);
+               code_slot = g_hash_table_lookup (domain_jit_info (domain)->method_code_hash, patch_info->data.method);
+               if (!code_slot) {
+                       code_slot = mono_domain_alloc0 (domain, sizeof (gpointer));
+                       g_hash_table_insert (domain_jit_info (domain)->method_code_hash, patch_info->data.method, code_slot);
+               }
+               mono_domain_unlock (domain);
+               target = code_slot;
+               break;
+       }
        case MONO_PATCH_INFO_SWITCH: {
                gpointer *jump_table;
                int i;
@@ -3602,9 +3624,16 @@ mono_resolve_patch_target (MonoMethod *method, MonoDomain *domain, guint8 *code,
                target = (gpointer) (size_t) mono_jit_tls_id;
                break;
        }
-       case MONO_PATCH_INFO_TLS_OFFSET:
-               target = GINT_TO_POINTER (mini_get_tls_offset (GPOINTER_TO_INT (patch_info->data.target)));
+       case MONO_PATCH_INFO_TLS_OFFSET: {
+               int offset;
+
+               offset = mini_get_tls_offset (GPOINTER_TO_INT (patch_info->data.target));
+#ifdef MONO_ARCH_HAVE_TRANSLATE_TLS_OFFSET
+               offset = mono_arch_translate_tls_offset (offset);
+#endif
+               target = GINT_TO_POINTER (offset);
                break;
+       }
        case MONO_PATCH_INFO_OBJC_SELECTOR_REF: {
                target = NULL;
                break;
@@ -3707,6 +3736,13 @@ mono_compile_create_vars (MonoCompile *cfg)
                g_print ("locals done\n");
 
        mono_arch_create_vars (cfg);
+
+       if (cfg->method->save_lmf && cfg->create_lmf_var) {
+               MonoInst *lmf_var = mono_compile_create_var (cfg, &mono_defaults.int_class->byval_arg, OP_LOCAL);
+               lmf_var->flags |= MONO_INST_VOLATILE;
+               lmf_var->flags |= MONO_INST_LMF;
+               cfg->lmf_var = lmf_var;
+       }
 }
 
 void
@@ -4541,7 +4577,6 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
         * Its possible to generate dwarf unwind info for xdebug etc, but not actually
         * using it during runtime, hence the define.
         */
-#ifdef MONO_ARCH_HAVE_XP_UNWIND
        if (cfg->encoded_unwind_ops) {
                jinfo->used_regs = mono_cache_unwind_info (cfg->encoded_unwind_ops, cfg->encoded_unwind_ops_len);
                g_free (cfg->encoded_unwind_ops);
@@ -4552,7 +4587,6 @@ create_jit_info (MonoCompile *cfg, MonoMethod *method_to_compile)
                jinfo->used_regs = mono_cache_unwind_info (unwind_info, info_len);
                g_free (unwind_info);
        }
-#endif
 
        return jinfo;
 }
@@ -4958,7 +4992,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 #endif
 
        /* The debugger has no liveness information, so avoid sharing registers/stack slots */
-       if (mono_debug_using_mono_debugger () || debug_options.mdb_optimizations) {
+       if (debug_options.mdb_optimizations) {
                cfg->disable_reuse_registers = TRUE;
                cfg->disable_reuse_stack_slots = TRUE;
                /* 
@@ -5211,6 +5245,8 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        mono_handle_global_vregs (cfg);
        if (cfg->opt & MONO_OPT_DEADCE)
                mono_local_deadce (cfg);
+       if (cfg->opt & MONO_OPT_ALIAS_ANALYSIS)
+               mono_local_alias_analysis (cfg);
        /* Disable this for LLVM to make the IR easier to handle */
        if (!COMPILE_LLVM (cfg))
                mono_if_conversion (cfg);
@@ -5365,6 +5401,7 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
 #endif
 
        if (cfg->comp_done & MONO_COMP_SSA && COMPILE_LLVM (cfg)) {
+               mono_ssa_loop_invariant_code_motion (cfg);
                /* This removes MONO_INST_FAULT flags too so perform it unconditionally */
                if (cfg->opt & MONO_OPT_ABCREM)
                        mono_perform_abc_removal (cfg);
@@ -5381,7 +5418,9 @@ mini_method_compile (MonoMethod *method, guint32 opts, MonoDomain *domain, gbool
        if (COMPILE_SOFT_FLOAT (cfg))
                mono_decompose_soft_float (cfg);
 #endif
-       if (!COMPILE_LLVM (cfg))
+       if (COMPILE_LLVM (cfg))
+               mono_decompose_vtype_opts_llvm (cfg);
+       else
                mono_decompose_vtype_opts (cfg);
        if (cfg->flags & MONO_CFG_HAS_ARRAY_ACCESS)
                mono_decompose_array_access_opts (cfg);
@@ -5782,9 +5821,6 @@ mono_jit_compile_method_inner (MonoMethod *method, MonoDomain *target_domain, in
                if (jinfo)
                        mono_profiler_method_end_jit (method, jinfo, MONO_PROFILE_OK);
                return code;
-
-               //if (mono_debug_format != MONO_DEBUG_FORMAT_NONE) 
-               //mono_debug_add_wrapper (method, nm);
        } else if ((method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME)) {
                const char *name = method->name;
                char *full_name, *msg;
@@ -6169,7 +6205,6 @@ mono_jit_compile_method_with_opt (MonoMethod *method, guint32 opt, MonoException
                if (!callinfo->wrapper) {
                        callinfo->wrapper = p;
                        mono_register_jit_icall_wrapper (callinfo, p);
-                       mono_debug_add_icall_wrapper (method, callinfo);
                }
                mono_jit_unlock ();
                mono_loader_unlock ();
@@ -6446,6 +6481,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                 */
 #ifdef MONO_ARCH_DYN_CALL_SUPPORTED
                if (mono_aot_only || debug_options.dyn_runtime_invoke) {
+                       MonoType *ret_type;
                        MonoMethodSignature *sig = mono_method_signature (method);
                        gboolean supported = TRUE;
                        int i;
@@ -6466,8 +6502,9 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                        if (supported)
                                info->dyn_call_info = mono_arch_dyn_call_prepare (sig);
 
+                       ret_type = mini_type_get_underlying_type (NULL, sig->ret);
                        if (info->dyn_call_info) {
-                               switch (sig->ret->type) {
+                               switch (ret_type->type) {
                                case MONO_TYPE_VOID:
                                        break;
                                case MONO_TYPE_I1:
@@ -6484,7 +6521,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                                case MONO_TYPE_CHAR:
                                case MONO_TYPE_R4:
                                case MONO_TYPE_R8:
-                                       info->ret_box_class = mono_class_from_mono_type (sig->ret);
+                                       info->ret_box_class = mono_class_from_mono_type (ret_type);
                                        break;
                                case MONO_TYPE_PTR:
                                        info->ret_box_class = mono_defaults.int_class;
@@ -6496,11 +6533,11 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                                case MONO_TYPE_OBJECT:
                                        break;
                                case MONO_TYPE_GENERICINST:
-                                       if (!MONO_TYPE_IS_REFERENCE (sig->ret))
-                                               info->ret_box_class = mono_class_from_mono_type (sig->ret);
+                                       if (!MONO_TYPE_IS_REFERENCE (ret_type))
+                                               info->ret_box_class = mono_class_from_mono_type (ret_type);
                                        break;
                                case MONO_TYPE_VALUETYPE:
-                                       info->ret_box_class = mono_class_from_mono_type (sig->ret);
+                                       info->ret_box_class = mono_class_from_mono_type (ret_type);
                                        break;
                                default:
                                        g_assert_not_reached ();
@@ -6562,7 +6599,7 @@ mono_jit_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObjec
                if (sig->hasthis)
                        args [pindex ++] = &obj;
                for (i = 0; i < sig->param_count; ++i) {
-                       MonoType *t = sig->params [i];
+                       MonoType *t = mini_type_get_underlying_type (NULL, sig->params [i]);
 
                        if (t->byref) {
                                args [pindex ++] = &params [i];
@@ -6922,6 +6959,10 @@ register_jit_stats (void)
        mono_counters_register ("Method cache lookups", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.methods_lookups);
        mono_counters_register ("Compiled CIL code size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.cil_code_size);
        mono_counters_register ("Native code size", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.native_code_size);
+       mono_counters_register ("Aliases found", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.alias_found);
+       mono_counters_register ("Aliases eliminated", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.alias_removed);
+       mono_counters_register ("Aliased loads eliminated", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.loads_eliminated);
+       mono_counters_register ("Aliased stores eliminated", MONO_COUNTER_JIT | MONO_COUNTER_INT, &mono_jit_stats.stores_eliminated);
 }
 
 static void runtime_invoke_info_free (gpointer value);
@@ -7048,11 +7089,6 @@ mini_init (const char *filename, const char *runtime_version)
 
        InitializeCriticalSection (&jit_mutex);
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-       if (mini_debug_running_inside_mdb ())
-               mini_debugger_init ();
-#endif
-
 #ifdef MONO_HAVE_FAST_TLS
        MONO_FAST_TLS_INIT (mono_jit_tls);
        MONO_FAST_TLS_INIT (mono_lmf_addr);
@@ -7308,7 +7344,7 @@ mini_init (const char *filename, const char *runtime_version)
 #endif
 
 #if defined(MONO_ARCH_EMULATE_MUL_DIV) || defined(MONO_ARCH_SOFT_FLOAT_FALLBACK)
-       if (EMUL_MUL_DIV || mono_arch_is_soft_float ()) {
+       if (ARCH_EMULATE_MUL_DIV || mono_arch_is_soft_float ()) {
                register_opcode_emulation (OP_FDIV, "__emul_fdiv", "double double double", mono_fdiv, "mono_fdiv", FALSE);
        }
 #endif
@@ -7390,6 +7426,8 @@ mini_init (const char *filename, const char *runtime_version)
 
 #if SIZEOF_REGISTER == 4
        register_opcode_emulation (OP_FCONV_TO_U, "__emul_fconv_to_u", "uint32 double", mono_fconv_u4, "mono_fconv_u4", TRUE);
+#else
+       register_opcode_emulation (OP_FCONV_TO_U, "__emul_fconv_to_u", "ulong double", mono_fconv_u8, "mono_fconv_u8", TRUE);
 #endif
 
        /* other jit icalls */
@@ -7572,8 +7610,6 @@ mini_cleanup (MonoDomain *domain)
        mono_domain_free (domain, TRUE);
 #endif
 
-       mono_debugger_cleanup ();
-
 #ifdef ENABLE_LLVM
        if (mono_use_llvm)
                mono_llvm_cleanup ();
index 8d363f0371d83809a7c2ad910f5cb089869c1dc9..01dffc2b89f4cf9a46600d2ab2da17d9b5630b00 100644 (file)
 #define LLVM_CHECK_VERSION(major,minor) 0
 #endif
 
-/* 
- * Whenever we are using mono's LLVM branch.
- * This can be used in if statements, code which references new definitions from the branch
- * still needs an #ifdef LLVM_MONO_BRANCH.
- */
-#ifdef LLVM_MONO_BRANCH
-#define IS_LLVM_MONO_BRANCH 1
-#else
-#define IS_LLVM_MONO_BRANCH 0
-#endif
-
 #define NOT_IMPLEMENTED do { g_assert_not_reached (); } while (0)
 
 /* for 32 bit systems */
 #endif
 
 /* Version number of the AOT file format */
-#define MONO_AOT_FILE_VERSION 95
+#define MONO_AOT_FILE_VERSION 97
 
 //TODO: This is x86/amd64 specific.
 #define mono_simd_shuffle_mask(a,b,c,d) ((a) | ((b) << 2) | ((c) << 4) | ((d) << 6))
@@ -284,6 +273,10 @@ typedef struct MonoAotFileInfo
 
        /* These are used for sanity checking object layout problems when cross-compiling */
        guint32 double_align, long_align, generic_tramp_num;
+       /* The page size used by trampoline pages */
+       guint32 tramp_page_size;
+       /* The offset where the trampolines begin on a trampoline page */
+       guint32 tramp_page_code_offsets [MONO_AOT_TRAMP_NUM];
 } MonoAotFileInfo;
 
 /* Per-domain information maintained by the JIT */
@@ -469,7 +462,7 @@ enum {
 
 /* FIXME: Add more instructions */
 /* INEG sets the condition codes, and the OP_LNEG decomposition depends on this on x86 */
-#define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || MONO_IS_ZERO (ins) || (ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || (ins->opcode == OP_LNEG) || (ins->opcode == OP_ISUB) || (ins->opcode == OP_CMOV_IGE) || (ins->opcode == OP_ISHL_IMM) || (ins->opcode == OP_ISHR_IMM) || (ins->opcode == OP_ISHR_UN_IMM) || (ins->opcode == OP_IAND_IMM) || (ins->opcode == OP_ICONV_TO_U1) || (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_SEXT_I4) || (ins->opcode == OP_LCONV_TO_U1) || (ins->opcode == OP_ICONV_TO_U2) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_LCONV_TO_I2) || (ins->opcode == OP_LDADDR))
+#define MONO_INS_HAS_NO_SIDE_EFFECT(ins) (MONO_IS_MOVE (ins) || (ins->opcode == OP_ICONST) || (ins->opcode == OP_I8CONST) || MONO_IS_ZERO (ins) || (ins->opcode == OP_ADD_IMM) || (ins->opcode == OP_R8CONST) || (ins->opcode == OP_LADD_IMM) || (ins->opcode == OP_ISUB_IMM) || (ins->opcode == OP_IADD_IMM) || (ins->opcode == OP_LNEG) || (ins->opcode == OP_ISUB) || (ins->opcode == OP_CMOV_IGE) || (ins->opcode == OP_ISHL_IMM) || (ins->opcode == OP_ISHR_IMM) || (ins->opcode == OP_ISHR_UN_IMM) || (ins->opcode == OP_IAND_IMM) || (ins->opcode == OP_ICONV_TO_U1) || (ins->opcode == OP_ICONV_TO_I1) || (ins->opcode == OP_SEXT_I4) || (ins->opcode == OP_LCONV_TO_U1) || (ins->opcode == OP_ICONV_TO_U2) || (ins->opcode == OP_ICONV_TO_I2) || (ins->opcode == OP_LCONV_TO_I2) || (ins->opcode == OP_LDADDR) || (ins->opcode == OP_PHI) || (ins->opcode == OP_NOP) || (ins->opcode == OP_ZEXT_I4) || (ins->opcode == OP_NOT_NULL))
 
 #define MONO_METHOD_IS_FINAL(m) (((m)->flags & METHOD_ATTRIBUTE_FINAL) || ((m)->klass && ((m)->klass->flags & TYPE_ATTRIBUTE_SEALED)))
 
@@ -854,6 +847,10 @@ struct MonoCallInst {
        LLVMCallInfo *cinfo;
        int rgctx_arg_reg, imt_arg_reg;
 #endif
+#ifdef TARGET_ARM
+       /* See the comment in mini-arm.c!mono_arch_emit_call for RegTypeFP. */
+       GSList *float_args;
+#endif
 };
 
 struct MonoCallArgParm {
@@ -892,7 +889,7 @@ enum {
         */
        MONO_INST_LMF = 32,
        /* On loads, the source address points to a constant value */
-       MONO_INST_CONSTANT_LOAD = 64,
+       MONO_INST_INVARIANT_LOAD = 64,
        /* On variables, the variable needs GC tracking */
        MONO_INST_GC_TRACK = 128,
        /*
@@ -1392,6 +1389,9 @@ typedef struct {
        /* For native-to-managed wrappers, the saved old domain */
        MonoInst *orig_domain_var;
 
+       MonoInst *lmf_var;
+       MonoInst *lmf_addr_var;
+
        unsigned char   *cil_start;
 #ifdef __native_client_codegen__
        /* this alloc is not aligned, native_code */
@@ -1437,6 +1437,17 @@ typedef struct {
        guint            disable_vreg_to_lvreg : 1;
        guint            disable_deadce_vars : 1;
        guint            disable_out_of_line_bblocks : 1;
+       guint            create_lmf_var : 1;
+       /*
+        * When this is set, the code to push/pop the LMF from the LMF stack is generated as IR
+        * instead of being generated in emit_prolog ()/emit_epilog ().
+        */
+       guint            lmf_ir : 1;
+       /*
+        * Whenever to use the mono_lmf TLS variable instead of indirection through the
+        * mono_lmf_addr TLS variable.
+        */
+       guint            lmf_ir_mono_lmf : 1;
        guint            gen_write_barriers : 1;
        guint            init_ref_vars : 1;
        guint            extend_live_ranges : 1;
@@ -1451,6 +1462,7 @@ typedef struct {
        guint            compute_gc_maps : 1;
        guint            soft_breakpoints : 1;
        guint            arch_eh_jit_info : 1;
+       guint            has_indirection : 1;
        gpointer         debug_info;
        guint32          lmf_offset;
     guint16          *intvars;
@@ -1620,6 +1632,10 @@ typedef struct {
        gint32 cas_linkdemand;
        gint32 cas_demand_generation;
        gint32 generic_virtual_invocations;
+       gint32 alias_found;
+       gint32 alias_removed;
+       gint32 loads_eliminated;
+       gint32 stores_eliminated;
        int methods_with_llvm;
        int methods_without_llvm;
        char *max_ratio_method;
@@ -1974,11 +1990,13 @@ gint32    mono_get_jit_tls_offset           (void) MONO_INTERNAL;
 gint32    mono_get_lmf_tls_offset           (void) MONO_INTERNAL;
 gint32    mono_get_lmf_addr_tls_offset      (void) MONO_INTERNAL;
 int       mini_get_tls_offset               (MonoTlsKey key) MONO_INTERNAL;
+gboolean  mini_tls_get_supported            (MonoCompile *cfg, MonoTlsKey key) MONO_INTERNAL;
 MonoInst* mono_create_tls_get               (MonoCompile *cfg, MonoTlsKey key) MONO_INTERNAL;
 MonoInst* mono_get_jit_tls_intrinsic        (MonoCompile *cfg) MONO_INTERNAL;
 MonoInst* mono_get_domain_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
 MonoInst* mono_get_thread_intrinsic         (MonoCompile* cfg) MONO_INTERNAL;
 MonoInst* mono_get_lmf_intrinsic            (MonoCompile* cfg) MONO_INTERNAL;
+MonoInst* mono_get_lmf_addr_intrinsic       (MonoCompile* cfg) MONO_INTERNAL;
 GList    *mono_varlist_insert_sorted        (MonoCompile *cfg, GList *list, MonoMethodVar *mv, int sort_type) MONO_INTERNAL;
 GList    *mono_varlist_sort                 (MonoCompile *cfg, GList *list, int sort_type) MONO_INTERNAL;
 void      mono_analyze_liveness             (MonoCompile *cfg) MONO_INTERNAL;
@@ -2208,6 +2226,7 @@ int               mono_method_to_ir (MonoCompile *cfg, MonoMethod *method, MonoB
 MonoInst         *mono_decompose_opcode (MonoCompile *cfg, MonoInst *ins) MONO_INTERNAL;
 void              mono_decompose_long_opts (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_decompose_vtype_opts (MonoCompile *cfg) MONO_INTERNAL;
+void              mono_decompose_vtype_opts_llvm (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_decompose_array_access_opts (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_decompose_soft_float (MonoCompile *cfg) MONO_INTERNAL;
 void              mono_handle_global_vregs (MonoCompile *cfg) MONO_INTERNAL;
@@ -2279,6 +2298,8 @@ gboolean  mono_arch_gsharedvt_sig_supported     (MonoMethodSignature *sig) MONO_
 gpointer  mono_arch_get_gsharedvt_trampoline    (MonoTrampInfo **info, gboolean aot) MONO_INTERNAL;
 gpointer  mono_arch_get_gsharedvt_call_info     (gpointer addr, MonoMethodSignature *normal_sig, MonoMethodSignature *gsharedvt_sig, MonoGenericSharingContext *gsctx, gboolean gsharedvt_in, gint32 vcall_offset, gboolean calli) MONO_INTERNAL;
 gboolean  mono_arch_opcode_needs_emulation      (MonoCompile *cfg, int opcode) MONO_INTERNAL;
+gboolean  mono_arch_tail_call_supported         (MonoMethodSignature *caller_sig, MonoMethodSignature *callee_sig) MONO_INTERNAL;
+int       mono_arch_translate_tls_offset        (int offset) MONO_INTERNAL;
 
 #ifdef MONO_ARCH_SOFT_FLOAT_FALLBACK
 gboolean  mono_arch_is_soft_float               (void) MONO_INTERNAL;
@@ -2302,6 +2323,7 @@ void     mono_arch_skip_breakpoint              (MonoContext *ctx, MonoJitInfo *
 void     mono_arch_skip_single_step             (MonoContext *ctx) MONO_INTERNAL;
 gpointer mono_arch_get_seq_point_info           (MonoDomain *domain, guint8 *code) MONO_INTERNAL;
 void     mono_arch_setup_resume_sighandler_ctx  (MonoContext *ctx, gpointer func) MONO_INTERNAL;
+void     mono_arch_init_lmf_ext                 (MonoLMFExt *ext, gpointer prev_lmf) MONO_INTERNAL;
 #endif
 
 #ifdef USE_JUMP_TABLES
@@ -2343,7 +2365,6 @@ mgreg_t mono_arch_context_get_int_reg                 (MonoContext *ctx, int reg) MONO_INTE
 void     mono_arch_context_set_int_reg             (MonoContext *ctx, int reg, mgreg_t val) MONO_INTERNAL;
 void     mono_arch_flush_register_windows       (void) MONO_INTERNAL;
 gboolean mono_arch_is_inst_imm                  (gint64 imm) MONO_INTERNAL;
-MonoInst* mono_arch_get_domain_intrinsic        (MonoCompile* cfg) MONO_INTERNAL;
 gboolean mono_arch_is_int_overflow              (void *sigctx, void *info) MONO_INTERNAL;
 void     mono_arch_invalidate_method            (MonoJitInfo *ji, void *func, gpointer func_arg) MONO_INTERNAL;
 guint32  mono_arch_get_patch_offset             (guint8 *code) MONO_INTERNAL;
@@ -2456,6 +2477,7 @@ void        mono_ssa_cprop                      (MonoCompile *cfg) MONO_INTERNAL
 void        mono_ssa_deadce                     (MonoCompile *cfg) MONO_INTERNAL;
 void        mono_ssa_strength_reduction         (MonoCompile *cfg) MONO_INTERNAL;
 void        mono_free_loop_info                 (MonoCompile *cfg) MONO_INTERNAL;
+void        mono_ssa_loop_invariant_code_motion (MonoCompile *cfg) MONO_INTERNAL;
 
 void        mono_ssa_compute2                   (MonoCompile *cfg);
 void        mono_ssa_remove2                    (MonoCompile *cfg);
@@ -2474,7 +2496,6 @@ void      mono_debug_serialize_debug_info       (MonoCompile *cfg, guint8 **out_
 void      mono_debug_add_aot_method             (MonoDomain *domain,
                                                 MonoMethod *method, guint8 *code_start, 
                                                 guint8 *debug_info, guint32 debug_info_len) MONO_INTERNAL;
-void      mono_debug_add_icall_wrapper          (MonoMethod *method, MonoJitICallInfo* info) MONO_INTERNAL;
 MONO_API void      mono_debug_print_vars                 (gpointer ip, gboolean only_arguments);
 MONO_API void      mono_debugger_run_finally             (MonoContext *start_ctx);
 
@@ -2482,16 +2503,6 @@ extern gssize mono_breakpoint_info_index [MONO_BREAKPOINT_ARRAY_SIZE];
 
 MONO_API gboolean mono_breakpoint_clean_code (guint8 *method_start, guint8 *code, int offset, guint8 *buf, int size);
 
-#ifdef MONO_DEBUGGER_SUPPORTED
-
-/* Mono Debugger support */
-void      mini_debugger_init                    (void);
-int       mini_debugger_main                    (MonoDomain *domain, MonoAssembly *assembly, int argc, char **argv);
-gboolean  mini_debug_running_inside_mdb         (void);
-void      mini_debugger_set_attach_ok           (void);
-
-#endif
-
 /* Tracing */
 MonoTraceSpec *mono_trace_parse_options         (const char *options) MONO_INTERNAL;
 void           mono_trace_set_assembly          (MonoAssembly *assembly) MONO_INTERNAL;
@@ -2509,6 +2520,8 @@ extern void
 mono_local_cprop (MonoCompile *cfg);
 extern void
 mono_local_deadce (MonoCompile *cfg);
+void
+mono_local_alias_analysis (MonoCompile *cfg) MONO_INTERNAL;
 
 /* CAS - stack walk */
 MonoSecurityFrame* ves_icall_System_Security_SecurityFrame_GetSecurityFrame (gint32 skip) MONO_INTERNAL;
@@ -2773,10 +2786,10 @@ gboolean SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_INTERNAL;
 #define ARCH_HAVE_DELEGATE_TRAMPOLINES 0
 #endif
 
-#ifdef MONO_ARCH_USE_OP_TAIL_CALL
-#define ARCH_USE_OP_TAIL_CALL 1
+#ifdef MONO_ARCH_HAVE_OP_TAIL_CALL
+#define ARCH_HAVE_OP_TAIL_CALL 1
 #else
-#define ARCH_USE_OP_TAIL_CALL 0
+#define ARCH_HAVE_OP_TAIL_CALL 0
 #endif
 
 #ifndef MONO_ARCH_HAVE_TLS_GET
@@ -2789,4 +2802,30 @@ gboolean SIG_HANDLER_SIGNATURE (mono_chain_signal) MONO_INTERNAL;
 #define ARCH_HAVE_TLS_GET_REG 0
 #endif
 
+#ifdef MONO_ARCH_EMULATE_MUL_DIV
+#define ARCH_EMULATE_MUL_DIV 1
+#else
+#define ARCH_EMULATE_MUL_DIV 0
+#endif
+
+#ifndef MONO_ARCH_MONITOR_ENTER_ADJUSTMENT
+#define MONO_ARCH_MONITOR_ENTER_ADJUSTMENT 1
+#endif
+
+#ifndef MONO_ARCH_DYN_CALL_PARAM_AREA
+#define MONO_ARCH_DYN_CALL_PARAM_AREA 0
+#endif
+
+#ifdef MONO_ARCH_HAVE_IMT
+#define ARCH_HAVE_IMT 1
+#else
+#define ARCH_HAVE_IMT 0
+#endif
+
+#ifdef MONO_ARCH_VARARG_ICALLS
+#define ARCH_VARARG_ICALLS 1
+#else
+#define ARCH_VARARG_ICALLS 0
+#endif
+
 #endif /* __MONO_MINI_H__ */
index 0e754329ae7e9bc78d7d85dc53f497d7049aa847..bee894bdc5571b11a7fe175c8f100d141e58b217 100644 (file)
@@ -26,3 +26,4 @@ OPTFLAG(GSHARED  ,25, "gshared",    "Generic Sharing")
 OPTFLAG(GSHAREDVT,24, "gsharedvt",     "Generic sharing for valuetypes")
 OPTFLAG(SIMD    ,26, "simd",       "Simd intrinsics")
 OPTFLAG(UNSAFE  ,27, "unsafe",     "Remove bound checks and perform other dangerous changes")
+OPTFLAG(ALIAS_ANALYSIS  ,28, "alias-analysis",      "Alias analysis of locals")
index a966be512bb0a9243384b868dcfc733fa9c0fec2..12c55254231904484cd34b4a7f9625e677830486 100644 (file)
@@ -50,7 +50,5 @@ PATCH_INFO(GSHAREDVT_METHOD, "gsharedvt_method")
 PATCH_INFO(JIT_TLS_ID, "jit_tls_id")
 PATCH_INFO(TLS_OFFSET, "tls_offset")
 PATCH_INFO(OBJC_SELECTOR_REF, "objc_selector_ref")
+PATCH_INFO(METHOD_CODE_SLOT, "method_code_slot")
 PATCH_INFO(NONE, "none")
-
-
-
index d58d814e11fb0685d48c275cc497a968b8ab034a..023d2778009bebb9a1002239cba36ec82a2427ee 100644 (file)
@@ -1350,4 +1350,117 @@ mono_ssa_strength_reduction (MonoCompile *cfg)
 }
 #endif
 
+void
+mono_ssa_loop_invariant_code_motion (MonoCompile *cfg)
+{
+       MonoBasicBlock *bb, *h, *idom;
+       MonoInst *ins, *n, *tins;
+       int i;
+
+       g_assert (cfg->comp_done & MONO_COMP_SSA);
+       if (!(cfg->comp_done & MONO_COMP_LOOPS) || !(cfg->comp_done & MONO_COMP_SSA_DEF_USE))
+               return;
+
+       for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) {
+               GList *lp = bb->loop_blocks;
+
+               if (!lp)
+                       continue;
+               h = (MonoBasicBlock *)lp->data;
+               if (bb != h)
+                       continue;
+               MONO_BB_FOR_EACH_INS_SAFE (bb, n, ins) {
+                       gboolean is_class_init = FALSE;
+
+                       /*
+                        * Try to move instructions out of loop headers into the preceeding bblock.
+                        */
+                       if (ins->opcode == OP_VOIDCALL) {
+                               MonoCallInst *call = (MonoCallInst*)ins;
+
+                               if (call->fptr_is_patch) {
+                                       MonoJumpInfo *ji = (MonoJumpInfo*)call->fptr;
+
+                                       if (ji->type == MONO_PATCH_INFO_CLASS_INIT)
+                                               is_class_init = TRUE;
+                               }
+                       }
+                       if (ins->opcode == OP_LDLEN || ins->opcode == OP_STRLEN || ins->opcode == OP_CHECK_THIS || ins->opcode == OP_AOTCONST || is_class_init) {
+                               gboolean skip;
+                               int sreg;
+
+                               idom = h->idom;
+                               /*
+                                * h->nesting is needed to work around:
+                                * http://llvm.org/bugs/show_bug.cgi?id=17868
+                                */
+                               if (!(idom && idom->last_ins && idom->last_ins->opcode == OP_BR && idom->last_ins->inst_target_bb == h && h->nesting == 1)) {
+                                       continue;
+                               }
+
+                               /*
+                                * Make sure there are no instructions with side effects before ins.
+                                */
+                               skip = FALSE;
+                               MONO_BB_FOR_EACH_INS (bb, tins) {
+                                       if (tins == ins)
+                                               break;
+                                       if (!MONO_INS_HAS_NO_SIDE_EFFECT (tins)) {
+                                               skip = TRUE;
+                                               break;
+                                       }
+                               }
+                               if (skip) {
+                                       /*
+                                         printf ("%s\n", mono_method_full_name (cfg->method, TRUE));
+                                         mono_print_ins (tins);
+                                       */
+                                       continue;
+                               }
+
+                               /* Make sure we don't move the instruction before the def of its sreg */
+                               if (ins->opcode == OP_LDLEN || ins->opcode == OP_STRLEN || ins->opcode == OP_CHECK_THIS)
+                                       sreg = ins->sreg1;
+                               else
+                                       sreg = -1;
+                               if (sreg != -1) {
+                                       MonoInst *tins;
+
+                                       skip = FALSE;
+                                       for (tins = ins->prev; tins; tins = tins->prev) {
+                                               const char *spec = INS_INFO (tins->opcode);
+
+                                               if (tins->opcode == OP_MOVE && tins->dreg == sreg) {
+                                                       sreg = tins->sreg1;
+                                               } if (spec [MONO_INST_DEST] != ' ' && tins->dreg == sreg) {
+                                                       skip = TRUE;
+                                                       break;
+                                               }
+                                       }
+                                       if (skip)
+                                               continue;
+                                       ins->sreg1 = sreg;
+                               }
+
+                               if (cfg->verbose_level > 1) {
+                                       printf ("licm in BB%d on ", bb->block_num);
+                                       mono_print_ins (ins);
+                               }
+                               //{ static int count = 0; count ++; printf ("%d\n", count); }
+                               MONO_REMOVE_INS (bb, ins);
+                               mono_bblock_insert_before_ins (idom, idom->last_ins, ins);
+                               if (ins->opcode == OP_LDLEN || ins->opcode == OP_STRLEN)
+                                       idom->has_array_access = TRUE;
+                       }
+               }
+       }
+
+       cfg->comp_done &=  ~MONO_COMP_SSA_DEF_USE;
+       for (i = 0; i < cfg->num_varinfo; i++) {
+               MonoMethodVar *info = MONO_VARINFO (cfg, i);
+               info->def = NULL;
+               info->uses = NULL;
+       }
+}
+
 #endif /* DISABLE_JIT */
index d94448ab5f1f11152b3e9f1fc0d8d8c4b1deb39f..6766c26a694ad7f82fb5daaf20a32cef29aa049f 100644 (file)
@@ -95,7 +95,7 @@ continuation_store (MonoContinuation *cont, int state, MonoException **e)
        }
 
        cont->lmf = lmf;
-       cont->return_ip = __builtin_return_address (0);
+       cont->return_ip = __builtin_extract_return_addr (__builtin_return_address (0));
        cont->return_sp = __builtin_frame_address (0);
 
        num_bytes = (char*)cont->top_sp - (char*)cont->return_sp;
index f67b704c362727b2e9f80e000e3fda8b85849779..551b2a2fdaf61777910edb599686a6abacf8cfd7 100644 (file)
@@ -31,6 +31,8 @@
 #  define fprintf(__ignore, ...) g_log ("mono-gc", G_LOG_LEVEL_MESSAGE, __VA_ARGS__)
 #endif
 
+#define RETURN_ADDRESS(N) (__builtin_extract_return_addr (__builtin_return_address (N)))
+
 static MonoTraceSpec trace_spec;
 
 gboolean
@@ -401,7 +403,7 @@ mono_trace_enter_method (MonoMethod *method, char *ebp)
        g_free (fname);
 
        if (!ebp) {
-               printf (") ip: %p\n", __builtin_return_address (1));
+               printf (") ip: %p\n", RETURN_ADDRESS (1));
                return;
        }       
 
@@ -411,7 +413,7 @@ mono_trace_enter_method (MonoMethod *method, char *ebp)
 
        if (method->is_inflated) {
                /* FIXME: Might be better to pass the ji itself */
-               MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), __builtin_return_address (0), NULL);
+               MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (0), NULL);
                if (ji) {
                        gsctx = mono_jit_info_get_generic_sharing_context (ji);
                        if (gsctx && (gsctx->var_is_vt || gsctx->mvar_is_vt)) {
@@ -569,7 +571,7 @@ mono_trace_leave_method (MonoMethod *method, ...)
 
        if (method->is_inflated) {
                /* FIXME: Might be better to pass the ji itself */
-               MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), __builtin_return_address (0), NULL);
+               MonoJitInfo *ji = mini_jit_info_table_find (mono_domain_get (), RETURN_ADDRESS (0), NULL);
                if (ji) {
                        gsctx = mono_jit_info_get_generic_sharing_context (ji);
                        if (gsctx && (gsctx->var_is_vt || gsctx->mvar_is_vt)) {
@@ -682,7 +684,7 @@ handle_enum:
                printf ("(unknown return type %x)", mono_method_signature (method)->ret->type);
        }
 
-       //printf (" ip: %p\n", __builtin_return_address (1));
+       //printf (" ip: %p\n", RETURN_ADDRESS (1));
        printf ("\n");
        fflush (stdout);
 }
index 2e92b35b6b8cec8aa55347d9e8e1eac20c72687f..10d5ef2f3288ee2d0d4a213d364381406196e5ef 100644 (file)
@@ -428,7 +428,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
 
        code = buf = mono_global_codeman_reserve (kMaxCodeSize);
 
-       framesize = kMaxCodeSize + sizeof (MonoLMF);
+       framesize = kMaxCodeSize + sizeof (MonoLMFTramp);
        framesize = (framesize + (MONO_ARCH_FRAME_ALIGNMENT - 1)) & ~ (MONO_ARCH_FRAME_ALIGNMENT - 1);
 
        orig_rsp_to_rbp_offset = 0;
@@ -583,7 +583,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
 
        /* Save LMF begin */
 
-       offset += sizeof (MonoLMF);
+       offset += sizeof (MonoLMFTramp);
        lmf_offset = - offset;
 
        /* Save ip */
@@ -599,23 +599,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        amd64_mov_reg_reg (code, AMD64_R11, AMD64_RSP, sizeof(mgreg_t));
        amd64_alu_reg_imm (code, X86_ADD, AMD64_R11, framesize + 16);
        amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rsp), AMD64_R11, sizeof(mgreg_t));
-       /* Save method */
-       if (tramp_type == MONO_TRAMPOLINE_JIT || tramp_type == MONO_TRAMPOLINE_JUMP) {
-               amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, arg_offset, sizeof(gpointer));
-               amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, method), AMD64_R11, sizeof(gpointer));
-       } else {
-               amd64_mov_membase_imm (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, method), 0, sizeof(gpointer));
-       }
-       /* Save callee saved regs */
-#ifdef TARGET_WIN32
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rdi), AMD64_RDI, sizeof(mgreg_t));
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rsi), AMD64_RSI, sizeof(mgreg_t));
-#endif
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, rbx), AMD64_RBX, sizeof(mgreg_t));
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r12), AMD64_R12, sizeof(mgreg_t));
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r13), AMD64_R13, sizeof(mgreg_t));
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r14), AMD64_R14, sizeof(mgreg_t));
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, r15), AMD64_R15, sizeof(mgreg_t));
+       /* Save pointer to registers */
+       amd64_lea_membase (code, AMD64_R11, AMD64_RBP, saved_regs_offset);
+       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMFTramp, regs), AMD64_R11, sizeof(mgreg_t));
 
        if (aot) {
                code = mono_arch_emit_load_aotconst (buf, code, &ji, MONO_PATCH_INFO_JIT_ICALL_ADDR, "mono_get_lmf_addr");
@@ -625,11 +611,12 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        amd64_call_reg (code, AMD64_R11);
 
        /* Save lmf_addr */
-       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), AMD64_RAX, sizeof(gpointer));
+       amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMFTramp, lmf_addr), AMD64_RAX, sizeof(gpointer));
        /* Save previous_lmf */
-       /* Set the lowest bit to 1 to signal that this LMF has the ip field set */
+       /* Set the lowest bit to signal that this LMF has the ip field set */
+       /* Set the third lowest bit to signal that this is a MonoLMFTramp structure */
        amd64_mov_reg_membase (code, AMD64_R11, AMD64_RAX, 0, sizeof(gpointer));
-       amd64_alu_reg_imm_size (code, X86_ADD, AMD64_R11, 1, sizeof(gpointer));
+       amd64_alu_reg_imm_size (code, X86_ADD, AMD64_R11, 0x5, sizeof(gpointer));
        amd64_mov_membase_reg (code, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), AMD64_R11, sizeof(gpointer));
        /* Set new lmf */
        amd64_lea_membase (code, AMD64_R11, AMD64_RBP, lmf_offset);
@@ -677,10 +664,9 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        amd64_mov_reg_membase (code, AMD64_RAX, AMD64_RBP, res_offset, sizeof(mgreg_t));        
 
        /* Restore LMF */
-
        amd64_mov_reg_membase (code, AMD64_RCX, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, previous_lmf), sizeof(gpointer));
-       amd64_alu_reg_imm_size (code, X86_SUB, AMD64_RCX, 1, sizeof(gpointer));
-       amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMF, lmf_addr), sizeof(gpointer));
+       amd64_alu_reg_imm_size (code, X86_SUB, AMD64_RCX, 0x5, sizeof(gpointer));
+       amd64_mov_reg_membase (code, AMD64_R11, AMD64_RBP, lmf_offset + G_STRUCT_OFFSET (MonoLMFTramp, lmf_addr), sizeof(gpointer));
        amd64_mov_membase_reg (code, AMD64_R11, 0, AMD64_RCX, sizeof(gpointer));
 
        /* 
index 225ef9f4e7cb10e2ad870b7c7728a11b39d72557..6e973e0e7424f90d2a4a44ceac65b6d78b4bdca9 100644 (file)
@@ -16,6 +16,7 @@
 #include <mono/metadata/marshal.h>
 #include <mono/metadata/tabledefs.h>
 #include <mono/arch/arm/arm-codegen.h>
+#include <mono/arch/arm/arm-vfp-codegen.h>
 
 #include "mini.h"
 #include "mini-arm.h"
@@ -173,7 +174,7 @@ emit_bx (guint8* code, int reg)
        return code;
 }
 
-/* Stack size for trampoline function 
+/* Stack size for trampoline function
  */
 #define STACK ALIGN_TO (sizeof (MonoLMF), 8)
 
@@ -195,7 +196,7 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        gpointer *constants;
 #endif
 
-       int cfa_offset, lmf_offset, regsave_size, lr_offset;
+       int cfa_offset, regsave_size, lr_offset;
        GSList *unwind_ops = NULL;
        MonoJumpInfo *ji = NULL;
        int buf_len;
@@ -207,7 +208,12 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        /* Now we'll create in 'buf' the ARM trampoline code. This
         is the trampoline code common to all methods  */
 
-       buf_len = 212;
+       buf_len = 272;
+
+       /* Add space for saving/restoring VFP regs. */
+       if (mono_arm_is_hard_float ())
+               buf_len += 8 * 2;
+
        code = buf = mono_global_codeman_reserve (buf_len);
 
        /*
@@ -216,8 +222,6 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
         * saved as sp + LR_OFFSET by the push in the specific trampoline
         */
 
-       /* The offset of lmf inside the stack frame */
-       lmf_offset = STACK - sizeof (MonoLMF);
        /* The size of the area already allocated by the push in the specific trampoline */
        regsave_size = 14 * sizeof (mgreg_t);
        /* The offset where lr was saved inside the regsave area */
@@ -282,11 +286,13 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
         * The pointer to the struct is put in r1.
         * the iregs array is already allocated on the stack by push.
         */
-       ARM_SUB_REG_IMM8 (code, ARMREG_SP, ARMREG_SP, STACK - regsave_size);
+       code = mono_arm_emit_load_imm (code, ARMREG_R2, STACK - regsave_size);
+       ARM_SUB_REG_REG (code, ARMREG_SP, ARMREG_SP, ARMREG_R2);
        cfa_offset += STACK - regsave_size;
        mono_add_unwind_op_def_cfa_offset (unwind_ops, code, buf, cfa_offset);
        /* V1 == lmf */
-       ARM_ADD_REG_IMM8 (code, ARMREG_V1, ARMREG_SP, STACK - sizeof (MonoLMF));
+       code = mono_arm_emit_load_imm (code, ARMREG_R2, STACK - sizeof (MonoLMF));
+       ARM_ADD_REG_REG (code, ARMREG_V1, ARMREG_SP, ARMREG_R2);
 
        /*
         * The stack now looks like:
@@ -310,7 +316,8 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
                ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, method));
        }
        /* save caller SP */
-       ARM_ADD_REG_IMM8 (code, ARMREG_R2, ARMREG_SP, cfa_offset);
+       code = mono_arm_emit_load_imm (code, ARMREG_R2, cfa_offset);
+       ARM_ADD_REG_REG (code, ARMREG_R2, ARMREG_SP, ARMREG_R2);
        ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, sp));
        /* save caller FP */
        ARM_LDR_IMM (code, ARMREG_R2, ARMREG_V1, (G_STRUCT_OFFSET (MonoLMF, iregs) + ARMREG_FP*4));
@@ -323,11 +330,22 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        }
        ARM_STR_IMM (code, ARMREG_R2, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, ip));
 
+       /* Save VFP registers. */
+       if (mono_arm_is_hard_float ()) {
+               /*
+                * Strictly speaking, we don't have to save d0-d7 in the LMF, but
+                * it's easier than attempting to store them on the stack since
+                * this trampoline code is pretty messy.
+                */
+               ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, fregs));
+               ARM_FSTMD (code, ARM_VFP_D0, 8, ARMREG_R0);
+       }
+
        /*
         * Now we're ready to call xxx_trampoline ().
         */
        /* Arg 1: the saved registers */
-       ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, iregs));
+       ARM_ADD_REG_IMM (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, iregs), 0);
 
        /* Arg 2: code (next address to the instruction that called us) */
        if (tramp_type == MONO_TRAMPOLINE_JUMP) {
@@ -407,6 +425,12 @@ mono_arch_create_generic_trampoline (MonoTrampolineType tramp_type, MonoTrampInf
        /* *(lmf_addr) = previous_lmf */
        ARM_STR_IMM (code, ARMREG_IP, ARMREG_LR, G_STRUCT_OFFSET (MonoLMF, previous_lmf));
 
+       /* Restore VFP registers. */
+       if (mono_arm_is_hard_float ()) {
+               ARM_ADD_REG_IMM8 (code, ARMREG_R0, ARMREG_V1, G_STRUCT_OFFSET (MonoLMF, fregs));
+               ARM_FLDMD (code, ARM_VFP_D0, 8, ARMREG_R0);
+       }
+
        /* Non-standard function epilogue. Instead of doing a proper
         * return, we just jump to the compiled code.
         */
index 671b90a493748c4fe46ac03414ee88de1152d5be..7cec84281ebd8c12065fb0b56256d0156647873b 100644 (file)
@@ -22,6 +22,7 @@
 #include "mini.h"
 #include "mini-ppc.h"
 
+#if 0
 /* Same as mono_create_ftnptr, but doesn't require a domain */
 static gpointer
 mono_ppc_create_ftnptr (guint8 *code)
@@ -38,6 +39,7 @@ mono_ppc_create_ftnptr (guint8 *code)
        return code;
 #endif
 }
+#endif
 
 /*
  * Return the instruction to jump from code to target, 0 if not
index fe25878f14756bb2b14c4a65d32c84fcfd6e0786..0888809884a7aaa6c42ea2528a80695a187ea583 100644 (file)
@@ -191,6 +191,32 @@ mono_arch_nullify_class_init_trampoline (guint8 *code, mgreg_t *regs)
 
 /*========================= End of Function ========================*/
 
+/*------------------------------------------------------------------*/
+/*                                                                  */
+/* Name                - mono_arch_get_nullified_class_init                */
+/*                                                                  */
+/* Function    - Nullify a PLT entry call.                         */
+/*                                                                  */
+/*------------------------------------------------------------------*/
+
+gpointer
+mono_arch_get_nullified_class_init_trampoline (MonoTrampInfo **info)
+{
+       guint8 *buf, *code;
+
+       code = buf = mono_global_codeman_reserve (16);
+
+       s390_br (code, s390_r14);
+
+       if (info)
+               *info = mono_tramp_info_create ("nullified_class_init_trampoline", 
+                                               buf, code - buf, NULL, NULL);
+
+       return (buf);
+}
+
+/*========================= End of Function ========================*/
+
 /*------------------------------------------------------------------*/
 /*                                                                  */
 /* Name                - mono_arch_nullify_plt_entry                       */
index 2377e0dd009b5e970a01d2732dc2584f943e4458..018ad903e40307776f205a93c9962bc66d260e4b 100644 (file)
@@ -31,6 +31,8 @@ typedef struct {
        guint8 info [MONO_ZERO_LEN_ARRAY];
 } MonoUnwindInfo;
 
+#define ALIGN_TO(val,align) ((((size_t)val) + ((align) - 1)) & ~((align) - 1))
+
 static CRITICAL_SECTION unwind_mutex;
 
 static MonoUnwindInfo **cached_info;
@@ -49,8 +51,9 @@ static int map_hw_reg_to_dwarf_reg [] = { 0, 2, 1, 3, 7, 6, 4, 5, 8, 9, 10, 11,
 #define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (AMD64_RIP))
 #elif defined(TARGET_ARM)
 // http://infocenter.arm.com/help/topic/com.arm.doc.ihi0040a/IHI0040A_aadwarf.pdf
-static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 };
-#define NUM_REGS 16
+/* Assign d8..d15 to hregs 16..24 */
+static int map_hw_reg_to_dwarf_reg [] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 264, 265, 266, 267, 268, 269, 270, 271 };
+#define NUM_REGS 272
 #define DWARF_DATA_ALIGN (-4)
 #define DWARF_PC_REG (mono_hw_reg_to_dwarf_reg (ARMREG_LR))
 #elif defined (TARGET_X86)
@@ -248,6 +251,68 @@ decode_sleb128 (guint8 *buf, guint8 **endbuf)
        return res;
 }
 
+void
+mono_print_unwind_info (guint8 *unwind_info, int unwind_info_len)
+{
+       guint8 *p;
+       int pos, reg, offset, cfa_reg, cfa_offset;
+
+       p = unwind_info;
+       pos = 0;
+       while (p < unwind_info + unwind_info_len) {
+               int op = *p & 0xc0;
+
+               switch (op) {
+               case DW_CFA_advance_loc:
+                       pos += *p & 0x3f;
+                       p ++;
+                       break;
+               case DW_CFA_offset:
+                       reg = *p & 0x3f;
+                       p ++;
+                       offset = decode_uleb128 (p, &p) * DWARF_DATA_ALIGN;
+                       if (reg == DWARF_PC_REG)
+                               printf ("CFA: [%x] offset: %s at cfa-0x%x\n", pos, "pc", -offset);
+                       else
+                               printf ("CFA: [%x] offset: %s at cfa-0x%x\n", pos, mono_arch_regname (mono_dwarf_reg_to_hw_reg (reg)), -offset);
+                       break;
+               case 0: {
+                       int ext_op = *p;
+                       p ++;
+                       switch (ext_op) {
+                       case DW_CFA_def_cfa:
+                               cfa_reg = decode_uleb128 (p, &p);
+                               cfa_offset = decode_uleb128 (p, &p);
+                               printf ("CFA: [%x] def_cfa: %s+0x%x\n", pos, mono_arch_regname (mono_dwarf_reg_to_hw_reg (cfa_reg)), cfa_offset);
+                               break;
+                       case DW_CFA_def_cfa_offset:
+                               cfa_offset = decode_uleb128 (p, &p);
+                               printf ("CFA: [%x] def_cfa_offset: 0x%x\n", pos, cfa_offset);
+                               break;
+                       case DW_CFA_def_cfa_register:
+                               cfa_reg = decode_uleb128 (p, &p);
+                               printf ("CFA: [%x] def_cfa_reg: %s\n", pos, mono_arch_regname (mono_dwarf_reg_to_hw_reg (cfa_reg)));
+                               break;
+                       case DW_CFA_offset_extended_sf:
+                               reg = decode_uleb128 (p, &p);
+                               offset = decode_sleb128 (p, &p) * DWARF_DATA_ALIGN;
+                               printf ("CFA: [%x] offset_extended_sf: %s at cfa-0x%x\n", pos, mono_arch_regname (mono_dwarf_reg_to_hw_reg (reg)), -offset);
+                               break;
+                       case DW_CFA_advance_loc4:
+                               pos += read32 (p);
+                               p += 4;
+                               break;
+                       default:
+                               g_assert_not_reached ();
+                       }
+                       break;
+               }
+               default:
+                       g_assert_not_reached ();
+               }
+       }
+}
+
 /*
  * mono_unwind_ops_encode:
  *
@@ -330,14 +395,14 @@ mono_unwind_ops_encode (GSList *unwind_ops, guint32 *out_len)
 #endif
 
 static G_GNUC_UNUSED void
-print_dwarf_state (int cfa_reg, int cfa_offset, int ip, int nregs, Loc *locations)
+print_dwarf_state (int cfa_reg, int cfa_offset, int ip, int nregs, Loc *locations, guint8 *reg_saved)
 {
        int i;
 
        printf ("\t%x: cfa=r%d+%d ", ip, cfa_reg, cfa_offset);
 
        for (i = 0; i < nregs; ++i)
-               if (locations [i].loc_type == LOC_OFFSET)
+               if (reg_saved [i] && locations [i].loc_type == LOC_OFFSET)
                        printf ("r%d@%d(cfa) ", i, locations [i].offset);
        printf ("\n");
 }
@@ -358,12 +423,12 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                                   guint8 **out_cfa)
 {
        Loc locations [NUM_REGS];
-       int i, pos, reg, cfa_reg, cfa_offset;
+       guint8 reg_saved [NUM_REGS];
+       int i, pos, reg, cfa_reg, cfa_offset, offset;
        guint8 *p;
        guint8 *cfa_val;
 
-       for (i = 0; i < NUM_REGS; ++i)
-               locations [i].loc_type = LOC_SAME;
+       memset (reg_saved, 0, sizeof (reg_saved));
 
        p = unwind_info;
        pos = 0;
@@ -381,6 +446,7 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                case DW_CFA_offset:
                        reg = *p & 0x3f;
                        p ++;
+                       reg_saved [reg] = TRUE;
                        locations [reg].loc_type = LOC_OFFSET;
                        locations [reg].offset = decode_uleb128 (p, &p) * DWARF_DATA_ALIGN;
                        break;
@@ -400,8 +466,19 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
                                break;
                        case DW_CFA_offset_extended_sf:
                                reg = decode_uleb128 (p, &p);
+                               offset = decode_sleb128 (p, &p);
+                               g_assert (reg < NUM_REGS);
+                               reg_saved [reg] = TRUE;
                                locations [reg].loc_type = LOC_OFFSET;
-                               locations [reg].offset = decode_sleb128 (p, &p) * DWARF_DATA_ALIGN;
+                               locations [reg].offset = offset * DWARF_DATA_ALIGN;
+                               break;
+                       case DW_CFA_offset_extended:
+                               reg = decode_uleb128 (p, &p);
+                               offset = decode_uleb128 (p, &p);
+                               g_assert (reg < NUM_REGS);
+                               reg_saved [reg] = TRUE;
+                               locations [reg].loc_type = LOC_OFFSET;
+                               locations [reg].offset = offset * DWARF_DATA_ALIGN;
                                break;
                        case DW_CFA_advance_loc4:
                                pos += read32 (p);
@@ -422,7 +499,7 @@ mono_unwind_frame (guint8 *unwind_info, guint32 unwind_info_len,
 
        cfa_val = (guint8*)regs [mono_dwarf_reg_to_hw_reg (cfa_reg)] + cfa_offset;
        for (i = 0; i < NUM_REGS; ++i) {
-               if (locations [i].loc_type == LOC_OFFSET) {
+               if (reg_saved [i] && locations [i].loc_type == LOC_OFFSET) {
                        int hreg = mono_dwarf_reg_to_hw_reg (i);
                        g_assert (hreg < nregs);
                        regs [hreg] = *(mgreg_t*)(cfa_val + locations [i].offset);
@@ -647,33 +724,27 @@ read_encoded_val (guint32 encoding, guint8 *p, guint8 **endp)
 /*
  * decode_lsda:
  *
- *   Decode the Language Specific Data Area generated by LLVM.
+ *   Decode the Mono specific Language Specific Data Area generated by LLVM.
  */
 static void
 decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32 *ex_info_len, gpointer **type_info, int *this_reg, int *this_offset)
 {
-       gint32 ttype_offset, call_site_length;
-       gint32 ttype_encoding, call_site_encoding;
-       guint8 *ttype, *action_table, *call_site, *p;
-       int i, ncall_sites;
+       guint8 *p;
+       int i, ncall_sites, this_encoding;
+       guint32 mono_magic, version;
 
-       /*
-        * LLVM generates a c++ style LSDA, which can be decoded by looking at
-        * eh_personality.cc in gcc.
-        */
        p = lsda;
 
-       if (*p == DW_EH_PE_udata4) {
-               /* This is the modified LSDA generated by the LLVM mono branch */
-               guint32 mono_magic, version;
+       /* This is the modified LSDA generated by the LLVM mono branch */
+       mono_magic = decode_uleb128 (p, &p);
+       g_assert (mono_magic == 0x4d4fef4f);
+       version = decode_uleb128 (p, &p);
+       g_assert (version == 1);
+       this_encoding = *p;
+       p ++;
+       if (this_encoding == DW_EH_PE_udata4) {
                gint32 op, reg, offset;
 
-               p ++;
-               mono_magic = decode_uleb128 (p, &p);
-               g_assert (mono_magic == 0x4d4fef4f);
-               version = decode_uleb128 (p, &p);
-               g_assert (version == 1);
-
                /* 'this' location */
                op = *p;
                g_assert (op == DW_OP_bregx);
@@ -684,61 +755,24 @@ decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32
                *this_reg = mono_dwarf_reg_to_hw_reg (reg);
                *this_offset = offset;
        } else {
-               /* Read @LPStart */
-               g_assert (*p == DW_EH_PE_omit);
-               p ++;
+               g_assert (this_encoding == DW_EH_PE_omit);
 
                *this_reg = -1;
                *this_offset = -1;
        }
-
-       /* Read @TType */
-       ttype_encoding = *p;
-       p ++;
-       ttype_offset = decode_uleb128 (p, &p);
-       ttype = p + ttype_offset;
-
-       /* Read call-site table */
-       call_site_encoding = *p;
-       g_assert (call_site_encoding == DW_EH_PE_udata4);
-       p ++;
-       call_site_length = decode_uleb128 (p, &p);
-       call_site = p;
-       p += call_site_length;
-       action_table = p;
-
-       /* Calculate the size of our table */
-       ncall_sites = 0;
-       p = call_site;
-       while (p < action_table) {
-               int block_start_offset, block_size, landing_pad, action_offset;
-
-               block_start_offset = read32 (p);
-               p += sizeof (gint32);
-               block_size = read32 (p);
-               p += sizeof (gint32);
-               landing_pad = read32 (p);
-               p += sizeof (gint32);
-               action_offset = decode_uleb128 (p, &p);
-
-               /* landing_pad == 0 means the region has no landing pad */
-               if (landing_pad)
-                       ncall_sites ++;
-       }
+       ncall_sites = decode_uleb128 (p, &p);
+       p = (guint8*)ALIGN_TO ((mgreg_t)p, 4);
 
        if (ex_info) {
                *ex_info = g_malloc0 (ncall_sites * sizeof (MonoJitExceptionInfo));
                *ex_info_len = ncall_sites;
        }
-
        if (type_info)
                *type_info = g_malloc0 (ncall_sites * sizeof (gpointer));
 
-       p = call_site;
-       i = 0;
-       while (p < action_table) {
-               int block_start_offset, block_size, landing_pad, action_offset, type_offset;
-               guint8 *action, *tinfo;
+       for (i = 0; i < ncall_sites; ++i) {
+               int block_start_offset, block_size, landing_pad;
+               guint8 *tinfo;
 
                block_start_offset = read32 (p);
                p += sizeof (gint32);
@@ -746,49 +780,19 @@ decode_lsda (guint8 *lsda, guint8 *code, MonoJitExceptionInfo **ex_info, guint32
                p += sizeof (gint32);
                landing_pad = read32 (p);
                p += sizeof (gint32);
-               action_offset = decode_uleb128 (p, &p);
-
-               if (!action_offset)
-                       continue;
-
-               action = action_table + action_offset - 1;
-
-               type_offset = decode_sleb128 (action, &action);
-
-               if (landing_pad) {
-                       //printf ("BLOCK: %p-%p %p, %d\n", code + block_start_offset, code + block_start_offset + block_size, code + landing_pad, action_offset);
-
-                       g_assert (ttype_offset);
-
-                       if (ttype_encoding == DW_EH_PE_absptr) {
-                               guint8 *ttype_entry = (ttype - (type_offset * sizeof (gpointer)));
-                               tinfo = *(gpointer*)ttype_entry;
-                       } else if (ttype_encoding == (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4)) {
-                               guint8 *ttype_entry = (ttype - (type_offset * 4));
-                               gint32 offset = *(gint32*)ttype_entry;
-                               guint8 *stub = ttype_entry + offset;
-                               tinfo = *(gpointer*)stub;
-                       } else if (ttype_encoding == (DW_EH_PE_pcrel | DW_EH_PE_sdata4)) {
-                               guint8 *ttype_entry = (ttype - (type_offset * 4));
-                               gint32 offset = *(gint32*)ttype_entry;
-                               tinfo = ttype_entry + offset;
-                       } else if (ttype_encoding == DW_EH_PE_udata4) {
-                               /* Embedded directly */
-                               guint8 *ttype_entry = (ttype - (type_offset * 4));
-                               tinfo = ttype_entry;
-                       } else {
-                               g_assert_not_reached ();
-                       }
+               tinfo = p;
+               p += sizeof (gint32);
 
-                       if (ex_info) {
-                               if (*type_info)
-                                       (*type_info) [i] = tinfo;
-                               (*ex_info)[i].try_start = code + block_start_offset;
-                               (*ex_info)[i].try_end = code + block_start_offset + block_size;
-                               (*ex_info)[i].handler_start = code + landing_pad;
+               g_assert (landing_pad);
+               g_assert (((size_t)tinfo % 4) == 0);
+               //printf ("X: %p %d\n", landing_pad, *(int*)tinfo);
 
-                       }
-                       i ++;
+               if (ex_info) {
+                       if (*type_info)
+                               (*type_info) [i] = tinfo;
+                       (*ex_info)[i].try_start = code + block_start_offset;
+                       (*ex_info)[i].try_end = code + block_start_offset + block_size;
+                       (*ex_info)[i].handler_start = code + landing_pad;
                }
        }
 }
index 64fe072e9a09d9c1623d585fbaf01994761a3c37..585b5641829af3d4668b8035161874947dca3cea 100644 (file)
@@ -24,10 +24,17 @@ else
 runtime_lib=../interpreter/libmint.la
 endif
 
+if DISABLE_EXECUTABLES
+bin_PROGRAMS =
+else
 if DISABLE_LIBRARIES
+bin_PROGRAMS =
 else
+if SUPPORT_BOEHM
 bin_PROGRAMS = monograph
 endif
+endif
+endif
 
 AM_CPPFLAGS =                          \
        -I$(top_srcdir)                 \
index f11a1dcdeffd2ce3eb23d16d088a431977b999aa..29489ad49467e599b7a27a9431597fa484d858e3 100644 (file)
@@ -2,10 +2,13 @@ using System;
 using System.Threading;
 
 public class FinalizerException {
+
        ~FinalizerException () {
                throw new Exception ();
        }
 
+       static IntPtr aptr;
+
        /*
         * We allocate the exception object deep down the stack so
         * that it doesn't get pinned.
@@ -13,6 +16,7 @@ public class FinalizerException {
        public static unsafe void MakeException (int depth) {
                // Avoid tail calls
                int* values = stackalloc int [20];
+               aptr = new IntPtr (values);
                if (depth <= 0) {
                        new FinalizerException ();
                        return;
index 95f2fa0c10ddbce76342c6176dd4f38130bcecbc..21e47bb648e63763af716ff83c8028c10b6ff68b 100644 (file)
@@ -108,7 +108,8 @@ monoutils_sources = \
        mono-hwcap.h    \
        mono-hwcap.c    \
        bsearch.h       \
-       bsearch.c
+       bsearch.c       \
+       mono-signal-handler.h
 
 arch_sources = 
 
index eb5fd603514ef8a6d9c716858ad6d3dc9255d58c..5f242752ef75d6e211a390373268f94e92bc4bb2 100644 (file)
 #include "utils/mono-compiler.h"
 #include "mach-support.h"
 
+/* _mcontext.h now defines __darwin_mcontext32, not __darwin_mcontext, starting with Xcode 5.1 */
+#ifdef _STRUCT_MCONTEXT32
+       #define __darwin_mcontext       __darwin_mcontext32
+#endif
+
 /* Known offsets used for TLS storage*/
 
 
index 2be0b023c90f8efc4d520d39431175eeb2f3025b..01816d8c93a702e0e73fcbd333fc7a440fcf9181 100644 (file)
@@ -35,6 +35,8 @@ gboolean mono_hwcap_arm_is_v6 = FALSE;
 gboolean mono_hwcap_arm_is_v7 = FALSE;
 gboolean mono_hwcap_arm_is_v7s = 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;
 
@@ -60,6 +62,14 @@ mono_hwcap_arch_init (void)
                if (hwcap & 0x00000040)
                        mono_hwcap_arm_has_vfp = TRUE;
 
+               /* HWCAP_ARM_VFPv3 */
+               if (hwcap & 0x00002000)
+                       mono_hwcap_arm_has_vfp3 = TRUE;
+
+               /* HWCAP_ARM_VFPv3D16 */
+               if (hwcap & 0x00004000)
+                       mono_hwcap_arm_has_vfp3_d16 = TRUE;
+
                /* TODO: Find a way to detect Thumb 2. */
        }
 
@@ -136,6 +146,12 @@ mono_hwcap_arch_init (void)
                                if (strstr (line, "vfp"))
                                        mono_hwcap_arm_has_vfp = TRUE;
 
+                               if (strstr (line, "vfpv3"))
+                                       mono_hwcap_arm_has_vfp3 = TRUE;
+
+                               if (strstr (line, "vfpv3-d16"))
+                                       mono_hwcap_arm_has_vfp3_d16 = TRUE;
+
                                continue;
                        }
                }
@@ -154,6 +170,8 @@ mono_hwcap_print(FILE *f)
        g_fprintf (f, "mono_hwcap_arm_is_v7 = %i\n", mono_hwcap_arm_is_v7);
        g_fprintf (f, "mono_hwcap_arm_is_v7s = %i\n", mono_hwcap_arm_is_v7s);
        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);
 }
index 6bc9c3b907ad6fd8332a3e04b3411ac6ba9ff7c0..76a20a1f53dd25c7db77a447c3fd91918251be4a 100644 (file)
@@ -8,6 +8,8 @@ extern gboolean mono_hwcap_arm_is_v6;
 extern gboolean mono_hwcap_arm_is_v7;
 extern gboolean mono_hwcap_arm_is_v7s;
 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;
 
index 01b8c1bb50c6f8b1098c1764758f5b5aac28c48e..5bd290f75ef1906e73edc4b4feda9b61be8ef09c 100644 (file)
@@ -561,7 +561,7 @@ get_cpu_times (int cpu_id, gint64 *user, gint64 *systemt, gint64 *irq, gint64 *s
        char buf [256];
        char *s;
        int hz = get_user_hz ();
-       guint64 user_ticks, nice_ticks, system_ticks, idle_ticks, iowait_ticks, irq_ticks, sirq_ticks;
+       guint64 user_ticks = 0, nice_ticks = 0, system_ticks = 0, idle_ticks = 0, iowait_ticks, irq_ticks = 0, sirq_ticks = 0;
        FILE *f = fopen ("/proc/stat", "r");
        if (!f)
                return;
index e3160eff1f4d486a60fe4bf33b33b88ee9dfdc90..15f6451100760906ba579e1eb40ffaa47bd417c2 100644 (file)
@@ -177,7 +177,23 @@ unregister_thread (void *arg)
        mono_native_tls_set_value (small_id_key, GUINT_TO_POINTER (info->small_id + 1));
 
        info->thread_state = STATE_SHUTTING_DOWN;
+
+       /*
+       First perform the callback that requires no locks.
+       This callback has the potential of taking other locks, so we do it before.
+       After it completes, the thread remains functional.
+       */
+       if (threads_callbacks.thread_detach)
+               threads_callbacks.thread_detach (info);
+
        mono_thread_info_suspend_lock ();
+
+       /*
+       Now perform the callback that must be done under locks.
+       This will render the thread useless and non-suspendable, so it must
+       be done while holding the suspend lock to give no other thread chance
+       to suspend it.
+       */
        if (threads_callbacks.thread_unregister)
                threads_callbacks.thread_unregister (info);
        mono_threads_unregister_current_thread (info);
index 08583a064a0ff90fce07be22dfaa43be900e482d..d06aea6e724569010f8d649c0933d7de97046a00 100644 (file)
@@ -137,10 +137,19 @@ typedef struct {
 typedef struct {
        void* (*thread_register)(THREAD_INFO_TYPE *info, void *baseaddr);
        /*
-       This callback is called after @info is removed from the thread list.
+       This callback is called with @info still on the thread list.
+       This call is made while holding the suspend lock, so don't do callbacks.
        SMR remains functional as its small_id has not been reclaimed.
        */
        void (*thread_unregister)(THREAD_INFO_TYPE *info);
+       /*
+       This callback is called right before thread_unregister. This is called
+       without any locks held so it's the place for complicated cleanup.
+
+       The thread must remain operational between this call and thread_unregister.
+       It must be possible to successfully suspend it after thread_unregister completes.
+       */
+       void (*thread_detach)(THREAD_INFO_TYPE *info);
        void (*thread_attach)(THREAD_INFO_TYPE *info);
        gboolean (*mono_method_is_critical) (void *method);
 #ifndef HOST_WIN32
index 890f0782d57b45ab33385e1f64204c39b3bc7577..007dc4e6d225bd81336071a0fcda25750b5b8091 100644 (file)
@@ -4,6 +4,8 @@
  * Copyright 2013 Xamarin, Inc (http://www.xamarin.com)
  */
 
+#include <config.h>
+
 #include "mono-tls.h"
 
 static int tls_offsets [TLS_KEY_NUM];
index ceb0619d28c0c57f4444ea45b25c7e6720a77346..b647427902e8b1d0746df6689fd54e63401f1300 100644 (file)
@@ -36,6 +36,7 @@
   </ItemGroup>\r
   <Import Project="mono.props" />\r
   <ItemGroup>\r
+    <ClCompile Include="..\mono\mini\alias-analysis.c" />\r
     <ClCompile Include="..\mono\mini\exceptions-amd64.c">\r
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>\r
       <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug_SGen|Win32'">true</ExcludedFromBuild>\r
     <ClCompile Include="..\mono\mini\local-propagation.c" />\r
     <ClCompile Include="..\mono\mini\driver.c" />\r
     <ClCompile Include="..\mono\mini\debug-mini.c" />\r
-    <ClInclude Include="..\mono\mini\debug-mini.h" />\r
     <ClCompile Include="..\mono\mini\linear-scan.c" />\r
     <ClCompile Include="..\mono\mini\aot-compiler.c" />\r
     <ClCompile Include="..\mono\mini\aot-runtime.c" />\r
     <ClCompile Include="..\mono\mini\mini-gc.c" />\r
     <ClInclude Include="..\mono\mini\debugger-agent.h " />\r
     <ClCompile Include="..\mono\mini\debugger-agent.c" />\r
-    <ClCompile Include="..\mono\mini\debug-debugger.c" />\r
-    <ClInclude Include="..\mono\mini\debug-debugger.h" />\r
     <ClCompile Include="..\mono\mini\xdebug.c" />\r
     <ClInclude Include="..\mono\mini\mini-llvm.h" />\r
     <ClInclude Include="..\mono\mini\mini-llvm-cpp.h" />\r
index 3ad4ff659156c03dce78025f41c2b2fec53d48b0..8f2e480d9516d45a9ca0fec8e0048d14699de638 100644 (file)
@@ -52,6 +52,7 @@
     <ClCompile Include="..\mono\metadata\exception.c" />\r
     <ClCompile Include="..\mono\metadata\file-io.c" />\r
     <ClCompile Include="..\mono\metadata\filewatcher.c" />\r
+    <ClCompile Include="..\mono\metadata\gc-memfuncs.c" />\r
     <ClCompile Include="..\mono\metadata\gc.c" />\r
     <ClCompile Include="..\mono\metadata\icall.c" />\r
     <ClCompile Include="..\mono\metadata\image.c" />\r
index 8c3ef282414391c568927e6c54bb370b7b0c2130..e2c5ea539050dbcc71051567f4ac989b5f720e75 100644 (file)
@@ -57,6 +57,7 @@
     <ClCompile Include="..\mono\utils\mono-threads-windows.c" />\r
     <ClCompile Include="..\mono\utils\mono-threads.c" />\r
     <ClCompile Include="..\mono\utils\mono-time.c" />\r
+    <ClCompile Include="..\mono\utils\mono-tls.c" />\r
     <ClCompile Include="..\mono\utils\mono-uri.c" />\r
     <ClCompile Include="..\mono\utils\mono-value-hash.c" />\r
     <ClCompile Include="..\mono\utils\monobitset.c" />\r
index 4aefd7cc94365f129466085043ee72101054524f..f03d93a8366fb4dbc91f2a7d5eab6877cbe99c72 100644 (file)
@@ -65,6 +65,12 @@ namespace Mono.Tools.LocaleBuilder
 
                public bool HasMissingLocale { get; set; }
 
+               public bool IsNeutral {
+                       get {
+                               return Territory == null;
+                       }
+               }
+
                public string OriginalName { get; set; }
 
                public CultureInfoEntry Parent { get; set; }
index 16368ce288f292eeb27107411d3be8bf897762d2..4d0383a36208f38b19aa8ab0a58d1dbbcee8bb53 100644 (file)
@@ -429,11 +429,6 @@ namespace Mono.Tools.LocaleBuilder
                                        ci.DateTimeFormatEntry.CalendarWeekRule = (int) rule;
                                }
 
-                               string fraction_value;
-                               if (currency_fractions.TryGetValue (ci.Territory, out fraction_value)) {
-                                       ci.NumberFormatEntry.CurrencyDecimalDigits = fraction_value;
-                               }
-
                                RegionInfoEntry region = regions.Where (l => l.Name == ci.Territory).FirstOrDefault ();
                                if (region == null) {
                                        region = new RegionInfoEntry () {
@@ -466,6 +461,11 @@ namespace Mono.Tools.LocaleBuilder
                                        regions.Add (region);
                                }
 
+                               string fraction_value;
+                               if (currency_fractions.TryGetValue (region.ISOCurrencySymbol, out fraction_value)) {
+                                       ci.NumberFormatEntry.CurrencyDecimalDigits = fraction_value;
+                               }
+
                                ci.RegionInfoEntry = region;
                        }
 
@@ -587,7 +587,7 @@ namespace Mono.Tools.LocaleBuilder
                                        case "zh-Hant":
                                                nfe.CurrencySymbol = "HK$";
                                                break;
-                                               
+
                                        default:
                                                var all_currencies = new List<string> ();
                                                GetAllChildrenValues (ci, all_currencies, l => l.NumberFormatEntry.CurrencySymbol);
@@ -621,6 +621,8 @@ namespace Mono.Tools.LocaleBuilder
                                                if (!ci.HasMissingLocale)
                                                        Console.WriteLine ("No currency decimal digits data for `{0}'", ci.Name);
 
+                                               nfe.CurrencyDecimalDigits = "2";
+                                       } else if (ci.IsNeutral) {
                                                nfe.CurrencyDecimalDigits = "2";
                                        } else {
                                                // .NET has weird concept of territory data available for neutral cultures (e.g. en, es, pt)
@@ -1073,8 +1075,7 @@ namespace Mono.Tools.LocaleBuilder
                                el = node.SelectSingleNode ("decimal");
                                if (el != null) {
                                        ni.NumberDecimalSeparator =
-                                       ni.PercentDecimalSeparator =
-                                       ni.CurrencyDecimalSeparator = el.InnerText;
+                                       ni.PercentDecimalSeparator = el.InnerText;
                                }
 
                                el = node.SelectSingleNode ("plusSign");
index f50d85d7e9bada616567394c0ff8c043ff0355fc..bbe19f5bc7ef73d72f0916dfd1e22e9edc0f051a 100644 (file)
@@ -1159,358 +1159,357 @@ namespace Mono.Tools.LocaleBuilder
                };
 
                static readonly Dictionary<int, string[]> Numbers = new Dictionary<int, string[]> {
-                       { 0x0001, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x0002, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0003, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0004, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x0005, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0006, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0007, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0008, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0009, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x000a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x000b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x000c, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x000d, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x000e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x000f, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0010, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0011, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0012, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x0013, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0014, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0015, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0016, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0017, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x0018, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0019, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x001a, new [] { "8", "3", "2", "1", "1" } },
-                       { 0x001b, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x001c, new [] { "5", "1", "1", "0", "0" } },
-                       { 0x001d, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x001e, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x001f, new [] { "8", "3", "1", "2", "2" } },
-                       { 0x0020, new [] { "3", "0", "1", "0", "0" } },
-                       { 0x0021, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0022, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x0023, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0024, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0025, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0026, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0027, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0028, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0029, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x002a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x002b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x002c, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x002d, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x002e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x002f, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0032, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x0034, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x0035, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x0036, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x0037, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0038, new [] { "12", "2", "1", "1", "1" } },
-                       { 0x0039, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x003a, new [] { "1", "0", "1", "2", "2" } },
-                       { 0x003b, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x003c, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x003e, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x003f, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0040, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0041, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0042, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x0043, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0044, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0045, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x0046, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0047, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0048, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0049, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x004a, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x004b, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x004c, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x004d, new [] { "12", "1", "1", "1", "1" } },
-                       { 0x004e, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x004f, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0050, new [] { "5", "1", "1", "0", "0" } },
-                       { 0x0051, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x0052, new [] { "1", "0", "1", "2", "2" } },
-                       { 0x0053, new [] { "5", "1", "2", "1", "1" } },
-                       { 0x0054, new [] { "4", "1", "0", "0", "0" } },
-                       { 0x0056, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0057, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x005a, new [] { "3", "2", "1", "0", "0" } },
-                       { 0x005b, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x005d, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x005e, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x005f, new [] { "8", "3", "3", "0", "0" } },
-                       { 0x0061, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0062, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0063, new [] { "3", "0", "3", "4", "2" } },
-                       { 0x0064, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0065, new [] { "10", "3", "1", "0", "0" } },
-                       { 0x0068, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x006a, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x006b, new [] { "14", "2", "1", "2", "2" } },
-                       { 0x006c, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x006d, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x006e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x006f, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0070, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x0078, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x007a, new [] { "9", "2", "1", "0", "0" } },
-                       { 0x007c, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x007e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x007f, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0080, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x0081, new [] { "1", "0", "1", "2", "2" } },
-                       { 0x0082, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0083, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0084, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0085, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x0086, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0087, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x0088, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x008c, new [] { "3", "0", "3", "4", "2" } },
-                       { 0x0091, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x0401, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x0402, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0403, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0404, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0405, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0406, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0407, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0408, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0409, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x040b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x040c, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x040d, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x040e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x040f, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0410, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0411, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0412, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x0413, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0414, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0415, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0416, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0417, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x0418, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0419, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x041a, new [] { "8", "3", "2", "1", "1" } },
-                       { 0x041b, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x041c, new [] { "5", "1", "1", "0", "0" } },
-                       { 0x041d, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x041e, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x041f, new [] { "8", "3", "1", "2", "2" } },
-                       { 0x0420, new [] { "3", "0", "1", "0", "0" } },
-                       { 0x0421, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0422, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x0423, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0424, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0425, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0426, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0427, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0428, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0429, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x042a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x042b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x042c, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x042d, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x042e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x042f, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0432, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x0434, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x0435, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x0436, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x0437, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0438, new [] { "12", "2", "1", "1", "1" } },
-                       { 0x0439, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x043a, new [] { "1", "0", "1", "2", "2" } },
-                       { 0x043b, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x043e, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x043f, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0440, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0441, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0442, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x0443, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0444, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0445, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x0446, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0447, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0448, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0449, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x044a, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x044b, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x044c, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x044d, new [] { "12", "1", "1", "1", "1" } },
-                       { 0x044e, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x044f, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0450, new [] { "5", "1", "1", "0", "0" } },
-                       { 0x0451, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x0452, new [] { "1", "0", "1", "2", "2" } },
-                       { 0x0453, new [] { "5", "1", "2", "1", "1" } },
-                       { 0x0454, new [] { "4", "1", "0", "0", "0" } },
-                       { 0x0456, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0457, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x045a, new [] { "3", "2", "1", "0", "0" } },
-                       { 0x045b, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x045d, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x045e, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0461, new [] { "1", "0", "1", "1", "1" } },
-                       { 0x0462, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0463, new [] { "3", "0", "3", "4", "2" } },
-                       { 0x0464, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0465, new [] { "10", "3", "1", "0", "0" } },
-                       { 0x0468, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x046a, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x046b, new [] { "14", "2", "1", "2", "2" } },
-                       { 0x046c, new [] { "2", "2", "1", "2", "2" } },
-                       { 0x046d, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x046e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x046f, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0470, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x0478, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x047a, new [] { "9", "2", "1", "0", "0" } },
-                       { 0x047c, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x047e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0480, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x0481, new [] { "1", "0", "1", "2", "2" } },
-                       { 0x0482, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0483, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0484, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0485, new [] { "5", "1", "1", "1", "1" } },
-                       { 0x0486, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0487, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x0488, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x048c, new [] { "3", "0", "3", "4", "2" } },
-                       { 0x0491, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x0801, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x0804, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x0807, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x0809, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x080a, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x080c, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0810, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x0813, new [] { "12", "2", "1", "1", "1" } },
-                       { 0x0814, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x0816, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x081a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x081d, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x082c, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x082e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x083b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x083c, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x083e, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x0843, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0845, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x0850, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x085d, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x085f, new [] { "8", "3", "3", "0", "0" } },
-                       { 0x086b, new [] { "14", "2", "1", "2", "2" } },
-                       { 0x0c01, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x0c04, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x0c07, new [] { "9", "2", "1", "1", "1" } },
-                       { 0x0c09, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x0c0a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0c0c, new [] { "15", "3", "1", "0", "0" } },
-                       { 0x0c1a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x0c3b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x0c6b, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x1001, new [] { "3", "0", "3", "0", "0" } },
-                       { 0x1004, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x1007, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x1009, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x100a, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x100c, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x101a, new [] { "8", "3", "2", "0", "0" } },
-                       { 0x103b, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x1401, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x1404, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x1407, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x1409, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x140a, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x140c, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x141a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x143b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x1801, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x1809, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x180a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x180c, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x181a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x183b, new [] { "12", "2", "1", "2", "2" } },
-                       { 0x1c01, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x1c09, new [] { "2", "2", "1", "1", "1" } },
-                       { 0x1c0a, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x1c1a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x1c3b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x2001, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x2009, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x200a, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x201a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x203b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x2401, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x2409, new [] { "1", "0", "1", "0", "0" } },
-                       { 0x240a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x241a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x243b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x2801, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x2809, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x280a, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x281a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x2c01, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x2c09, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x2c0a, new [] { "2", "2", "1", "0", "0" } },
-                       { 0x2c1a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x3001, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x3009, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x300a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x301a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x3401, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x3409, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x340a, new [] { "9", "2", "1", "0", "0" } },
-                       { 0x3801, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x380a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x3c01, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x3c0a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x4001, new [] { "3", "2", "3", "0", "0" } },
-                       { 0x4009, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x400a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x4409, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x440a, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x4809, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x480a, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x4c0a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x500a, new [] { "14", "2", "1", "0", "0" } },
-                       { 0x540a, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x641a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x681a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x6c1a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x701a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x703b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x742c, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x743b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x7804, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x7814, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x781a, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x782c, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x783b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x7843, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x7850, new [] { "5", "1", "1", "0", "0" } },
-                       { 0x785d, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x7c04, new [] { "0", "0", "1", "1", "1" } },
-                       { 0x7c14, new [] { "12", "2", "1", "0", "0" } },
-                       { 0x7c1a, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x7c28, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x7c2e, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x7c3b, new [] { "8", "3", "1", "0", "0" } },
-                       { 0x7c43, new [] { "8", "3", "1", "1", "1" } },
-                       { 0x7c50, new [] { "2", "0", "1", "1", "1" } },
-                       { 0x7c5d, new [] { "0", "0", "1", "0", "0" } },
-                       { 0x7c5f, new [] { "8", "3", "3", "0", "0" } },
-                       { 0x7c68, new [] { "2", "2", "1", "0", "0" } },
+                       { 0x0001, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x0002, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0003, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0004, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x0005, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0006, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0007, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0008, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0009, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x000A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x000B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x000C, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x000D, new [] { "2", "2", "1", "1", "1", ".", "," } },
+                       { 0x000E, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x000F, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0010, new [] { "9", "2", "1", "1", "1", ",", "." } },
+                       { 0x0011, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x0012, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x0013, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0014, new [] { "12", "2", "1", "0", "0", ",", " " } },
+                       { 0x0015, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0016, new [] { "9", "2", "1", "1", "1", ",", "." } },
+                       { 0x0017, new [] { "2", "2", "1", "1", "1", ".", "'" } },
+                       { 0x0018, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0019, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x001A, new [] { "8", "3", "2", "1", "1", ",", "." } },
+                       { 0x001B, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x001C, new [] { "5", "1", "1", "0", "0", ",", "." } },
+                       { 0x001D, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x001E, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x001F, new [] { "8", "3", "1", "2", "2", ",", "." } },
+                       { 0x0020, new [] { "3", "0", "1", "0", "0", ".", "," } },
+                       { 0x0021, new [] { "0", "0", "1", "0", "0", ",", "." } },
+                       { 0x0022, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x0023, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0024, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0025, new [] { "8", "3", "1", "1", "1", ".", " " } },
+                       { 0x0026, new [] { "9", "2", "1", "1", "1", ",", " " } },
+                       { 0x0027, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0028, new [] { "8", "3", "1", "1", "1", ";", " " } },
+                       { 0x0029, new [] { "3", "2", "3", "0", "0", "/", "," } },
+                       { 0x002A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x002B, new [] { "8", "3", "1", "0", "0", ".", "," } },
+                       { 0x002C, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x002D, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x002E, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x002F, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0032, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x0034, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x0035, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x0036, new [] { "2", "2", "1", "1", "1", ".", "," } },
+                       { 0x0037, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0038, new [] { "12", "2", "1", "1", "1", ",", "." } },
+                       { 0x0039, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x003A, new [] { "1", "0", "1", "2", "2", ".", "," } },
+                       { 0x003B, new [] { "12", "2", "1", "2", "2", ",", " " } },
+                       { 0x003C, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x003E, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x003F, new [] { "1", "0", "1", "1", "1", "-", " " } },
+                       { 0x0040, new [] { "8", "3", "1", "1", "1", "-", " " } },
+                       { 0x0041, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x0042, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x0043, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0044, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0045, new [] { "12", "2", "1", "2", "2", ".", "," } },
+                       { 0x0046, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0047, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0048, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0049, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x004A, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x004B, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x004C, new [] { "12", "2", "1", "2", "2", ".", "," } },
+                       { 0x004D, new [] { "12", "1", "1", "1", "1", ".", "," } },
+                       { 0x004E, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x004F, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0050, new [] { "5", "1", "1", "0", "0", ",", " " } },
+                       { 0x0051, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x0052, new [] { "1", "0", "1", "2", "2", ".", "," } },
+                       { 0x0053, new [] { "5", "1", "2", "1", "1", ".", "," } },
+                       { 0x0054, new [] { "4", "1", "0", "0", "0", ".", "," } },
+                       { 0x0056, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0057, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x005A, new [] { "3", "2", "1", "0", "0", ".", "," } },
+                       { 0x005B, new [] { "14", "2", "1", "0", "0", ".", "," } },
+                       { 0x005D, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x005E, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x005F, new [] { "8", "3", "3", "0", "0", ".", "," } },
+                       { 0x0061, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x0062, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0063, new [] { "3", "0", "3", "4", "2", "٫", "٬" } },
+                       { 0x0064, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x0065, new [] { "10", "3", "1", "0", "0", ".", "," } },
+                       { 0x0068, new [] { "2", "2", "1", "0", "0", ".", "," } },
+                       { 0x006A, new [] { "2", "2", "1", "0", "0", ".", "," } },
+                       { 0x006B, new [] { "14", "2", "1", "2", "2", ",", "." } },
+                       { 0x006C, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x006D, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x006E, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x006F, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0070, new [] { "2", "2", "1", "0", "0", ".", "," } },
+                       { 0x0078, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x007A, new [] { "9", "2", "1", "0", "0", ",", "." } },
+                       { 0x007C, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x007E, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0080, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x0081, new [] { "1", "0", "1", "2", "2", ".", "," } },
+                       { 0x0082, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0083, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0084, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0085, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x0086, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x0087, new [] { "2", "2", "1", "0", "0", ",", " " } },
+                       { 0x0088, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x008C, new [] { "3", "0", "3", "4", "2", ".", "," } },
+                       { 0x0091, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x0401, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x0402, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0403, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0404, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x0405, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0406, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0407, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0408, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0409, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x040B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x040C, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x040D, new [] { "2", "2", "1", "1", "1", ".", "," } },
+                       { 0x040E, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x040F, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0410, new [] { "9", "2", "1", "1", "1", ",", "." } },
+                       { 0x0411, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x0412, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x0413, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0414, new [] { "12", "2", "1", "0", "0", ",", " " } },
+                       { 0x0415, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0416, new [] { "9", "2", "1", "1", "1", ",", "." } },
+                       { 0x0417, new [] { "2", "2", "1", "1", "1", ".", "'" } },
+                       { 0x0418, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0419, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x041A, new [] { "8", "3", "2", "1", "1", ",", "." } },
+                       { 0x041B, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x041C, new [] { "5", "1", "1", "0", "0", ",", "." } },
+                       { 0x041D, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x041E, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x041F, new [] { "8", "3", "1", "2", "2", ",", "." } },
+                       { 0x0420, new [] { "3", "0", "1", "0", "0", ".", "," } },
+                       { 0x0421, new [] { "0", "0", "1", "0", "0", ",", "." } },
+                       { 0x0422, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x0423, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0424, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0425, new [] { "8", "3", "1", "1", "1", ".", " " } },
+                       { 0x0426, new [] { "9", "2", "1", "1", "1", ",", " " } },
+                       { 0x0427, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0428, new [] { "8", "3", "1", "1", "1", ";", " " } },
+                       { 0x0429, new [] { "3", "2", "3", "0", "0", "/", "," } },
+                       { 0x042A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x042B, new [] { "8", "3", "1", "0", "0", ".", "," } },
+                       { 0x042C, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x042D, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x042E, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x042F, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0432, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x0434, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x0435, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x0436, new [] { "2", "2", "1", "1", "1", ".", "," } },
+                       { 0x0437, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0438, new [] { "12", "2", "1", "1", "1", ",", "." } },
+                       { 0x0439, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x043A, new [] { "1", "0", "1", "2", "2", ".", "," } },
+                       { 0x043B, new [] { "12", "2", "1", "2", "2", ",", " " } },
+                       { 0x043E, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x043F, new [] { "1", "0", "1", "1", "1", "-", " " } },
+                       { 0x0440, new [] { "8", "3", "1", "1", "1", "-", " " } },
+                       { 0x0441, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x0442, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x0443, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0444, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0445, new [] { "12", "2", "1", "2", "2", ".", "," } },
+                       { 0x0446, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0447, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0448, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0449, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x044A, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x044B, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x044C, new [] { "12", "2", "1", "2", "2", ".", "," } },
+                       { 0x044D, new [] { "12", "1", "1", "1", "1", ".", "," } },
+                       { 0x044E, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x044F, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x0450, new [] { "5", "1", "1", "0", "0", ",", " " } },
+                       { 0x0451, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x0452, new [] { "1", "0", "1", "2", "2", ".", "," } },
+                       { 0x0453, new [] { "5", "1", "2", "1", "1", ".", "," } },
+                       { 0x0454, new [] { "4", "1", "0", "0", "0", ".", "," } },
+                       { 0x0456, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0457, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x045A, new [] { "3", "2", "1", "0", "0", ".", "," } },
+                       { 0x045B, new [] { "14", "2", "1", "0", "0", ".", "," } },
+                       { 0x045D, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x045E, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x0461, new [] { "1", "0", "1", "1", "1", ".", "," } },
+                       { 0x0462, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0463, new [] { "3", "0", "3", "4", "2", "٫", "٬" } },
+                       { 0x0464, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x0465, new [] { "10", "3", "1", "0", "0", ".", "," } },
+                       { 0x0468, new [] { "2", "2", "1", "0", "0", ".", "," } },
+                       { 0x046A, new [] { "2", "2", "1", "0", "0", ".", "," } },
+                       { 0x046B, new [] { "14", "2", "1", "2", "2", ",", "." } },
+                       { 0x046C, new [] { "2", "2", "1", "2", "2", ".", "," } },
+                       { 0x046D, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x046E, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x046F, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0470, new [] { "2", "2", "1", "0", "0", ".", "," } },
+                       { 0x0478, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x047A, new [] { "9", "2", "1", "0", "0", ",", "." } },
+                       { 0x047C, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x047E, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0480, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x0481, new [] { "1", "0", "1", "2", "2", ".", "," } },
+                       { 0x0482, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0483, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0484, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0485, new [] { "5", "1", "1", "1", "1", ",", " " } },
+                       { 0x0486, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x0487, new [] { "2", "2", "1", "0", "0", ",", " " } },
+                       { 0x0488, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x048C, new [] { "3", "0", "3", "4", "2", ".", "," } },
+                       { 0x0491, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x0801, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x0804, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x0807, new [] { "2", "2", "1", "1", "1", ".", "'" } },
+                       { 0x0809, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x080A, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x080C, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x0810, new [] { "2", "2", "1", "1", "1", ".", "'" } },
+                       { 0x0813, new [] { "12", "2", "1", "1", "1", ",", "." } },
+                       { 0x0814, new [] { "12", "2", "1", "0", "0", ",", " " } },
+                       { 0x0816, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x081A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x081D, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x082C, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x082E, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x083B, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x083C, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x083E, new [] { "0", "0", "1", "0", "0", ",", "." } },
+                       { 0x0843, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x0845, new [] { "12", "2", "1", "2", "2", ".", "," } },
+                       { 0x0850, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x085D, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x085F, new [] { "8", "3", "3", "0", "0", ".", "," } },
+                       { 0x086B, new [] { "14", "2", "1", "2", "2", ",", "." } },
+                       { 0x0C01, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x0C04, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x0C07, new [] { "9", "2", "1", "1", "1", ",", "." } },
+                       { 0x0C09, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x0C0A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x0C0C, new [] { "15", "3", "1", "0", "0", ",", " " } },
+                       { 0x0C1A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x0C3B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x0C6B, new [] { "12", "2", "1", "2", "2", ".", "," } },
+                       { 0x1001, new [] { "3", "0", "3", "0", "0", ".", "," } },
+                       { 0x1004, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x1007, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x1009, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x100A, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x100C, new [] { "2", "2", "1", "0", "0", ".", "'" } },
+                       { 0x101A, new [] { "8", "3", "2", "0", "0", ",", "." } },
+                       { 0x103B, new [] { "12", "2", "1", "2", "2", ",", " " } },
+                       { 0x1401, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x1404, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x1407, new [] { "2", "2", "1", "1", "1", ".", "'" } },
+                       { 0x1409, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x140A, new [] { "0", "0", "1", "0", "0", ",", "." } },
+                       { 0x140C, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x141A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x143B, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x1801, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x1809, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x180A, new [] { "14", "2", "1", "0", "0", ".", "," } },
+                       { 0x180C, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x181A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x183B, new [] { "12", "2", "1", "2", "2", ",", " " } },
+                       { 0x1C01, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x1C09, new [] { "2", "2", "1", "1", "1", ",", " " } },
+                       { 0x1C0A, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x1C1A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x1C3B, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x2001, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x2009, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x200A, new [] { "12", "2", "1", "0", "0", ",", "." } },
+                       { 0x201A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x203B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x2401, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x2409, new [] { "1", "0", "1", "0", "0", ".", "," } },
+                       { 0x240A, new [] { "14", "2", "1", "0", "0", ",", "." } },
+                       { 0x241A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x243B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x2801, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x2809, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x280A, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x281A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x2C01, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x2C09, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x2C0A, new [] { "2", "2", "1", "0", "0", ",", "." } },
+                       { 0x2C1A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x3001, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x3009, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x300A, new [] { "14", "2", "1", "0", "0", ",", "." } },
+                       { 0x301A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x3401, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x3409, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x340A, new [] { "9", "2", "1", "0", "0", ",", "." } },
+                       { 0x3801, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x380A, new [] { "14", "2", "1", "0", "0", ",", "." } },
+                       { 0x3C01, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x3C0A, new [] { "14", "2", "1", "0", "0", ",", "." } },
+                       { 0x4001, new [] { "3", "2", "3", "0", "0", ".", "," } },
+                       { 0x4009, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x400A, new [] { "14", "2", "1", "0", "0", ",", "." } },
+                       { 0x4409, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x440A, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x4809, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x480A, new [] { "12", "2", "1", "0", "0", ".", "," } },
+                       { 0x4C0A, new [] { "14", "2", "1", "0", "0", ".", "," } },
+                       { 0x500A, new [] { "14", "2", "1", "0", "0", ".", "," } },
+                       { 0x540A, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x641A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x681A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x6C1A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x701A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x703B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x742C, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x743B, new [] { "8", "3", "1", "0", "0", ",", " " } },
+                       { 0x7804, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x7814, new [] { "12", "2", "1", "0", "0", ",", " " } },
+                       { 0x781A, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x782C, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x783B, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x7843, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x7850, new [] { "5", "1", "1", "0", "0", ",", " " } },
+                       { 0x785D, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x7C04, new [] { "0", "0", "1", "1", "1", ".", "," } },
+                       { 0x7C14, new [] { "12", "2", "1", "0", "0", ",", " " } },
+                       { 0x7C1A, new [] { "8", "3", "1", "1", "1", ",", "." } },
+                       { 0x7C28, new [] { "8", "3", "1", "1", "1", ";", " " } },
+                       { 0x7C2E, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x7C3B, new [] { "8", "3", "1", "0", "0", ",", "." } },
+                       { 0x7C43, new [] { "8", "3", "1", "1", "1", ",", " " } },
+                       { 0x7C50, new [] { "2", "0", "1", "1", "1", ".", "," } },
+                       { 0x7C5D, new [] { "0", "0", "1", "0", "0", ".", "," } },
+                       { 0x7C5F, new [] { "8", "3", "3", "0", "0", ".", "," } },
+                       { 0x7C68, new [] { "2", "2", "1", "0", "0", ".", "," } },
                };
 
                static readonly Dictionary<int, string> Geo = new Dictionary<int, string> {
@@ -1761,6 +1760,8 @@ namespace Mono.Tools.LocaleBuilder
                        nf.NumberNegativePattern = entry_nf[2];
                        nf.PercentNegativePattern = entry_nf[3];
                        nf.PercentPositivePattern = entry_nf[4];
+                       nf.CurrencyDecimalSeparator = entry_nf[5];
+                       nf.CurrencyGroupSeparator = entry_nf[6];
 
                        string[][] gsizes;
                        if (!GroupSizes.TryGetValue (lcid, out gsizes)) {
index 32b3777d85aadfb0b62d5397ef7601106cff3d0e..1a3653ef1d7e0d18491915dc0886b143fe1ab82d 100644 (file)
@@ -10,6 +10,9 @@
 
 #define SGEN_PROTOCOL_EOF      255
 
+#define TYPE(t)                ((t) & 0x7f)
+#define WORKER(t)      ((t) & 0x80)
+
 static int
 read_entry (FILE *in, void **data)
 {
@@ -18,7 +21,7 @@ read_entry (FILE *in, void **data)
 
        if (fread (&type, 1, 1, in) != 1)
                return SGEN_PROTOCOL_EOF;
-       switch (type) {
+       switch (TYPE (type)) {
        case SGEN_PROTOCOL_COLLECTION_FORCE: size = sizeof (SGenProtocolCollectionForce); break;
        case SGEN_PROTOCOL_COLLECTION_BEGIN: size = sizeof (SGenProtocolCollection); break;
        case SGEN_PROTOCOL_COLLECTION_END: size = sizeof (SGenProtocolCollection); break;
@@ -62,134 +65,136 @@ read_entry (FILE *in, void **data)
        return (int)type;
 }
 
+#define WORKER_PREFIX(t)       (WORKER ((t)) ? "w" : " ")
+
 static void
 print_entry (int type, void *data)
 {
-       switch (type) {
+       switch (TYPE (type)) {
        case SGEN_PROTOCOL_COLLECTION_FORCE: {
                SGenProtocolCollectionForce *entry = data;
-               printf ("collection force generation %d\n", entry->generation);
+               printf ("%s collection force generation %d\n", WORKER_PREFIX (type), entry->generation);
                break;
        }
        case SGEN_PROTOCOL_COLLECTION_BEGIN: {
                SGenProtocolCollection *entry = data;
-               printf ("collection begin %d generation %d\n", entry->index, entry->generation);
+               printf ("%s collection begin %d generation %d\n", WORKER_PREFIX (type), entry->index, entry->generation);
                break;
        }
        case SGEN_PROTOCOL_COLLECTION_END: {
                SGenProtocolCollection *entry = data;
-               printf ("collection end %d generation %d\n", entry->index, entry->generation);
+               printf ("%s collection end %d generation %d\n", WORKER_PREFIX (type), entry->index, entry->generation);
                break;
        }
        case SGEN_PROTOCOL_ALLOC: {
                SGenProtocolAlloc *entry = data;
-               printf ("alloc obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s alloc obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_ALLOC_PINNED: {
                SGenProtocolAlloc *entry = data;
-               printf ("alloc pinned obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s alloc pinned obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_ALLOC_DEGRADED: {
                SGenProtocolAlloc *entry = data;
-               printf ("alloc degraded obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s alloc degraded obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_COPY: {
                SGenProtocolCopy *entry = data;
-               printf ("copy from %p to %p vtable %p size %d\n", entry->from, entry->to, entry->vtable, entry->size);
+               printf ("%s copy from %p to %p vtable %p size %d\n", WORKER_PREFIX (type), entry->from, entry->to, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_PIN: {
                SGenProtocolPin *entry = data;
-               printf ("pin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s pin obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_MARK: {
                SGenProtocolMark *entry = data;
-               printf ("mark obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s mark obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_SCAN_BEGIN: {
                SGenProtocolScanBegin *entry = data;
-               printf ("scan_begin obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s scan_begin obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_SCAN_VTYPE_BEGIN: {
                SGenProtocolScanVTypeBegin *entry = data;
-               printf ("scan_vtype_begin obj %p size %d\n", entry->obj, entry->size);
+               printf ("%s scan_vtype_begin obj %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->size);
                break;
        }
        case SGEN_PROTOCOL_WBARRIER: {
                SGenProtocolWBarrier *entry = data;
-               printf ("wbarrier ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
+               printf ("%s wbarrier ptr %p value %p value_vtable %p\n", WORKER_PREFIX (type), entry->ptr, entry->value, entry->value_vtable);
                break;
        }
        case SGEN_PROTOCOL_GLOBAL_REMSET: {
                SGenProtocolGlobalRemset *entry = data;
-               printf ("global_remset ptr %p value %p value_vtable %p\n", entry->ptr, entry->value, entry->value_vtable);
+               printf ("%s global_remset ptr %p value %p value_vtable %p\n", WORKER_PREFIX (type), entry->ptr, entry->value, entry->value_vtable);
                break;
        }
        case SGEN_PROTOCOL_PTR_UPDATE: {
                SGenProtocolPtrUpdate *entry = data;
-               printf ("ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n",
+               printf ("%s ptr_update ptr %p old_value %p new_value %p vtable %p size %d\n", WORKER_PREFIX (type),
                                entry->ptr, entry->old_value, entry->new_value, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_CLEANUP: {
                SGenProtocolCleanup *entry = data;
-               printf ("cleanup ptr %p vtable %p size %d\n", entry->ptr, entry->vtable, entry->size);
+               printf ("%s cleanup ptr %p vtable %p size %d\n", WORKER_PREFIX (type), entry->ptr, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_EMPTY: {
                SGenProtocolEmpty *entry = data;
-               printf ("empty start %p size %d\n", entry->start, entry->size);
+               printf ("%s empty start %p size %d\n", WORKER_PREFIX (type), entry->start, entry->size);
                break;
        }
        case SGEN_PROTOCOL_THREAD_SUSPEND: {
                SGenProtocolThreadSuspend *entry = data;
-               printf ("thread_suspend thread %p ip %p\n", entry->thread, entry->stopped_ip);
+               printf ("%s thread_suspend thread %p ip %p\n", WORKER_PREFIX (type), entry->thread, entry->stopped_ip);
                break;
        }
        case SGEN_PROTOCOL_THREAD_RESTART: {
                SGenProtocolThreadRestart *entry = data;
-               printf ("thread_restart thread %p\n", entry->thread);
+               printf ("%s thread_restart thread %p\n", WORKER_PREFIX (type), entry->thread);
                break;
        }
        case SGEN_PROTOCOL_THREAD_REGISTER: {
                SGenProtocolThreadRegister *entry = data;
-               printf ("thread_register thread %p\n", entry->thread);
+               printf ("%s thread_register thread %p\n", WORKER_PREFIX (type), entry->thread);
                break;
        }
        case SGEN_PROTOCOL_THREAD_UNREGISTER: {
                SGenProtocolThreadUnregister *entry = data;
-               printf ("thread_unregister thread %p\n", entry->thread);
+               printf ("%s thread_unregister thread %p\n", WORKER_PREFIX (type), entry->thread);
                break;
        }
        case SGEN_PROTOCOL_MISSING_REMSET: {
                SGenProtocolMissingRemset *entry = data;
-               printf ("missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n",
+               printf ("%s missing_remset obj %p obj_vtable %p offset %d value %p value_vtable %p value_pinned %d\n", WORKER_PREFIX (type),
                                entry->obj, entry->obj_vtable, entry->offset, entry->value, entry->value_vtable, entry->value_pinned);
                break;
        }
        case SGEN_PROTOCOL_CARD_SCAN: {
                SGenProtocolCardScan *entry = data;
-               printf ("card_scan start %p size %d\n", entry->start, entry->size);
+               printf ("%s card_scan start %p size %d\n", WORKER_PREFIX (type), entry->start, entry->size);
                break;
        }
        case SGEN_PROTOCOL_CEMENT: {
                SGenProtocolCement *entry = data;
-               printf ("cement obj %p vtable %p size %d\n", entry->obj, entry->vtable, entry->size);
+               printf ("%s cement obj %p vtable %p size %d\n", WORKER_PREFIX (type), entry->obj, entry->vtable, entry->size);
                break;
        }
        case SGEN_PROTOCOL_CEMENT_RESET: {
-               printf ("cement_reset\n");
+               printf ("%s cement_reset\n", WORKER_PREFIX (type));
                break;
        }
        case SGEN_PROTOCOL_DISLINK_UPDATE: {
                SGenProtocolDislinkUpdate *entry = data;
-               printf ("dislink_update link %p obj %p staged %d", entry->link, entry->obj, entry->staged);
+               printf ("%s dislink_update link %p obj %p staged %d", WORKER_PREFIX (type), entry->link, entry->obj, entry->staged);
                if (entry->obj)
                        printf (" track %d\n", entry->track);
                else
@@ -198,7 +203,7 @@ print_entry (int type, void *data)
        }
        case SGEN_PROTOCOL_DISLINK_UPDATE_STAGED: {
                SGenProtocolDislinkUpdateStaged *entry = data;
-               printf ("dislink_update_staged link %p obj %p index %d", entry->link, entry->obj, entry->index);
+               printf ("%s dislink_update_staged link %p obj %p index %d", WORKER_PREFIX (type), entry->link, entry->obj, entry->index);
                if (entry->obj)
                        printf (" track %d\n", entry->track);
                else
@@ -207,17 +212,17 @@ print_entry (int type, void *data)
        }
        case SGEN_PROTOCOL_DISLINK_PROCESS_STAGED: {
                SGenProtocolDislinkProcessStaged *entry = data;
-               printf ("dislink_process_staged link %p obj %p index %d\n", entry->link, entry->obj, entry->index);
+               printf ("%s dislink_process_staged link %p obj %p index %d\n", WORKER_PREFIX (type), entry->link, entry->obj, entry->index);
                break;
        }
        case SGEN_PROTOCOL_DOMAIN_UNLOAD_BEGIN: {
                SGenProtocolDomainUnload *entry = data;
-               printf ("dislink_unload_begin domain %p\n", entry->domain);
+               printf ("%s dislink_unload_begin domain %p\n", WORKER_PREFIX (type), entry->domain);
                break;
        }
        case SGEN_PROTOCOL_DOMAIN_UNLOAD_END: {
                SGenProtocolDomainUnload *entry = data;
-               printf ("dislink_unload_end domain %p\n", entry->domain);
+               printf ("%s dislink_unload_end domain %p\n", WORKER_PREFIX (type), entry->domain);
                break;
        }
        default:
@@ -234,7 +239,7 @@ matches_interval (gpointer ptr, gpointer start, int size)
 static gboolean
 is_match (gpointer ptr, int type, void *data)
 {
-       switch (type) {
+       switch (TYPE (type)) {
        case SGEN_PROTOCOL_COLLECTION_FORCE:
        case SGEN_PROTOCOL_COLLECTION_BEGIN:
        case SGEN_PROTOCOL_COLLECTION_END:
@@ -326,7 +331,7 @@ is_match (gpointer ptr, int type, void *data)
 static gboolean
 is_vtable_match (gpointer ptr, int type, void *data)
 {
-       switch (type) {
+       switch (TYPE (type)) {
        case SGEN_PROTOCOL_ALLOC:
        case SGEN_PROTOCOL_ALLOC_PINNED:
        case SGEN_PROTOCOL_ALLOC_DEGRADED: {
index 834bbe7bfae22c1dc8d974154daecdadff1fec7b..811ba97516c3149988598aade0f3ae8130878ded 100644 (file)
 /* Define to 1 if you have the <curses.h> header file. */
 /* #undef HAVE_CURSES_H */
 
+/* Define to 1 if you have the declaration of `InterlockedAdd',
+   and to 0 if you don't. */
+#define HAVE_DECL_INTERLOCKEDADD 1
+
+/* Define to 1 if you have the declaration of `InterlockedAdd64',
+   and to 0 if you don't. */
+#define HAVE_DECL_INTERLOCKEDADD64 1
+
 /* Define to 1 if you have the declaration of `InterlockedCompareExchange64',
    and to 0 if you don't. */
 #define HAVE_DECL_INTERLOCKEDCOMPAREEXCHANGE64 1
 
+/* Define to 1 if you have the declaration of `InterlockedDecrement64',
+   and to 0 if you don't. */
+#define HAVE_DECL_INTERLOCKEDDECREMENT64 1
+
+/* Define to 1 if you have the declaration of `InterlockedExchange64',
+   and to 0 if you don't. */
+#define HAVE_DECL_INTERLOCKEDEXCHANGE64 1
+
+/* Define to 1 if you have the declaration of `InterlockedIncrement64',
+   and to 0 if you don't. */
+#define HAVE_DECL_INTERLOCKEDINCREMENT64 1
+
+/* Define to 1 if you have the declaration of `__readfsdword',
+   and to 0 if you don't. */
+#define HAVE_DECL___READFSDWORD 1
+
 /* Define to 1 if you have the <dirent.h> header file. */
 /* #define HAVE_DIRENT_H 1 */
 
 /* Enable the allocation and indexing of arrays greater than Int32.MaxValue */
 /* #undef MONO_BIG_ARRAYS */
 
-/* The Mono Debugger is supported on this platform */
-/* #undef MONO_DEBUGGER_SUPPORTED */
-
 /* Sizeof sock_un.sun_path */
 /* #undef MONO_SIZEOF_SUNPATH */