-Subproject commit d6b00edf218008ecd8cfe90bc66b9b607431428f
+Subproject commit 00252c18fc0a4a206e45461736a890acb785a9d8
throw;
}
- Log.LogErrorWithCodeFromResources ("XmlPeek.ArgumentError", e.Message);
+ Log.LogError ("MSB3741: Unable to load arguments for the XmlPeek task. {0}", e.Message);
return false;
}
throw;
}
- Log.LogErrorWithCodeFromResources ("XmlPeekPoke.InputFileError", _xmlInputPath.ItemSpec, e.Message);
+ Log.LogError ("MSB3733: Input file \"{0}\" cannot be opened. {1}", _xmlInputPath.ItemSpec, e.Message);
return false;
} finally {
xmlinput.CloseReader ();
throw;
}
- Log.LogErrorWithCodeFromResources ("XmlPeekPoke.XPathError", _query, e.Message);
+ Log.LogError ("MSB3734: XPath Query \"{0}\" cannot be loaded. {1}", _query, e.Message);
return false;
}
throw;
}
- Log.LogErrorWithCodeFromResources ("XmlPeek.NamespacesError", e.Message);
+ Log.LogError ("MSB3742: Unable to process the Namespaces argument for the XmlPeek task. {0}", e.Message);
return false;
}
try {
expr.SetContext (xmlNamespaceManager);
} catch (XPathException e) {
- Log.LogErrorWithCodeFromResources ("XmlPeek.XPathContextError", e.Message);
+ Log.LogError ("MSB3743: Unable to set XPath expression's Context. {0}", e.Message);
return false;
}
_result [i++] = new TaskItem (item);
// This can be logged a lot, so low importance
- Log.LogMessageFromResources (MessageImportance.Low, "XmlPeek.Found", item);
+ Log.LogMessage (MessageImportance.Low, "Found \"{0}\".", item);
}
if (_result.Length == 0) {
// Logged no more than once per execute of this task
- Log.LogMessageFromResources ("XmlPeek.NotFound");
+ Log.LogMessage ("The specified XPath query did not capture any nodes.");
}
return true;
using System.Globalization;
using System.IO;
using System.Runtime.Serialization;
+#if PCL
+using System.Reflection;
+#else
using System.Security.Permissions;
+#endif
using System.Text;
using System.Text.RegularExpressions;
using NDesk.Options;
#endif
+#if PCL
+using MessageLocalizerConverter = System.Func<string, string>;
+#else
+using MessageLocalizerConverter = System.Converter<string, string>;
+#endif
+
#if NDESK_OPTIONS
namespace NDesk.Options
#else
protected static T Parse<T> (string value, OptionContext c)
{
Type tt = typeof (T);
- bool nullable = tt.IsValueType && tt.IsGenericType &&
- !tt.IsGenericTypeDefinition &&
- tt.GetGenericTypeDefinition () == typeof (Nullable<>);
- Type targetType = nullable ? tt.GetGenericArguments () [0] : typeof (T);
- TypeConverter conv = TypeDescriptor.GetConverter (targetType);
+#if PCL
+ TypeInfo ti = tt.GetTypeInfo ();
+#else
+ Type ti = tt;
+#endif
+ bool nullable =
+ ti.IsValueType &&
+ ti.IsGenericType &&
+ !ti.IsGenericTypeDefinition &&
+ ti.GetGenericTypeDefinition () == typeof (Nullable<>);
+#if PCL
+ Type targetType = nullable ? tt.GenericTypeArguments [0] : tt;
+#else
+ Type targetType = nullable ? tt.GetGenericArguments () [0] : tt;
+#endif
T t = default (T);
try {
- if (value != null)
+ if (value != null) {
+#if PCL
+ t = (T) Convert.ChangeType (value, targetType);
+#else
+ TypeConverter conv = TypeDescriptor.GetConverter (targetType);
t = (T) conv.ConvertFromString (value);
+#endif
+ }
}
catch (Exception e) {
throw new OptionException (
public abstract string Description { get; }
public abstract bool GetArguments (string value, out IEnumerable<string> replacement);
+#if !PCL
public static IEnumerable<string> GetArgumentsFromFile (string file)
{
return GetArguments (File.OpenText (file), true);
}
+#endif
public static IEnumerable<string> GetArguments (TextReader reader)
{
}
finally {
if (close)
- reader.Close ();
+ reader.Dispose ();
}
}
}
+#if !PCL
public class ResponseFileSource : ArgumentSource {
public override string[] GetNames ()
return true;
}
}
+#endif
+#if !PCL
[Serializable]
+#endif
public class OptionException : Exception {
private string option;
this.option = optionName;
}
+#if !PCL
protected OptionException (SerializationInfo info, StreamingContext context)
: base (info, context)
{
this.option = info.GetString ("OptionName");
}
+#endif
public string OptionName {
get {return this.option;}
}
+#if !PCL
#pragma warning disable 618 // SecurityPermissionAttribute is obsolete
[SecurityPermission (SecurityAction.LinkDemand, SerializationFormatter = true)]
#pragma warning restore 618
base.GetObjectData (info, context);
info.AddValue ("OptionName", option);
}
+#endif
}
public delegate void OptionAction<TKey, TValue> (TKey key, TValue value);
{
}
- public OptionSet (Converter<string, string> localizer)
+ public OptionSet (MessageLocalizerConverter localizer)
{
this.localizer = localizer;
this.roSources = new ReadOnlyCollection<ArgumentSource>(sources);
}
- Converter<string, string> localizer;
+ MessageLocalizerConverter localizer;
- public Converter<string, string> MessageLocalizer {
+ public MessageLocalizerConverter MessageLocalizer {
get {return localizer;}
}
Mono.Unix/ReadlinkTest.cs
Mono.Unix/StdioFileStreamTest.cs
Mono.Unix/UnixEncodingTest.cs
+Mono.Unix/UnixEndPointTest.cs
Mono.Unix/UnixGroupTest.cs
+Mono.Unix/UnixListenerTest.cs
Mono.Unix/UnixMarshalTest.cs
Mono.Unix/UnixPathTest.cs
Mono.Unix/UnixSignalTest.cs
uep.filename = "";
return uep;
}
- byte [] bytes = new byte [socketAddress.Size - 2 - 1];
+ int size = socketAddress.Size - 2;
+ byte [] bytes = new byte [size];
for (int i = 0; i < bytes.Length; i++) {
bytes [i] = socketAddress [i + 2];
+ // There may be junk after the null terminator, so ignore it all.
+ if (bytes [i] == 0) {
+ size = i;
+ break;
+ }
}
- string name = Encoding.Default.GetString (bytes);
+ string name = Encoding.Default.GetString (bytes, 0, size);
return new UnixEndPoint (name);
}
--- /dev/null
+// UnixEndPointTest.cs: Unit tests for Mono.Unix.UnixListener
+//
+// Authors:
+// David Lechner (david@lechnology.com)
+//
+// (c) 2015 David Lechner
+//
+
+using System;
+using System.IO;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+
+using NUnit.Framework;
+using Mono.Unix;
+
+namespace MonoTests.Mono.Unix {
+
+ [TestFixture]
+ public class UnixEndPointTest {
+
+ // Regression test for https://bugzilla.xamarin.com/show_bug.cgi?id=35004
+ [Test]
+ public void TestCreate ()
+ {
+ const string socketFile = "test";
+ // mangledSocketFile simulates the socket file name with a null
+ // terminator and junk after the null terminator. This can be present
+ // in a SocketAddress when marshaled from native code.
+ const string mangledSocketFile = socketFile + "\0junk";
+
+ var bytes = Encoding.Default.GetBytes (mangledSocketFile);
+ var socketAddress = new SocketAddress (AddressFamily.Unix, bytes.Length + 2);
+ for (int i = 0; i < bytes.Length; i++) {
+ socketAddress [i + 2] = bytes [i];
+ }
+ var dummyEndPoint = new UnixEndPoint (socketFile);
+
+ // testing that the Create() method strips off the null terminator and the junk
+ var endPoint = (UnixEndPoint)dummyEndPoint.Create (socketAddress);
+ Assert.AreEqual (socketFile, endPoint.Filename, "#A01");
+ }
+ }
+}
--- /dev/null
+// UnixListenerTest.cs: Unit tests for Mono.Unix.UnixListener
+//
+// Authors:
+// David Lechner (david@lechnology.com)
+//
+// (c) 2015 David Lechner
+//
+
+using System;
+using System.IO;
+
+using NUnit.Framework;
+using Mono.Unix;
+
+namespace MonoTests.Mono.Unix {
+
+ [TestFixture]
+ public class UnixListenerTest {
+
+ // test that a socket file is created and deleted by the UnixListener
+ [Test]
+ public void TestSocketFileCreateDelete ()
+ {
+ var socketFile = Path.GetTempFileName ();
+ // we just want the file name, not the file
+ File.Delete (socketFile);
+
+ using (var listener = new UnixListener (socketFile)) {
+ // creating an instance of UnixListener should create the file
+ Assert.IsTrue (File.Exists (socketFile), "#A01");
+ }
+ // and disposing the UnixListener should delete the file
+ Assert.IsFalse (File.Exists (socketFile), "#A02");
+ }
+ }
+}
MDTable tabIx = (MDTable)i;
if (count > max5BitSmlIx) {
+ if (tabIx == MDTable.Method || tabIx == MDTable.Field || tabIx == MDTable.TypeRef ||
+ tabIx == MDTable.TypeDef || tabIx == MDTable.Param || tabIx == MDTable.InterfaceImpl ||
+ tabIx == MDTable.MemberRef || tabIx == MDTable.Module || tabIx == MDTable.DeclSecurity ||
+ tabIx == MDTable.Property || tabIx == MDTable.Event || tabIx == MDTable.StandAloneSig ||
+ tabIx == MDTable.ModuleRef || tabIx == MDTable.TypeSpec || tabIx == MDTable.Assembly ||
+ tabIx == MDTable.AssemblyRef || tabIx == MDTable.File || tabIx == MDTable.ExportedType ||
+ tabIx == MDTable.ManifestResource || tabIx == MDTable.GenericParam)
lgeCIx[(int)CIx.HasCustomAttr] = true;
}
if (count > max3BitSmlIx) {
- if ((tabIx == MDTable.TypeRef) || (tabIx == MDTable.ModuleRef) || (tabIx == MDTable.Method) || (tabIx == MDTable.TypeSpec) || (tabIx == MDTable.Field))
+ if (tabIx == MDTable.Method || tabIx == MDTable.MemberRef)
lgeCIx[(int)CIx.CustomAttributeType] = true;
- if ((tabIx == MDTable.Method) || (tabIx == MDTable.MemberRef))
+ if (tabIx == MDTable.TypeDef || tabIx == MDTable.TypeRef || tabIx == MDTable.ModuleRef ||
+ tabIx == MDTable.Method || tabIx == MDTable.TypeSpec)
lgeCIx[(int)CIx.MemberRefParent] = true;
}
if (count > max2BitSmlIx) {
{
if (value == null)
throw new ArgumentNullException ("value");
- return Convert.ToUInt16 (((JsonPrimitive) value).Value, NumberFormatInfo.InvariantInfo);
+ return Convert.ToUInt32 (((JsonPrimitive) value).Value, NumberFormatInfo.InvariantInfo);
}
public static implicit operator ulong (JsonValue value)
Assert.AreEqual (number, jvalue); // should be exactly the same
}
+ [Test]
+ public void CheckIntegers ()
+ {
+ Assert.AreEqual (sbyte.MinValue, (sbyte) JsonValue.Parse (new JsonPrimitive (sbyte.MinValue).ToString ()));
+ Assert.AreEqual (sbyte.MaxValue, (sbyte) JsonValue.Parse (new JsonPrimitive (sbyte.MaxValue).ToString ()));
+ Assert.AreEqual (byte.MinValue, (byte) JsonValue.Parse (new JsonPrimitive (byte.MinValue).ToString ()));
+ Assert.AreEqual (byte.MaxValue, (byte) JsonValue.Parse (new JsonPrimitive (byte.MaxValue).ToString ()));
+
+ Assert.AreEqual (short.MinValue, (short) JsonValue.Parse (new JsonPrimitive (short.MinValue).ToString ()));
+ Assert.AreEqual (short.MaxValue, (short) JsonValue.Parse (new JsonPrimitive (short.MaxValue).ToString ()));
+ Assert.AreEqual (ushort.MinValue, (ushort) JsonValue.Parse (new JsonPrimitive (ushort.MinValue).ToString ()));
+ Assert.AreEqual (ushort.MaxValue, (ushort) JsonValue.Parse (new JsonPrimitive (ushort.MaxValue).ToString ()));
+
+ Assert.AreEqual (int.MinValue, (int) JsonValue.Parse (new JsonPrimitive (int.MinValue).ToString ()));
+ Assert.AreEqual (int.MaxValue, (int) JsonValue.Parse (new JsonPrimitive (int.MaxValue).ToString ()));
+ Assert.AreEqual (uint.MinValue, (uint) JsonValue.Parse (new JsonPrimitive (uint.MinValue).ToString ()));
+ Assert.AreEqual (uint.MaxValue, (uint) JsonValue.Parse (new JsonPrimitive (uint.MaxValue).ToString ()));
+
+ Assert.AreEqual (long.MinValue, (long) JsonValue.Parse (new JsonPrimitive (long.MinValue).ToString ()));
+ Assert.AreEqual (long.MaxValue, (long) JsonValue.Parse (new JsonPrimitive (long.MaxValue).ToString ()));
+ Assert.AreEqual (ulong.MinValue, (ulong) JsonValue.Parse (new JsonPrimitive (ulong.MinValue).ToString ()));
+ Assert.AreEqual (ulong.MaxValue, (ulong) JsonValue.Parse (new JsonPrimitive (ulong.MaxValue).ToString ()));
+ }
+
[Test]
public void CheckNumbers ()
{
}
}
}
+
+// vim: noexpandtab
+// Local Variables:
+// tab-width: 4
+// c-basic-offset: 4
+// indent-tabs-mode: t
+// End:
int readWriteTimeout;
RemoteCertificateValidationCallback serverCertificateValidationCallback;
bool unsafeAuthenticatedConnectionSharing;
+ X509CertificateCollection clientCertificates;
public WebRequestHandler ()
{
readWriteTimeout = 300000;
serverCertificateValidationCallback = null;
unsafeAuthenticatedConnectionSharing = false;
+ clientCertificates = new X509CertificateCollection();
}
public bool AllowPipelining {
}
}
- [MonoTODO]
public X509CertificateCollection ClientCertificates {
- get { throw new NotImplementedException (); }
+ get {
+ if (this.ClientCertificateOptions != ClientCertificateOption.Manual) {
+ throw new InvalidOperationException("The ClientCertificateOptions property must be set to 'Manual' to use this property.");
+ }
+
+ return clientCertificates;
+ }
}
[MonoTODO]
}
}
- [MonoTODO]
public RemoteCertificateValidationCallback ServerCertificateValidationCallback {
get { return serverCertificateValidationCallback; }
set {
wr.MaximumResponseHeadersLength = maxResponseHeadersLength;
wr.ReadWriteTimeout = readWriteTimeout;
wr.UnsafeAuthenticatedConnectionSharing = unsafeAuthenticatedConnectionSharing;
+ wr.ServerCertificateValidationCallback = serverCertificateValidationCallback;
+
+ if (this.ClientCertificateOptions == ClientCertificateOption.Manual) {
+ wr.ClientCertificates = clientCertificates;
+ }
return wr;
}
private static RSA user;
private static RSA machine;
+ private readonly static object user_lock = new object ();
+ private readonly static object machine_lock = new object ();
private static RSA GetKey (DataProtectionScope scope)
{
switch (scope) {
case DataProtectionScope.CurrentUser:
if (user == null) {
- CspParameters csp = new CspParameters ();
- csp.KeyContainerName = "DAPI";
- user = new RSACryptoServiceProvider (1536, csp);
+ lock (user_lock) {
+ CspParameters csp = new CspParameters ();
+ csp.KeyContainerName = "DAPI";
+ user = new RSACryptoServiceProvider (1536, csp);
+ }
}
return user;
case DataProtectionScope.LocalMachine:
if (machine == null) {
- CspParameters csp = new CspParameters ();
- csp.KeyContainerName = "DAPI";
- csp.Flags = CspProviderFlags.UseMachineKeyStore;
- machine = new RSACryptoServiceProvider (1536, csp);
+ lock (machine_lock) {
+ CspParameters csp = new CspParameters ();
+ csp.KeyContainerName = "DAPI";
+ csp.Flags = CspProviderFlags.UseMachineKeyStore;
+ machine = new RSACryptoServiceProvider (1536, csp);
+ }
}
return machine;
default:
using NUnit.Framework;
using System;
+using System.Text;
+using System.Collections.Generic;
+using System.Threading.Tasks;
using System.Security.Cryptography;
namespace MonoTests.System.Security.Cryptography {
ProtectUnprotect (notMuchEntropy, DataProtectionScope.LocalMachine);
}
+ [Test] // https://bugzilla.xamarin.com/show_bug.cgi?id=38933
+ public void ProtectCurrentUserMultiThread ()
+ {
+ string data = "Hello World";
+ string entropy = "This is a long string with no meaningful content.";
+ var entropyBytes = Encoding.UTF8.GetBytes (entropy);
+ var dataBytes = Encoding.UTF8.GetBytes (data);
+ var tasks = new List<Task> ();
+
+ for (int i = 0; i < 20; i++)
+ {
+ tasks.Add (new Task (() => {
+ byte[] encryptedBytes = ProtectedData.Protect (dataBytes, entropyBytes, DataProtectionScope.CurrentUser);
+ Assert.IsFalse (IsEmpty (encryptedBytes), "#1");
+
+ byte[] decryptedBytes = ProtectedData.Unprotect (encryptedBytes, entropyBytes, DataProtectionScope.CurrentUser);
+ string decryptedString = Encoding.UTF8.GetString(decryptedBytes);
+ Assert.AreEqual (data, decryptedString, "#2");
+ }, TaskCreationOptions.LongRunning));
+ }
+
+ foreach (var t in tasks) t.Start ();
+ Task.WaitAll (tasks.ToArray ());
+ }
+
[Test]
public void DataProtectionScope_All ()
{
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
<ItemGroup>\r
<Compile Include="..\..\build\common\Consts.cs" />\r
- <Compile Include="..\..\build\common\MonoTODOAttribute.cs" />\r
<Compile Include="Assembly\AssemblyInfo.cs" />\r </ItemGroup>\r
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. \r
Other similar extension points exist, see Microsoft.Common.targets.\r
../../build/common/Consts.cs
-../../build/common/MonoTODOAttribute.cs
Assembly/AssemblyInfo.cs
+++ /dev/null
-//
-// HttpMethodConstraint.cs
-//
-// Author:
-// Atsushi Enomoto <atsushi@ximian.com>
-//
-// Copyright (C) 2008 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Runtime.CompilerServices;
-using System.Security.Permissions;
-using System.Web;
-
-namespace System.Web.Routing
-{
- [TypeForwardedFrom ("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
- [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- public class HttpMethodConstraint : IRouteConstraint
- {
- public HttpMethodConstraint (params string[] allowedMethods)
- {
- if (allowedMethods == null)
- throw new ArgumentNullException ("allowedMethods");
- AllowedMethods = allowedMethods;
- }
-
- public ICollection<string> AllowedMethods { get; private set; }
-
- bool IRouteConstraint.Match (HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
- {
- return Match (httpContext, route, parameterName, values, routeDirection);
- }
-
- protected virtual bool Match (HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
- {
- if (httpContext == null)
- throw new ArgumentNullException ("httpContext");
- if (route == null)
- throw new ArgumentNullException ("route");
- if (parameterName == null)
- throw new ArgumentNullException ("parameterName");
- if (values == null)
- throw new ArgumentNullException ("values");
-
- switch (routeDirection) {
- case RouteDirection.IncomingRequest:
- // LAMESPEC: .NET allows case-insensitive comparison, which violates RFC 2616
- return AllowedMethods.Contains (httpContext.Request.HttpMethod);
-
- case RouteDirection.UrlGeneration:
- // See: aspnetwebstack's WebAPI equivalent for details.
- object method;
-
- if (!values.TryGetValue (parameterName, out method))
- return true;
-
- // LAMESPEC: .NET allows case-insensitive comparison, which violates RFC 2616
- return AllowedMethods.Contains (Convert.ToString (method));
-
- default:
- throw new ArgumentException ("Invalid routeDirection: " + routeDirection);
- }
- }
- }
-}
+++ /dev/null
-//
-// System.Web.Compilation.BuildManager
-//
-// Authors:
-// Marek Habersack (mhabersack@novell.com)
-//
-// (C) 2009-2010 Novell, Inc (http://www.novell.com)
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.ComponentModel;
-using System.Text;
-using System.Web;
-using System.Web.UI;
-using System.Web.Compilation;
-
-namespace System.Web.Routing
-{
- public class PageRouteHandler : IRouteHandler
- {
- public bool CheckPhysicalUrlAccess { get; private set; }
-
- public string VirtualPath { get; private set; }
-
- public PageRouteHandler (string virtualPath)
- : this (virtualPath, true)
- {
- }
-
- public PageRouteHandler (string virtualPath, bool checkPhysicalUrlAccess)
- {
- if (String.IsNullOrEmpty (virtualPath) || !virtualPath.StartsWith ("~/"))
- throw new ArgumentException ("VirtualPath must be a non empty string starting with ~/", "virtualPath");
-
- VirtualPath = virtualPath;
- CheckPhysicalUrlAccess = checkPhysicalUrlAccess;
- }
-
- [MonoTODO ("Implement checking physical URL access")]
- public virtual IHttpHandler GetHttpHandler (RequestContext requestContext)
- {
- if (requestContext == null)
- throw new ArgumentNullException ("requestContext");
-
- string vpath = GetSubstitutedVirtualPath (requestContext);
- int idx = vpath.IndexOf ('?');
- if (idx > -1)
- vpath = vpath.Substring (0, idx);
-
- if (String.IsNullOrEmpty (vpath))
- return null;
-
- return BuildManager.CreateInstanceFromVirtualPath (vpath, typeof (Page)) as IHttpHandler;
- }
-
- public string GetSubstitutedVirtualPath (RequestContext requestContext)
- {
- if (requestContext == null)
- throw new ArgumentNullException ("requestContext");
-
- RouteData rd = requestContext.RouteData;
- Route route = rd != null ? rd.Route as Route: null;
- if (route == null)
- return VirtualPath;
-
- VirtualPathData vpd = new Route (VirtualPath.Substring (2), this).GetVirtualPath (requestContext, rd.Values);
- if (vpd == null)
- return VirtualPath;
-
- return "~/" + vpd.VirtualPath;
- }
- }
-}
+++ /dev/null
-//
-// PatternParser.cs
-//
-// Author:
-// Atsushi Enomoto <atsushi@ximian.com>
-// Marek Habersack <mhabersack@novell.com>
-//
-// Copyright (C) 2008-2010 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Collections.Generic;
-using System.Security.Permissions;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Web;
-using System.Web.Util;
-using System.Diagnostics;
-using System.Globalization;
-
-namespace System.Web.Routing
-{
- sealed class PatternParser
- {
- struct PatternSegment
- {
- public bool AllLiteral;
- public List <PatternToken> Tokens;
- }
-
- static readonly char[] placeholderDelimiters = { '{', '}' };
-
- PatternSegment[] segments;
- Dictionary <string, bool> parameterNames;
- PatternToken[] tokens;
-
- int segmentCount;
- bool haveSegmentWithCatchAll;
-
- public string Url {
- get;
- private set;
- }
-
- public PatternParser (string pattern)
- {
- this.Url = pattern;
- Parse ();
- }
-
- void Parse ()
- {
- string url = Url;
- parameterNames = new Dictionary <string, bool> (StringComparer.OrdinalIgnoreCase);
-
- if (!String.IsNullOrEmpty (url)) {
- if (url [0] == '~' || url [0] == '/')
- throw new ArgumentException ("Url must not start with '~' or '/'");
- if (url.IndexOf ('?') >= 0)
- throw new ArgumentException ("Url must not contain '?'");
- } else {
- segments = new PatternSegment [0];
- tokens = new PatternToken [0];
- return;
- }
-
- string[] parts = url.Split ('/');
- int partsCount = segmentCount = parts.Length;
- var allTokens = new List <PatternToken> ();
- PatternToken tmpToken;
-
- segments = new PatternSegment [partsCount];
-
- for (int i = 0; i < partsCount; i++) {
- if (haveSegmentWithCatchAll)
- throw new ArgumentException ("A catch-all parameter can only appear as the last segment of the route URL");
-
- int catchAlls = 0;
- string part = parts [i];
- int partLength = part.Length;
- var tokens = new List <PatternToken> ();
-
- if (partLength == 0 && i < partsCount - 1)
- throw new ArgumentException ("Consecutive URL segment separators '/' are not allowed");
-
- if (part.IndexOf ("{}") != -1)
- throw new ArgumentException ("Empty URL parameter name is not allowed");
-
- if (i > 0)
- allTokens.Add (null);
-
- if (part.IndexOfAny (placeholderDelimiters) == -1) {
- // no placeholders here, short-circuit it
- tmpToken = new PatternToken (PatternTokenType.Literal, part);
- tokens.Add (tmpToken);
- allTokens.Add (tmpToken);
- segments [i].AllLiteral = true;
- segments [i].Tokens = tokens;
- continue;
- }
-
- string tmp;
- int from = 0, start;
- bool allLiteral = true;
- while (from < partLength) {
- start = part.IndexOf ('{', from);
- if (start >= partLength - 2)
- throw new ArgumentException ("Unterminated URL parameter. It must contain matching '}'");
-
- if (start < 0) {
- if (part.IndexOf ('}', from) >= from)
- throw new ArgumentException ("Unmatched URL parameter closer '}'. A corresponding '{' must precede");
- tmp = part.Substring (from);
- tmpToken = new PatternToken (PatternTokenType.Literal, tmp);
- tokens.Add (tmpToken);
- allTokens.Add (tmpToken);
- from += tmp.Length;
- break;
- }
-
- if (from == 0 && start > 0) {
- tmpToken = new PatternToken (PatternTokenType.Literal, part.Substring (0, start));
- tokens.Add (tmpToken);
- allTokens.Add (tmpToken);
- }
-
- int end = part.IndexOf ('}', start + 1);
- int next = part.IndexOf ('{', start + 1);
-
- if (end < 0 || next >= 0 && next < end)
- throw new ArgumentException ("Unterminated URL parameter. It must contain matching '}'");
- if (next == end + 1)
- throw new ArgumentException ("Two consecutive URL parameters are not allowed. Split into a different segment by '/', or a literal string.");
-
- if (next == -1)
- next = partLength;
-
- string token = part.Substring (start + 1, end - start - 1);
- PatternTokenType type;
- if (token [0] == '*') {
- catchAlls++;
- haveSegmentWithCatchAll = true;
- type = PatternTokenType.CatchAll;
- token = token.Substring (1);
- } else
- type = PatternTokenType.Standard;
-
- if (!parameterNames.ContainsKey (token))
- parameterNames.Add (token, true);
-
- tmpToken = new PatternToken (type, token);
- tokens.Add (tmpToken);
- allTokens.Add (tmpToken);
- allLiteral = false;
-
- if (end < partLength - 1) {
- token = part.Substring (end + 1, next - end - 1);
- tmpToken = new PatternToken (PatternTokenType.Literal, token);
- tokens.Add (tmpToken);
- allTokens.Add (tmpToken);
- end += token.Length;
- }
-
- if (catchAlls > 1 || (catchAlls == 1 && tokens.Count > 1))
- throw new ArgumentException ("A path segment that contains more than one section, such as a literal section or a parameter, cannot contain a catch-all parameter.");
- from = end + 1;
- }
-
- segments [i].AllLiteral = allLiteral;
- segments [i].Tokens = tokens;
- }
-
- if (allTokens.Count > 0)
- this.tokens = allTokens.ToArray ();
- allTokens = null;
- }
-
- RouteValueDictionary AddDefaults (RouteValueDictionary dict, RouteValueDictionary defaults)
- {
- if (defaults != null && defaults.Count > 0) {
- string key;
- foreach (var def in defaults) {
- key = def.Key;
- if (dict.ContainsKey (key))
- continue;
- dict.Add (key, def.Value);
- }
- }
-
- return dict;
- }
-
- static bool ParametersAreEqual (object a, object b)
- {
- if (a is string && b is string) {
- return String.Equals (a as string, b as string, StringComparison.OrdinalIgnoreCase);
- } else {
- // Parameter may be a boxed value type, need to use .Equals() for comparison
- return object.Equals (a, b);
- }
- }
-
- static bool ParameterIsNonEmpty (object param)
- {
- if (param is string)
- return !string.IsNullOrEmpty (param as string);
-
- return param != null;
- }
-
- bool IsParameterRequired (string parameterName, RouteValueDictionary defaultValues, out object defaultValue)
- {
- foreach (var token in tokens) {
- if (token == null)
- continue;
-
- if (string.Equals (token.Name, parameterName, StringComparison.OrdinalIgnoreCase)) {
- if (token.Type == PatternTokenType.CatchAll) {
- defaultValue = null;
- return false;
- }
- }
- }
-
- if (defaultValues == null)
- throw new ArgumentNullException ("defaultValues is null?!");
-
- return !defaultValues.TryGetValue (parameterName, out defaultValue);
- }
-
- static string EscapeReservedCharacters (Match m)
- {
- if (m == null)
- throw new ArgumentNullException("m");
-
- return Uri.HexEscape (m.Value[0]);
- }
-
- static string UriEncode (string str)
- {
- if (string.IsNullOrEmpty (str))
- return str;
-
- string escape = Uri.EscapeUriString (str);
- return Regex.Replace (escape, "([#?])", new MatchEvaluator (EscapeReservedCharacters));
- }
-
- bool MatchSegment (int segIndex, int argsCount, string[] argSegs, List <PatternToken> tokens, RouteValueDictionary ret)
- {
- string pathSegment = argSegs [segIndex];
- int pathSegmentLength = pathSegment != null ? pathSegment.Length : -1;
- int startIndex = pathSegmentLength - 1;
- PatternTokenType tokenType;
- int tokensCount = tokens.Count;
- PatternToken token;
- string tokenName;
-
- for (int tokenIndex = tokensCount - 1; tokenIndex > -1; tokenIndex--) {
- token = tokens [tokenIndex];
- if (startIndex < 0)
- return false;
-
- tokenType = token.Type;
- tokenName = token.Name;
-
- if (segIndex > segmentCount - 1 || tokenType == PatternTokenType.CatchAll) {
- var sb = new StringBuilder ();
-
- for (int j = segIndex; j < argsCount; j++) {
- if (j > segIndex)
- sb.Append ('/');
- sb.Append (argSegs [j]);
- }
-
- ret.Add (tokenName, sb.ToString ());
- break;
- }
-
- int scanIndex;
- if (token.Type == PatternTokenType.Literal) {
- int nameLen = tokenName.Length;
- if (startIndex + 1 < nameLen)
- return false;
- scanIndex = startIndex - nameLen + 1;
- if (String.Compare (pathSegment, scanIndex, tokenName, 0, nameLen, StringComparison.OrdinalIgnoreCase) != 0)
- return false;
- startIndex = scanIndex - 1;
- continue;
- }
-
- // Standard token
- int nextTokenIndex = tokenIndex - 1;
- if (nextTokenIndex < 0) {
- // First token
- ret.Add (tokenName, pathSegment.Substring (0, startIndex + 1));
- continue;
- }
-
- if (startIndex == 0)
- return false;
-
- var nextToken = tokens [nextTokenIndex];
- string nextTokenName = nextToken.Name;
-
- // Skip one char, since there can be no empty segments and if the
- // current token's value happens to be the same as preceeding
- // literal text, we'll save some time and complexity.
- scanIndex = startIndex - 1;
- int lastIndex = pathSegment.LastIndexOf (nextTokenName, scanIndex, StringComparison.OrdinalIgnoreCase);
- if (lastIndex == -1)
- return false;
-
- lastIndex += nextTokenName.Length - 1;
-
- string sectionValue = pathSegment.Substring (lastIndex + 1, startIndex - lastIndex);
- if (String.IsNullOrEmpty (sectionValue))
- return false;
-
- ret.Add (tokenName, sectionValue);
- startIndex = lastIndex;
- }
-
- return true;
- }
-
- public RouteValueDictionary Match (string path, RouteValueDictionary defaults)
- {
- var ret = new RouteValueDictionary ();
- string url = Url;
- string [] argSegs;
- int argsCount;
-
- if (String.IsNullOrEmpty (path)) {
- argSegs = null;
- argsCount = 0;
- } else {
- // quick check
- if (String.Compare (url, path, StringComparison.Ordinal) == 0 && url.IndexOf ('{') < 0)
- return AddDefaults (ret, defaults);
-
- argSegs = path.Split ('/');
- argsCount = argSegs.Length;
-
- if (String.IsNullOrEmpty (argSegs [argsCount - 1]))
- argsCount--; // path ends with a trailinig '/'
- }
- bool haveDefaults = defaults != null && defaults.Count > 0;
-
- if (argsCount == 1 && String.IsNullOrEmpty (argSegs [0]))
- argsCount = 0;
-
- if (!haveDefaults && ((haveSegmentWithCatchAll && argsCount < segmentCount) || (!haveSegmentWithCatchAll && argsCount != segmentCount)))
- return null;
-
- int i = 0;
-
- foreach (PatternSegment segment in segments) {
- if (i >= argsCount)
- break;
-
- if (segment.AllLiteral) {
- if (String.Compare (argSegs [i], segment.Tokens [0].Name, StringComparison.OrdinalIgnoreCase) != 0)
- return null;
- i++;
- continue;
- }
-
- if (!MatchSegment (i, argsCount, argSegs, segment.Tokens, ret))
- return null;
- i++;
- }
-
- // Check the remaining segments, if any, and see if they are required
- //
- // If a segment has more than one section (i.e. there's at least one
- // literal, then it cannot match defaults
- //
- // All of the remaining segments must have all defaults provided and they
- // must not be literals or the match will fail.
- if (i < segmentCount) {
- if (!haveDefaults)
- return null;
-
- for (;i < segmentCount; i++) {
- var segment = segments [i];
- if (segment.AllLiteral)
- return null;
-
- var tokens = segment.Tokens;
- if (tokens.Count != 1)
- return null;
-
- // if token is catch-all, we're done.
- if (tokens [0].Type == PatternTokenType.CatchAll)
- break;
-
- if (!defaults.ContainsKey (tokens [0].Name))
- return null;
- }
- } else if (!haveSegmentWithCatchAll && argsCount > segmentCount)
- return null;
-
- return AddDefaults (ret, defaults);
- }
-
- public string BuildUrl (Route route, RequestContext requestContext, RouteValueDictionary userValues, RouteValueDictionary constraints, out RouteValueDictionary usedValues)
- {
- usedValues = null;
-
- if (requestContext == null)
- return null;
-
- RouteData routeData = requestContext.RouteData;
- var currentValues = routeData.Values ?? new RouteValueDictionary ();
- var values = userValues ?? new RouteValueDictionary ();
- var defaultValues = (route != null ? route.Defaults : null) ?? new RouteValueDictionary ();
-
- // The set of values we should be using when generating the URL in this route
- var acceptedValues = new RouteValueDictionary ();
-
- // Keep track of which new values have been used
- HashSet<string> unusedNewValues = new HashSet<string> (values.Keys, StringComparer.OrdinalIgnoreCase);
-
- // This route building logic is based on System.Web.Http's Routing code (which is Apache Licensed by MS)
- // and which can be found at mono's external/aspnetwebstack/src/System.Web.Http/Routing/HttpParsedRoute.cs
- // Hopefully this will ensure a much higher compatiblity with MS.NET's System.Web.Routing logic. (pruiz)
-
- #region Step 1: Get the list of values we're going to use to match and generate this URL
- // Find out which entries in the URL are valid for the URL we want to generate.
- // If the URL had ordered parameters a="1", b="2", c="3" and the new values
- // specified that b="9", then we need to invalidate everything after it. The new
- // values should then be a="1", b="9", c=<no value>.
- foreach (var item in parameterNames) {
- var parameterName = item.Key;
-
- object newParameterValue;
- bool hasNewParameterValue = values.TryGetValue (parameterName, out newParameterValue);
- if (hasNewParameterValue) {
- unusedNewValues.Remove(parameterName);
- }
-
- object currentParameterValue;
- bool hasCurrentParameterValue = currentValues.TryGetValue (parameterName, out currentParameterValue);
-
- if (hasNewParameterValue && hasCurrentParameterValue) {
- if (!ParametersAreEqual (currentParameterValue, newParameterValue)) {
- // Stop copying current values when we find one that doesn't match
- break;
- }
- }
-
- // If the parameter is a match, add it to the list of values we will use for URL generation
- if (hasNewParameterValue) {
- if (ParameterIsNonEmpty (newParameterValue)) {
- acceptedValues.Add (parameterName, newParameterValue);
- }
- }
- else {
- if (hasCurrentParameterValue) {
- acceptedValues.Add (parameterName, currentParameterValue);
- }
- }
- }
-
- // Add all remaining new values to the list of values we will use for URL generation
- foreach (var newValue in values) {
- if (ParameterIsNonEmpty (newValue.Value) && !acceptedValues.ContainsKey (newValue.Key)) {
- acceptedValues.Add (newValue.Key, newValue.Value);
- }
- }
-
- // Add all current values that aren't in the URL at all
- foreach (var currentValue in currentValues) {
- if (!acceptedValues.ContainsKey (currentValue.Key) && !parameterNames.ContainsKey (currentValue.Key)) {
- acceptedValues.Add (currentValue.Key, currentValue.Value);
- }
- }
-
- // Add all remaining default values from the route to the list of values we will use for URL generation
- foreach (var item in parameterNames) {
- object defaultValue;
- if (!acceptedValues.ContainsKey (item.Key) && !IsParameterRequired (item.Key, defaultValues, out defaultValue)) {
- // Add the default value only if there isn't already a new value for it and
- // only if it actually has a default value, which we determine based on whether
- // the parameter value is required.
- acceptedValues.Add (item.Key, defaultValue);
- }
- }
-
- // All required parameters in this URL must have values from somewhere (i.e. the accepted values)
- foreach (var item in parameterNames) {
- object defaultValue;
- if (IsParameterRequired (item.Key, defaultValues, out defaultValue) && !acceptedValues.ContainsKey (item.Key)) {
- // If the route parameter value is required that means there's
- // no default value, so if there wasn't a new value for it
- // either, this route won't match.
- return null;
- }
- }
-
- // All other default values must match if they are explicitly defined in the new values
- var otherDefaultValues = new RouteValueDictionary (defaultValues);
- foreach (var item in parameterNames) {
- otherDefaultValues.Remove (item.Key);
- }
-
- foreach (var defaultValue in otherDefaultValues) {
- object value;
- if (values.TryGetValue (defaultValue.Key, out value)) {
- unusedNewValues.Remove (defaultValue.Key);
- if (!ParametersAreEqual (value, defaultValue.Value)) {
- // If there is a non-parameterized value in the route and there is a
- // new value for it and it doesn't match, this route won't match.
- return null;
- }
- }
- }
- #endregion
-
- #region Step 2: If the route is a match generate the appropriate URL
-
- var uri = new StringBuilder ();
- var pendingParts = new StringBuilder ();
- var pendingPartsAreAllSafe = false;
- bool blockAllUriAppends = false;
- var allSegments = new List<PatternSegment?> ();
-
- // Build a list of segments plus separators we can use as template.
- foreach (var segment in segments) {
- if (allSegments.Count > 0)
- allSegments.Add (null); // separator exposed as null.
- allSegments.Add (segment);
- }
-
- // Finally loop thru al segment-templates building the actual uri.
- foreach (var item in allSegments) {
- var segment = item.GetValueOrDefault ();
-
- // If segment is a separator..
- if (item == null) {
- if (pendingPartsAreAllSafe) {
- // Accept
- if (pendingParts.Length > 0) {
- if (blockAllUriAppends)
- return null;
-
- // Append any pending literals to the URL
- uri.Append (pendingParts.ToString ());
- pendingParts.Length = 0;
- }
- }
- pendingPartsAreAllSafe = false;
-
- // Guard against appending multiple separators for empty segments
- if (pendingParts.Length > 0 && pendingParts[pendingParts.Length - 1] == '/') {
- // Dev10 676725: Route should not be matched if that causes mismatched tokens
- // Dev11 86819: We will allow empty matches if all subsequent segments are null
- if (blockAllUriAppends)
- return null;
-
- // Append any pending literals to the URI (without the trailing slash) and prevent any future appends
- uri.Append(pendingParts.ToString (0, pendingParts.Length - 1));
- pendingParts.Length = 0;
- } else {
- pendingParts.Append ("/");
- }
-#if false
- } else if (segment.AllLiteral) {
- // Spezial (optimized) case: all elements of segment are literals.
- pendingPartsAreAllSafe = true;
- foreach (var tk in segment.Tokens)
- pendingParts.Append (tk.Name);
-#endif
- } else {
- // Segments are treated as all-or-none. We should never output a partial segment.
- // If we add any subsegment of this segment to the generated URL, we have to add
- // the complete match. For example, if the subsegment is "{p1}-{p2}.xml" and we
- // used a value for {p1}, we have to output the entire segment up to the next "/".
- // Otherwise we could end up with the partial segment "v1" instead of the entire
- // segment "v1-v2.xml".
- bool addedAnySubsegments = false;
-
- foreach (var token in segment.Tokens) {
- if (token.Type == PatternTokenType.Literal) {
- // If it's a literal we hold on to it until we are sure we need to add it
- pendingPartsAreAllSafe = true;
- pendingParts.Append (token.Name);
- } else {
- if (token.Type == PatternTokenType.Standard || token.Type == PatternTokenType.CatchAll) {
- if (pendingPartsAreAllSafe) {
- // Accept
- if (pendingParts.Length > 0) {
- if (blockAllUriAppends)
- return null;
-
- // Append any pending literals to the URL
- uri.Append (pendingParts.ToString ());
- pendingParts.Length = 0;
-
- addedAnySubsegments = true;
- }
- }
- pendingPartsAreAllSafe = false;
-
- // If it's a parameter, get its value
- object acceptedParameterValue;
- bool hasAcceptedParameterValue = acceptedValues.TryGetValue (token.Name, out acceptedParameterValue);
- if (hasAcceptedParameterValue)
- unusedNewValues.Remove (token.Name);
-
- object defaultParameterValue;
- defaultValues.TryGetValue (token.Name, out defaultParameterValue);
-
- if (ParametersAreEqual (acceptedParameterValue, defaultParameterValue)) {
- // If the accepted value is the same as the default value, mark it as pending since
- // we won't necessarily add it to the URL we generate.
- pendingParts.Append (Convert.ToString (acceptedParameterValue, CultureInfo.InvariantCulture));
- } else {
- if (blockAllUriAppends)
- return null;
-
- // Add the new part to the URL as well as any pending parts
- if (pendingParts.Length > 0) {
- // Append any pending literals to the URL
- uri.Append (pendingParts.ToString ());
- pendingParts.Length = 0;
- }
- uri.Append (Convert.ToString (acceptedParameterValue, CultureInfo.InvariantCulture));
-
- addedAnySubsegments = true;
- }
- } else {
- Debug.Fail ("Invalid path subsegment type");
- }
- }
- }
-
- if (addedAnySubsegments) {
- // See comment above about why we add the pending parts
- if (pendingParts.Length > 0) {
- if (blockAllUriAppends)
- return null;
-
- // Append any pending literals to the URL
- uri.Append (pendingParts.ToString ());
- pendingParts.Length = 0;
- }
- }
- }
- }
-
- if (pendingPartsAreAllSafe) {
- // Accept
- if (pendingParts.Length > 0) {
- if (blockAllUriAppends)
- return null;
-
- // Append any pending literals to the URI
- uri.Append (pendingParts.ToString ());
- }
- }
-
- // Process constraints keys
- if (constraints != null) {
- // If there are any constraints, mark all the keys as being used so that we don't
- // generate query string items for custom constraints that don't appear as parameters
- // in the URI format.
- foreach (var constraintsItem in constraints) {
- unusedNewValues.Remove (constraintsItem.Key);
- }
- }
-
- // Encode the URI before we append the query string, otherwise we would double encode the query string
- var encodedUri = new StringBuilder ();
- encodedUri.Append (UriEncode (uri.ToString ()));
- uri = encodedUri;
-
- // Add remaining new values as query string parameters to the URI
- if (unusedNewValues.Count > 0) {
- // Generate the query string
- bool firstParam = true;
- foreach (string unusedNewValue in unusedNewValues) {
- object value;
- if (acceptedValues.TryGetValue (unusedNewValue, out value)) {
- uri.Append (firstParam ? '?' : '&');
- firstParam = false;
- uri.Append (Uri.EscapeDataString (unusedNewValue));
- uri.Append ('=');
- uri.Append (Uri.EscapeDataString (Convert.ToString (value, CultureInfo.InvariantCulture)));
- }
- }
- }
-
- #endregion
-
- usedValues = acceptedValues;
- return uri.ToString();
- }
- }
-}
-
+++ /dev/null
-//
-// PatternToken.cs
-//
-// Author:
-// Marek Habersack <mhabersack@novell.com>
-//
-// Copyright (C) 2009 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Text;
-using System.Web;
-
-namespace System.Web.Routing
-{
- sealed class PatternToken
- {
- public PatternTokenType Type {
- get;
- private set;
- }
-
- public string Name {
- get;
- private set;
- }
-
- public PatternToken (PatternTokenType type, string name)
- {
- this.Type = type;
- this.Name = name;
- }
-
- public override string ToString ()
- {
- StringBuilder sb = new StringBuilder ();
-
- switch (Type) {
- case PatternTokenType.Standard:
- sb.Append ("PatternToken_Standard");
- break;
-
- case PatternTokenType.Literal:
- sb.Append ("PatternToken_Literal");
- break;
-
- case PatternTokenType.CatchAll:
- sb.Append ("PatternToken_CatchAll");
- break;
-
- default:
- sb.Append ("PatternToken_UNKNOWN");
- break;
- }
-
- sb.AppendFormat (" [Name = '{0}']", Name);
-
- return sb.ToString ();
- }
- }
-}
+++ /dev/null
-//
-// PatternTokenType.cs
-//
-// Author:
-// Marek Habersack <mhabersack@novell.com>
-//
-// Copyright (C) 2009 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-
-namespace System.Web.Routing
-{
- enum PatternTokenType
- {
- Standard,
- Literal,
- CatchAll
- }
-}
+++ /dev/null
-//
-// Route.cs
-//
-// Author:
-// Atsushi Enomoto <atsushi@ximian.com>
-//
-// Copyright (C) 2008 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Runtime.CompilerServices;
-using System.Security.Permissions;
-using System.Text.RegularExpressions;
-using System.Web;
-using System.Globalization;
-
-namespace System.Web.Routing
-{
- [TypeForwardedFrom ("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
- [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- public class Route : RouteBase
- {
- static readonly Type httpRequestBaseType = typeof (HttpRequestBase);
- PatternParser url;
-
- public RouteValueDictionary Constraints { get; set; }
-
- public RouteValueDictionary DataTokens { get; set; }
-
- public RouteValueDictionary Defaults { get; set; }
-
- public IRouteHandler RouteHandler { get; set; }
-
- public string Url {
- get { return url != null ? url.Url : String.Empty; }
- set { url = value != null ? new PatternParser (value) : new PatternParser (String.Empty); }
- }
-
- public Route (string url, IRouteHandler routeHandler)
- : this (url, null, routeHandler)
- {
- }
-
- public Route (string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
- : this (url, defaults, null, routeHandler)
- {
- }
-
- public Route (string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
- : this (url, defaults, constraints, null, routeHandler)
- {
- }
-
- public Route (string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler)
- {
- Url = url;
- Defaults = defaults;
- Constraints = constraints;
- DataTokens = dataTokens;
- RouteHandler = routeHandler;
- }
-
- public override RouteData GetRouteData (HttpContextBase httpContext)
- {
- var path = httpContext.Request.AppRelativeCurrentExecutionFilePath;
- var pathInfo = httpContext.Request.PathInfo;
-
- if (!String.IsNullOrEmpty (pathInfo))
- path += pathInfo;
-
- // probably code like this causes ArgumentOutOfRangeException under .NET.
- // It somehow allows such path that is completely equivalent to the Url. Dunno why.
- if (Url != path && path.Substring (0, 2) != "~/")
- return null;
- path = path.Substring (2);
-
- var values = url.Match (path, Defaults);
- if (values == null)
- return null;
-
- if (!ProcessConstraints (httpContext, values, RouteDirection.IncomingRequest))
- return null;
-
- var rd = new RouteData (this, RouteHandler);
- RouteValueDictionary rdValues = rd.Values;
-
- foreach (var p in values)
- rdValues.Add (p.Key, p.Value);
-
- RouteValueDictionary dataTokens = DataTokens;
- if (dataTokens != null) {
- RouteValueDictionary rdDataTokens = rd.DataTokens;
- foreach (var token in dataTokens)
- rdDataTokens.Add (token.Key, token.Value);
- }
-
- return rd;
- }
-
- public override VirtualPathData GetVirtualPath (RequestContext requestContext, RouteValueDictionary values)
- {
- if (requestContext == null)
- throw new ArgumentNullException ("requestContext");
- if (url == null)
- return new VirtualPathData (this, String.Empty);
-
- // null values is allowed.
- // if (values == null)
- // values = requestContext.RouteData.Values;
-
- RouteValueDictionary usedValues;
- string resultUrl = url.BuildUrl (this, requestContext, values, Constraints, out usedValues);
-
- if (resultUrl == null)
- return null;
-
- if (!ProcessConstraints (requestContext.HttpContext, usedValues, RouteDirection.UrlGeneration))
- return null;
-
- var result = new VirtualPathData (this, resultUrl);
-
- RouteValueDictionary dataTokens = DataTokens;
- if (dataTokens != null) {
- foreach (var item in dataTokens)
- result.DataTokens[item.Key] = item.Value;
- }
-
- return result;
- }
-
- private bool ProcessConstraintInternal (HttpContextBase httpContext, Route route, object constraint, string parameterName,
- RouteValueDictionary values, RouteDirection routeDirection, RequestContext reqContext,
- out bool invalidConstraint)
- {
- invalidConstraint = false;
- IRouteConstraint irc = constraint as IRouteConstraint;
- if (irc != null)
- return irc.Match (httpContext, route, parameterName, values, routeDirection);
-
- string s = constraint as string;
- if (s != null) {
- string v = null;
- object o;
-
- // NOTE: If constraint was not an IRouteConstraint, is is asumed
- // to be an object 'convertible' to string, or at least this is how
- // ASP.NET seems to work by the tests i've done latelly. (pruiz)
-
- if (values != null && values.TryGetValue (parameterName, out o))
- v = Convert.ToString (o, CultureInfo.InvariantCulture);
-
- if (!String.IsNullOrEmpty (v))
- return MatchConstraintRegex (v, s);
- else if (reqContext != null) {
- RouteData rd = reqContext != null ? reqContext.RouteData : null;
- RouteValueDictionary rdValues = rd != null ? rd.Values : null;
-
- if (rdValues == null || rdValues.Count == 0)
- return false;
-
- if (!rdValues.TryGetValue (parameterName, out o))
- return false;
-
- v = Convert.ToString (o, CultureInfo.InvariantCulture);
- if (String.IsNullOrEmpty (v))
- return false;
-
- return MatchConstraintRegex (v, s);
- }
- return false;
- }
-
- invalidConstraint = true;
- return false;
- }
-
- static bool MatchConstraintRegex (string value, string constraint)
- {
- int len = constraint.Length;
- if (len > 0) {
- // Bug #651966 - regexp constraints must be treated
- // as absolute expressions
- if (constraint [0] != '^') {
- constraint = "^" + constraint;
- len++;
- }
-
- if (constraint [len - 1] != '$')
- constraint += "$";
- }
-
- return Regex.IsMatch (value, constraint, RegexOptions.CultureInvariant | RegexOptions.IgnoreCase | RegexOptions.Compiled);
- }
-
- protected virtual bool ProcessConstraint (HttpContextBase httpContext, object constraint, string parameterName, RouteValueDictionary values, RouteDirection routeDirection)
- {
- if (parameterName == null)
- throw new ArgumentNullException ("parameterName");
-
- // .NET "compatibility"
- if (values == null)
- throw new NullReferenceException ();
-
- RequestContext reqContext;
- reqContext = SafeGetContext (httpContext != null ? httpContext.Request : null);
- bool invalidConstraint;
- bool ret = ProcessConstraintInternal (httpContext, this, constraint, parameterName, values, routeDirection, reqContext, out invalidConstraint);
-
- if (invalidConstraint)
- throw new InvalidOperationException (
- String.Format (
- "Constraint parameter '{0}' on the route with URL '{1}' must have a string value type or be a type which implements IRouteConstraint",
- parameterName, Url
- )
- );
-
- return ret;
- }
-
- private bool ProcessConstraints (HttpContextBase httpContext, RouteValueDictionary values, RouteDirection routeDirection)
- {
- var constraints = Constraints;
-
- if (Constraints != null) {
- foreach (var p in constraints)
- if (!ProcessConstraint (httpContext, p.Value, p.Key, values, routeDirection))
- return false;
- }
-
- return true;
- }
-
- RequestContext SafeGetContext (HttpRequestBase req)
- {
- if (req == null || req.GetType () != httpRequestBaseType)
- return null;
-
- return req.RequestContext;
- }
- }
-}
+++ /dev/null
-//
-// RouteCollection.cs
-//
-// Author:
-// Atsushi Enomoto <atsushi@ximian.com>
-//
-// Copyright (C) 2008 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.IO;
-using System.Runtime.CompilerServices;
-using System.Security.Permissions;
-using System.Web;
-using System.Web.Hosting;
-
-namespace System.Web.Routing
-{
- [TypeForwardedFrom ("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
- [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- public class RouteCollection : Collection<RouteBase>
- {
- class Lock : IDisposable
- {
- //RouteCollection owner;
- //bool read;
-
- public Lock (RouteCollection owner, bool read)
- {
- //this.owner = owner;
- //this.read = read;
- }
-
- public void Dispose ()
- {
- //if (read)
- // owner.read_lock = null;
- //else
- // owner_write_lock = null;
- }
- }
-
- public RouteCollection ()
- : this (null)
- {
- }
-
- public RouteCollection (VirtualPathProvider virtualPathProvider)
- {
- // null argument is allowed
- //provider = virtualPathProvider;
-
- read_lock = new Lock (this, true);
- write_lock = new Lock (this, false);
- }
-
- //VirtualPathProvider provider;
- Dictionary<string,RouteBase> d = new Dictionary<string,RouteBase> ();
-
- Lock read_lock, write_lock;
-
- public RouteBase this [string name] {
- get {
- foreach (var p in d)
- if (p.Key == name)
- return p.Value;
- return null;
- }
- }
-
- public bool LowercaseUrls { get; set; }
- public bool AppendTrailingSlash { get; set; }
- public bool RouteExistingFiles { get; set; }
-
- public void Add (string name, RouteBase item)
- {
- lock (GetWriteLock ()) {
- base.Add (item);
- if (!String.IsNullOrEmpty (name))
- d.Add (name, item);
- }
- }
-
- protected override void ClearItems ()
- {
- lock (GetWriteLock ()) {
- base.ClearItems ();
- d.Clear ();
- }
- }
-
- public IDisposable GetReadLock ()
- {
- return read_lock;
- }
-
- public RouteData GetRouteData (HttpContextBase httpContext)
- {
- if (httpContext == null)
- throw new ArgumentNullException ("httpContext");
-
- if (httpContext.Request == null)
- throw new ArgumentException ("The context does not contain any request data.", "httpContext");
- if (Count == 0)
- return null;
- if (!RouteExistingFiles) {
- var path = httpContext.Request.AppRelativeCurrentExecutionFilePath;
- VirtualPathProvider vpp = HostingEnvironment.VirtualPathProvider;
- if (path != "~/" && vpp != null && (vpp.FileExists (path) || vpp.DirectoryExists (path)))
- return null;
- }
- foreach (RouteBase rb in this) {
- var rd = rb.GetRouteData (httpContext);
- if (rd != null)
- return rd;
- }
-
- return null;
- }
-
- public VirtualPathData GetVirtualPath (RequestContext requestContext, RouteValueDictionary values)
- {
- return GetVirtualPath (requestContext, null, values);
- }
-
- public VirtualPathData GetVirtualPath (RequestContext requestContext, string name, RouteValueDictionary values)
- {
- if (requestContext == null)
- throw new ArgumentNullException ("httpContext");
- VirtualPathData vp = null;
- if (!String.IsNullOrEmpty (name)) {
- RouteBase rb = this [name];
- if (rb != null)
- vp = rb.GetVirtualPath (requestContext, values);
- else
- throw new ArgumentException ("A route named '" + name + "' could not be found in the route collection.", "name");
- } else {
- foreach (RouteBase rb in this) {
- vp = rb.GetVirtualPath (requestContext, values);
- if (vp != null)
- break;
- }
- }
-
- if (vp != null) {
- string appPath = requestContext.HttpContext.Request.ApplicationPath;
- if (appPath != null && (appPath.Length == 0 || !appPath.EndsWith ("/", StringComparison.Ordinal)))
- appPath += "/";
-
- string pathWithApp = String.Concat (appPath, vp.VirtualPath);
- vp.VirtualPath = requestContext.HttpContext.Response.ApplyAppPathModifier (pathWithApp);
- return vp;
- }
-
- return null;
- }
-
- public IDisposable GetWriteLock ()
- {
- return write_lock;
- }
- public void Ignore (string url)
- {
- Ignore (url, null);
- }
-
- public void Ignore (string url, object constraints)
- {
- if (url == null)
- throw new ArgumentNullException ("url");
-
- Add (new Route (url, null, new RouteValueDictionary (constraints), new StopRoutingHandler ()));
- }
-
- public Route MapPageRoute (string routeName, string routeUrl, string physicalFile)
- {
- return MapPageRoute (routeName, routeUrl, physicalFile, true, null, null, null);
- }
-
- public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess)
- {
- return MapPageRoute (routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, null, null, null);
- }
-
- public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess,
- RouteValueDictionary defaults)
- {
- return MapPageRoute (routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, defaults, null, null);
- }
-
- public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess,
- RouteValueDictionary defaults, RouteValueDictionary constraints)
- {
- return MapPageRoute (routeName, routeUrl, physicalFile, checkPhysicalUrlAccess, defaults, constraints, null);
- }
-
- public Route MapPageRoute (string routeName, string routeUrl, string physicalFile, bool checkPhysicalUrlAccess,
- RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens)
- {
- if (routeUrl == null)
- throw new ArgumentNullException ("routeUrl");
-
- var route = new Route (routeUrl, defaults, constraints, dataTokens, new PageRouteHandler (physicalFile, checkPhysicalUrlAccess));
- Add (routeName, route);
-
- return route;
- }
- protected override void InsertItem (int index, RouteBase item)
- {
- // FIXME: what happens wrt its name?
- lock (GetWriteLock ())
- base.InsertItem (index, item);
- }
-
- protected override void RemoveItem (int index)
- {
- // FIXME: what happens wrt its name?
- lock (GetWriteLock ()) {
- string k = GetKey (index);
- base.RemoveItem (index);
- if (k != null)
- d.Remove (k);
- }
- }
-
- protected override void SetItem (int index, RouteBase item)
- {
- // FIXME: what happens wrt its name?
- lock (GetWriteLock ()) {
- string k = GetKey (index);
- base.SetItem (index, item);
- if (k != null)
- d.Remove (k);
- }
- }
-
- string GetKey (int index)
- {
- var item = this [index];
- foreach (var p in d)
- if (p.Value == item)
- return p.Key;
- return null;
- }
- }
-}
+++ /dev/null
-//
-// PatternParser.cs
-//
-// Author:
-// Marek Habersack <mhabersack@novell.com>
-//
-// Copyright (C) 2009 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-#if SYSTEMCORE_DEP
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-
-namespace System.Web.Routing
-{
- static class RouteValueDictionaryExtensions
- {
- public static bool Has (this RouteValueDictionary dict, string key)
- {
- if (dict == null)
- return false;
-
- return dict.ContainsKey (key);
- }
-
- public static bool Has (this RouteValueDictionary dict, string key, object value)
- {
- if (dict == null)
- return false;
-
- object entryValue;
- if (dict.TryGetValue (key, out entryValue)) {
- if (value is string) {
- if (!(entryValue is string))
- return false;
-
- string s1 = value as string;
- string s2 = entryValue as string;
- return String.Compare (s1, s2, StringComparison.OrdinalIgnoreCase) == 0;
- }
-
- return entryValue == null ? value == null : entryValue.Equals (value);
- }
-
- return false;
- }
-
- public static bool GetValue (this RouteValueDictionary dict, string key, out object value)
- {
- if (dict == null) {
- value = null;
- return false;
- }
-
- return dict.TryGetValue (key, out value);
- }
-
- [Conditional ("DEBUG")]
- public static void Dump (this RouteValueDictionary dict, string name, string indent)
- {
- if (indent == null)
- indent = String.Empty;
-
- if (dict == null) {
- Console.WriteLine (indent + "Dictionary '{0}' is null", name);
- return;
- }
-
- if (dict.Count == 0) {
- Console.WriteLine (indent + "Dictionary '{0}' is empty", name);
- return;
- }
-
- Console.WriteLine (indent + "Dictionary '{0}':", name);
- foreach (var de in dict)
- Console.WriteLine (indent + "\t'{0}' == {1}", de.Key, de.Value);
- }
- }
-}
-#endif
+++ /dev/null
-//
-// UrlRoutingHandler.cs
-//
-// Author:
-// Atsushi Enomoto <atsushi@ximian.com>
-//
-// Copyright (C) 2008-2010 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Runtime.CompilerServices;
-using System.Security.Permissions;
-using System.Web;
-
-namespace System.Web.Routing
-{
- [TypeForwardedFrom ("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
- [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- public abstract class UrlRoutingHandler : IHttpHandler
- {
- RouteCollection routes;
-
- bool IHttpHandler.IsReusable {
- get { return IsReusable; }
- }
-
- protected virtual bool IsReusable { get { return false; } }
-
- public RouteCollection RouteCollection {
- get {
- if (routes == null)
- routes = RouteTable.Routes;
- return routes;
- }
- set { routes = value; }
- }
-
- void IHttpHandler.ProcessRequest (HttpContext context)
- {
- ProcessRequest (context);
- }
-
- protected virtual void ProcessRequest (HttpContext httpContext)
- {
- ProcessRequest (new HttpContextWrapper (httpContext));
- }
-
- protected virtual void ProcessRequest (HttpContextBase httpContext)
- {
- if (httpContext == null)
- throw new ArgumentNullException ("httpContext");
-
- var rd = RouteCollection.GetRouteData (httpContext);
- if (rd == null)
- throw new HttpException ("The incoming request does not match any route");
- if (rd.RouteHandler == null)
- throw new InvalidOperationException ("No IRouteHandler is assigned to the selected route");
-
- RequestContext rc = new RequestContext (httpContext, rd);
-
- var hh = rd.RouteHandler.GetHttpHandler (rc);
- VerifyAndProcessRequest (hh, httpContext);
- }
-
- protected abstract void VerifyAndProcessRequest (IHttpHandler httpHandler, HttpContextBase httpContext);
- }
-}
+++ /dev/null
-//
-// UrlRoutingModule.cs
-//
-// Author:
-// Atsushi Enomoto <atsushi@ximian.com>
-//
-// Copyright (C) 2008 Novell Inc. http://novell.com
-//
-
-//
-// Permission is hereby granted, free of charge, to any person obtaining
-// a copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to
-// permit persons to whom the Software is furnished to do so, subject to
-// the following conditions:
-//
-// The above copyright notice and this permission notice shall be
-// included in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-//
-using System;
-using System.Runtime.CompilerServices;
-using System.Security.Permissions;
-using System.Threading;
-using System.Web;
-
-namespace System.Web.Routing
-{
- [TypeForwardedFrom ("System.Web.Routing, Version=3.5.0.0, Culture=Neutral, PublicKeyToken=31bf3856ad364e35")]
- [AspNetHostingPermission (SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- [AspNetHostingPermission (SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
- public class UrlRoutingModule : IHttpModule
- {
- RouteCollection routes;
- public RouteCollection RouteCollection {
- get {
- if (routes == null)
- routes = RouteTable.Routes;
- return routes;
- }
- set { routes = value; }
- }
-
- protected virtual void Dispose ()
- {
- }
-
- void IHttpModule.Dispose ()
- {
- Dispose ();
- }
-
- void IHttpModule.Init (HttpApplication application)
- {
- Init (application);
- }
-
- protected virtual void Init (HttpApplication application)
- {
- application.PostMapRequestHandler += PostMapRequestHandler;
- application.PostResolveRequestCache += PostResolveRequestCache;
- }
-
- void PostMapRequestHandler (object o, EventArgs e)
- {
- var app = (HttpApplication) o;
- PostMapRequestHandler (new HttpContextWrapper (app.Context));
- }
-
- void PostResolveRequestCache (object o, EventArgs e)
- {
- var app = (HttpApplication) o;
- PostResolveRequestCache (new HttpContextWrapper (app.Context));
- }
- [Obsolete]
- public virtual void PostMapRequestHandler (HttpContextBase context)
- {
- }
-
- [MonoTODO]
- public virtual void PostResolveRequestCache (HttpContextBase context)
- {
- if (context == null)
- throw new ArgumentNullException ("context");
-
- var rd = RouteCollection.GetRouteData (context);
- if (rd == null)
- return; // do nothing
-
- if (rd.RouteHandler == null)
- throw new InvalidOperationException ("No IRouteHandler is assigned to the selected route");
-
- if (rd.RouteHandler is StopRoutingHandler)
- return; //stop further processing
-
- var rc = new RequestContext (context, rd);
-
- IHttpHandler http = rd.RouteHandler.GetHttpHandler (rc);
- if (http == null)
- throw new InvalidOperationException ("The mapped IRouteHandler did not return an IHttpHandler");
- context.Request.RequestContext = rc;
- context.RemapHandler (http);
- }
- }
-}
public sealed class FormsAuthenticationModule : IHttpModule
{
static readonly object authenticateEvent = new object ();
-
+
+ // Config values
+ private static bool _fAuthChecked;
+ private static bool _fAuthRequired;
+
AuthenticationSection _config = null;
bool isConfigInitialized = false;
EventHandlerList events = new EventHandlerList ();
-
+
+ internal static bool FormsAuthRequired {
+ get {
+ return _fAuthRequired;
+ }
+ }
+
public event FormsAuthenticationEventHandler Authenticate {
add { events.AddHandler (authenticateEvent, value); }
remove { events.RemoveHandler (authenticateEvent, value); }
if(isConfigInitialized)
return;
_config = (AuthenticationSection) WebConfigurationManager.GetSection ("system.web/authentication");
+
+ // authentication is an app level setting only
+ // so we can read app config early on in an attempt to try and
+ // skip wiring up event delegates
+ if (!_fAuthChecked) {
+ _fAuthRequired = (_config.Mode == AuthenticationMode.Forms);
+ _fAuthChecked = true;
+ }
isConfigInitialized = true;
}
public void Init (HttpApplication app)
{
+
app.AuthenticateRequest += new EventHandler (OnAuthenticateRequest);
app.EndRequest += new EventHandler (OnEndRequest);
}
return config == null ? true : config.IsValidUser (user, verb);
}
+
+ internal static void ReportUrlAuthorizationFailure(HttpContext context, object webEventSource) {
+ // Deny access
+ context.Response.StatusCode = 401;
+ context.Response.Write (new HttpException(401, "Unauthorized").GetHtmlErrorMessage ());
+
+#if false // Sys.Web.Mng not implemented on mono.
+ if (context.User != null && context.User.Identity.IsAuthenticated) {
+ // We don't raise failure audit event for anonymous user
+ WebBaseEvent.RaiseSystemEvent(webEventSource, WebEventCodes.AuditUrlAuthorizationFailure);
+ }
+#endif
+ context.ApplicationInstance.CompleteRequest();
+ }
+
}
}
--- /dev/null
+//------------------------------------------------------------------------------
+// <copyright file="Util.cs" company="Microsoft">
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// </copyright>
+//------------------------------------------------------------------------------
+
+/*
+ * Implements various utility functions used by the template code
+ *
+ * Copyright (c) 1998 Microsoft Corporation
+ */
+
+namespace System.Web.UI {
+ using System;
+ using System.Collections;
+ using System.Collections.Specialized;
+ using System.ComponentModel;
+ using System.Diagnostics;
+ using System.Diagnostics.CodeAnalysis;
+ using System.Drawing;
+ using System.Globalization;
+ using System.IO;
+ using System.Reflection;
+ using System.Runtime.Serialization.Formatters;
+ using System.Security;
+ using System.Security.Permissions;
+ using System.Text;
+ using System.Text.RegularExpressions;
+ using System.Web.Compilation;
+ using System.Web.Configuration;
+ using System.Web.Hosting;
+ using System.Web.Management;
+ using System.Web.Security;
+ //using System.Web.Security.Cryptography;
+ using System.Web.UI.WebControls;
+ using System.Web.Util;
+ using Microsoft.Win32;
+ //using Debug = System.Web.Util.Debug;
+
+internal static class Util {
+
+ internal static string GetUrlWithApplicationPath(HttpContextBase context, string url) {
+ string appPath = context.Request.ApplicationPath ?? String.Empty;
+ if (!appPath.EndsWith("/", StringComparison.OrdinalIgnoreCase)) {
+ appPath += "/";
+ }
+
+ return context.Response.ApplyAppPathModifier(appPath + url);
+ }
+}
+
+}
Mono.Web.Util/SettingsMappingManager.cs
Mono.Web.Util/SettingsMappingWhat.cs
+ReferenceSources/SR.cs
System.Web/ApplicationShutdownReason.cs
System.Web/BeginEventHandler.cs
System.Web.Caching/AggregateCacheDependency.cs
System.Web/TraceData.cs
System.Web/TraceManager.cs
System.Web/TraceMode.cs
+System.Web.UI/Util.cs
System.Web.UI.Adapters/ControlAdapter.cs
System.Web.UI.Adapters/PageAdapter.cs
../../../external/referencesource/System.Web/UI/WebControls/Adapters/WmlPostFieldType.cs
System.Web.Security/MachineKey.cs
System.Web.Security/MachineKeyProtection.cs
../../../external/referencesource/System.Web/State/SessionStateBehavior.cs
-System.Web.Routing/PageRouteHandler.cs
../../../external/referencesource/System.Web/UI/ClientIDMode.cs
../../../external/referencesource/System.Web/UI/DataKeyPropertyAttribute.cs
System.Web.UI/FileLevelMasterPageControlBuilder.cs
../../../external/referencesource/System.Web/Util/RequestValidationSource.cs
System.Web.Util/RequestValidator.cs
-System.Web.Routing/HttpMethodConstraint.cs
+../../../external/referencesource/System.Web/Routing/BoundUrl.cs
+../../../external/referencesource/System.Web/Routing/ContentPathSegment.cs
+../../../external/referencesource/System.Web/Routing/HttpMethodConstraint.cs
../../../external/referencesource/System.Web/Routing/IRouteConstraint.cs
../../../external/referencesource/System.Web/Routing/IRouteHandler.cs
-System.Web.Routing/PatternParser.cs
-System.Web.Routing/PatternToken.cs
-System.Web.Routing/PatternTokenType.cs
+../../../external/referencesource/System.Web/Routing/LiteralSubsegment.cs
+../../../external/referencesource/System.Web/Routing/PageRouteHandler.cs
+../../../external/referencesource/System.Web/Routing/ParameterSubsegment.cs
+../../../external/referencesource/System.Web/Routing/ParsedRoute.cs
+../../../external/referencesource/System.Web/Routing/PathSegment.cs
+../../../external/referencesource/System.Web/Routing/PathSubsegment.cs
../../../external/referencesource/System.Web/Routing/RequestContext.cs
-System.Web.Routing/Route.cs
+../../../external/referencesource/System.Web/Routing/Route.cs
../../../external/referencesource/System.Web/Routing/RouteBase.cs
-System.Web.Routing/RouteCollection.cs
+../../../external/referencesource/System.Web/Routing/RouteCollection.cs
../../../external/referencesource/System.Web/Routing/RouteData.cs
../../../external/referencesource/System.Web/Routing/RouteDirection.cs
+../../../external/referencesource/System.Web/Routing/RouteParser.cs
../../../external/referencesource/System.Web/Routing/RouteTable.cs
../../../external/referencesource/System.Web/Routing/RouteValueDictionary.cs
-System.Web.Routing/RouteValueDictionaryExtensions.cs
+../../../external/referencesource/System.Web/Routing/SeparatorPathSegment.cs
../../../external/referencesource/System.Web/Routing/StopRoutingHandler.cs
-System.Web.Routing/UrlRoutingHandler.cs
-System.Web.Routing/UrlRoutingModule.cs
+../../../external/referencesource/System.Web/Routing/UrlAuthFailureHandler.cs
+../../../external/referencesource/System.Web/Routing/UrlRoutingHandler.cs
+../../../external/referencesource/System.Web/Routing/UrlRoutingModule.cs
../../../external/referencesource/System.Web/Routing/VirtualPathData.cs
../../../external/referencesource/System.Web/Abstractions/HttpApplicationStateBase.cs
../../../external/referencesource/System.Web/Hosting/IProcessHostSupportFunctions.cs
../../../external/referencesource/System.Web/Hosting/HTTP_COOKED_URL.cs
../../../external/referencesource/System.Web/Hosting/HostingEnvironmentException.cs
-../../../external/referencesource/System.Web/Routing/PathSegment.cs
-../../../external/referencesource/System.Web/Routing/PathSubsegment.cs
-../../../external/referencesource/System.Web/Routing/BoundUrl.cs
-../../../external/referencesource/System.Web/Routing/SeparatorPathSegment.cs
-../../../external/referencesource/System.Web/Routing/UrlAuthFailureHandler.cs
-../../../external/referencesource/System.Web/Routing/LiteralSubsegment.cs
-../../../external/referencesource/System.Web/Routing/ParameterSubsegment.cs
-../../../external/referencesource/System.Web/Routing/ContentPathSegment.cs
../../../external/referencesource/System.Web/Util/SynchronizationContextMode.cs
../../../external/referencesource/System.Web/Util/ISyncContextLock.cs
../../../external/referencesource/System.Web/Util/DoNotResetAttribute.cs
MonoIOError error;
FlushBuffer ();
+
+ if (CanSeek && !isExposed) {
+ MonoIO.Seek (safeHandle, buf_start, SeekOrigin.Begin, out error);
+ if (error != MonoIOError.ERROR_SUCCESS)
+ throw MonoIO.GetException (GetSecureFileName (name), error);
+ }
+
int wcount = count;
while (wcount > 0){
int wcount = buf_length;
int offset = 0;
while (wcount > 0){
- int n = MonoIO.Write (safeHandle, buf, 0, buf_length, out error);
+ int n = MonoIO.Write (safeHandle, buf, offset, buf_length, out error);
if (error != MonoIOError.ERROR_SUCCESS) {
// don't leak the path information for isolated storage
throw MonoIO.GetException (GetSecureFileName (name), error);
var Istart = 0;
while (Istart < str.Length && !char.IsLetterOrDigit(str[Istart])) Istart++;
var Iend = str.Length - 1;
- while (Iend > Istart && !char.IsLetterOrDigit(str[Iend])) Iend--;
+ while (Iend > Istart && !char.IsLetterOrDigit(str[Iend]) && str[Iend] != ')') // zone name can include parentheses like "Central Standard Time (Mexico)"
+ Iend--;
return str.Substring (Istart, Iend-Istart+1);
}
}
}
#endif
+
+ [Test] // Covers #11699
+ public void ReadWriteFileLength ()
+ {
+ int bufferSize = 128;
+ int readLength = 1;
+ int writeLength = bufferSize + 1;
+
+ string path = TempFolder + DSC + "readwritefilelength.tmp";
+
+ try {
+ File.WriteAllBytes (path, new byte [readLength + 1]);
+
+ using (var file = new FileStream (path, FileMode.Open, FileAccess.ReadWrite, FileShare.Read,
+ bufferSize, FileOptions.SequentialScan))
+ {
+ file.Read (new byte [readLength], 0, readLength);
+ file.Write (new byte [writeLength], 0, writeLength);
+
+ Assert.AreEqual (readLength + writeLength, file.Length);
+ }
+ } finally {
+ DeleteFile (path);
+ }
+ }
}
}
}
}
+#if MONO_FEATURE_THREAD_SUSPEND_RESUME
[Test]
public void WaitOneWithTimeoutAndSpuriousWake ()
{
Assert.IsTrue (thread.Join (1000), "#1");
}
}
+#endif // MONO_FEATURE_THREAD_SUSPEND_RESUME
}
}
var timeZones = (global::System.Collections.ObjectModel.ReadOnlyCollection<TimeZoneInfo>) method.Invoke (null, null);
Assert.IsTrue (timeZones.Count > 0, "GetSystemTimeZones should not return an empty collection.");
}
+
+ [Test]
+ public void WindowsRegistryTimezoneWithParentheses ()
+ {
+ var method = (MethodInfo) typeof (TimeZoneInfo).GetMember ("TrimSpecial", MemberTypes.Method, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic)[0];
+
+ var name = method.Invoke (null, new object [] { " <---> Central Standard Time (Mexico) ||<<>>" });
+ Assert.AreEqual (name, "Central Standard Time (Mexico)", "#1");
+ }
}
[TestFixture]
if (methref == null) {
methref = methoddef.MakeVarArgSignature (opt);
+ methref.AddCallConv (call_conv);
vararg_sig_table [full_signature] = methref;
}
Console.WriteLine (" - Warning: ignoring '" + t + "'");
Console.WriteLine (" " + ex.Message);
}
+ } catch (NotSupportedException ex) {
+ if (verbose)
+ Console.WriteLine (" - Warning: " + ex.Message);
}
}
} else {
Console.WriteLine (" - Warning: ignoring '" + type + "'");
Console.WriteLine (" " + ex.Message);
}
+ } catch (NotSupportedException ex) {
+ if (verbose)
+ Console.WriteLine (" - Warning: " + ex.Message);
}
}
}
static void
dis_code (MonoImage *m, guint32 token, guint32 rva, MonoGenericContainer *container)
{
+ MonoError error;
MonoMethodHeader *mh;
const char *ptr = mono_image_rva_map (m, rva);
const char *loc;
g_free (override);
}
- mh = mono_metadata_parse_mh_full (m, container, ptr);
+ mh = mono_metadata_parse_mh_full (m, container, ptr, &error);
entry_point = mono_image_get_entry_point (m);
if (entry_point && mono_metadata_token_index (entry_point) && mono_metadata_token_table (entry_point) == MONO_TABLE_METHOD) {
loc = mono_metadata_locate_token (m, entry_point);
hex_dump (mh->code + mh->code_size, 0, 64);
*/
mono_metadata_free_mh (mh);
+ } else {
+ mono_error_cleanup (&error);
}
}
MonoType *type;
for (i = 0; i < t->rows; i++) {
+ MonoError error;
mono_metadata_decode_row (t, i, cols, MONO_FIELD_RVA_SIZE);
rva = mono_image_rva_map (m, cols [MONO_FIELD_RVA_RVA]);
sig = mono_metadata_blob_heap (m, mono_metadata_decode_row_col (ft, cols [MONO_FIELD_RVA_FIELD] -1, MONO_FIELD_SIGNATURE));
mono_metadata_decode_value (sig, &sig);
/* FIELD signature == 0x06 */
g_assert (*sig == 0x06);
- type = mono_metadata_parse_field_type (m, 0, sig + 1, &sig);
+ type = mono_metadata_parse_type_checked (m, NULL, 0, FALSE, sig + 1, &sig, &error);
+ if (!type) {
+ fprintf (output, "// invalid field %d due to %s\n", i, mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ continue;
+ }
mono_class_init (mono_class_from_mono_type (type));
size = mono_type_size (type, &align);
environment.h \
exception.c \
exception.h \
+ exception-internals.h \
file-io.c \
file-io.h \
filewatcher.c \
string_vt = mono_class_vtable (domain, mono_defaults.string_class);
string_empty_fld = mono_class_get_field_from_name (mono_defaults.string_class, "Empty");
g_assert (string_empty_fld);
- mono_field_static_set_value (string_vt, string_empty_fld, mono_string_intern (mono_string_new (domain, "")));
+ MonoString *empty_str = mono_string_intern_checked (mono_string_new (domain, ""), &error);
+ mono_error_assert_ok (&error);
+ mono_field_static_set_value (string_vt, string_empty_fld, empty_str);
/*
* Create an instance early since we can't do it when there is no memory.
#include <mono/metadata/profiler-private.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/domain-internals.h>
+#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/mono-endian.h>
#include <mono/metadata/mono-debug.h>
#include <mono/io-layer/io-layer.h>
void
mono_assembly_load_friends (MonoAssembly* ass)
{
+ MonoError error;
int i;
MonoCustomAttrInfo* attrs;
GSList *list;
if (ass->friend_assembly_names_inited)
return;
- attrs = mono_custom_attrs_from_assembly (ass);
+ attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+ mono_error_assert_ok (&error);
if (!attrs) {
mono_assemblies_lock ();
ass->friend_assembly_names_inited = TRUE;
info = mono_wrapper_info_create (mb, WRAPPER_SUBTYPE_NONE);
info->d.alloc.gc_name = "boehm";
info->d.alloc.alloc_type = atype;
+ mb->init_locals = FALSE;
res = mono_mb_create (mb, csig, 8, info);
mono_mb_free (mb);
- mono_method_get_header (res)->init_locals = FALSE;
return res;
}
MonoType*
mono_class_inflate_generic_type_with_mempool (MonoImage *image, MonoType *type, MonoGenericContext *context, MonoError *error);
-MonoClass*
-mono_class_inflate_generic_class (MonoClass *gklass, MonoGenericContext *context);
-
MonoType*
mono_class_inflate_generic_type_checked (MonoType *type, MonoGenericContext *context, MonoError *error);
MonoError error;
MonoType *result;
result = mono_class_inflate_generic_type_checked (type, context, &error);
-
- if (!mono_error_ok (&error)) {
- mono_error_cleanup (&error);
- return NULL;
- }
+ mono_error_cleanup (&error);
return result;
}
return inflated;
}
+/*
+ * mono_class_inflate_generic_class:
+ *
+ * Inflate the class @gklass with @context. Set @error on failure.
+ */
MonoClass*
mono_class_inflate_generic_class_checked (MonoClass *gklass, MonoGenericContext *context, MonoError *error)
{
return res;
}
-/*
- * mono_class_inflate_generic_class:
- *
- * Inflate the class GKLASS with CONTEXT.
- */
-MonoClass*
-mono_class_inflate_generic_class (MonoClass *gklass, MonoGenericContext *context)
-{
- MonoError error;
- MonoClass *res;
-
- res = mono_class_inflate_generic_class_checked (gklass, context, &error);
- g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
-
- return res;
-}
-
-
static MonoGenericContext
inflate_generic_context (MonoGenericContext *context, MonoGenericContext *inflate_with, MonoError *error)
if (eclass->byval_arg.type == MONO_TYPE_TYPEDBYREF || eclass->byval_arg.type == MONO_TYPE_VOID) {
/*Arrays of those two types are invalid.*/
- mono_class_set_failure (klass, MONO_EXCEPTION_TYPE_LOAD, NULL);
+ mono_class_set_failure (klass, MONO_EXCEPTION_INVALID_PROGRAM, NULL);
} else if (eclass->enumtype && !mono_class_enum_basetype (eclass)) {
if (!eclass->ref_info_handle || eclass->wastypebuilder) {
g_warning ("Only incomplete TypeBuilder objects are allowed to be an enum without base_type");
{
MonoError error;
MonoClass *res = mono_class_from_name_case_checked (image, name_space, name, &error);
- g_assert (!mono_error_ok (&error));
+ mono_error_cleanup (&error);
+
return res;
}
MonoClass *klass;
klass = mono_class_from_name_checked (image, name_space, name, &error);
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /* FIXME Don't swallow the error */
- }
+ mono_error_cleanup (&error); /* FIXME Don't swallow the error */
+
return klass;
}
case MONO_EXCEPTION_BAD_IMAGE: {
return mono_get_exception_bad_image_format ((const char *)exception_data);
}
+ case MONO_EXCEPTION_INVALID_PROGRAM: {
+ return mono_exception_from_name_msg (mono_defaults.corlib, "System", "InvalidProgramException", "");
+ }
default: {
MonoLoaderError *error;
MonoException *ex;
MONO_API MonoClass *
mono_class_from_generic_parameter (MonoGenericParam *param, MonoImage *image, mono_bool is_mvar);
-MONO_API MonoType*
+MONO_RT_EXTERNAL_ONLY MONO_API MonoType*
mono_class_inflate_generic_type (MonoType *type, MonoGenericContext *context) /* MONO_DEPRECATED */;
MONO_API MonoMethod*
static int
cominterop_get_com_slot_begin (MonoClass* klass)
{
+ MonoError error;
MonoCustomAttrInfo *cinfo = NULL;
MonoInterfaceTypeAttribute* itf_attr = NULL;
- cinfo = mono_custom_attrs_from_class (klass);
+ cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+ mono_error_assert_ok (&error);
if (cinfo) {
- MonoError error;
itf_attr = (MonoInterfaceTypeAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_interface_type_attribute_class (), &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
if (!cinfo->cached)
static gboolean
cominterop_class_guid (MonoClass* klass, guint8* guid)
{
+ MonoError error;
MonoCustomAttrInfo *cinfo;
- cinfo = mono_custom_attrs_from_class (klass);
+ cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+ mono_error_assert_ok (&error);
if (cinfo) {
- MonoError error;
MonoReflectionGuidAttribute *attr = (MonoReflectionGuidAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_guid_attribute_class (), &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
GPtrArray *ifaces;
MonoBoolean visible = 1;
- cinfo = mono_custom_attrs_from_class (klass);
+ cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+ mono_error_assert_ok (&error);
if (cinfo) {
- MonoError error;
MonoReflectionComVisibleAttribute *attr = (MonoReflectionComVisibleAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_get_guid_attribute_class (), &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/
static gpointer
cominterop_get_ccw (MonoObject* object, MonoClass* itf)
{
+ MonoError error;
int i;
MonoCCW *ccw = NULL;
MonoCCWInterface* ccw_entry = NULL;
g_hash_table_insert (ccw_hash, GINT_TO_POINTER (mono_object_hash (object)), ccw_list);
mono_cominterop_unlock ();
/* register for finalization to clean up ccw */
- mono_object_register_finalizer (object);
+ mono_object_register_finalizer (object, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
- cinfo = mono_custom_attrs_from_class (itf);
+ cinfo = mono_custom_attrs_from_class_checked (itf, &error);
+ mono_error_assert_ok (&error);
if (cinfo) {
static MonoClass* coclass_attribute = NULL;
if (!coclass_attribute)
guint32 lcid, gint32 *rgDispId)
{
static MonoClass *ComDispIdAttribute = NULL;
+ MonoError error;
MonoCustomAttrInfo *cinfo = NULL;
int i,ret = MONO_S_OK;
MonoMethod* method;
method = mono_class_get_method_from_name(klass, methodname, -1);
if (method) {
- cinfo = mono_custom_attrs_from_method (method);
+ cinfo = mono_custom_attrs_from_method_checked (method, &error);
+ mono_error_assert_ok (&error); /* FIXME what's reasonable to do here */
if (cinfo) {
- MonoError error;
MonoObject *result = mono_custom_attrs_get_attr_checked (cinfo, ComDispIdAttribute, &error);
g_assert (mono_error_ok (&error)); /*FIXME proper error handling*/;
static const unsigned char*
dis_one (GString *str, MonoDisHelper *dh, MonoMethod *method, const unsigned char *ip, const unsigned char *end)
{
- MonoMethodHeader *header = mono_method_get_header (method);
+ MonoError error;
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
const MonoOpcode *opcode;
guint32 label, token;
gint32 sval;
int i;
char *tmp;
- const unsigned char* il_code = mono_method_header_get_code (header, NULL, NULL);
+ const unsigned char* il_code;
+
+ if (!header) {
+ g_string_append_printf (str, "could not disassemble, bad header due to %s", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ return end;
+ }
+ il_code = mono_method_header_get_code (header, NULL, NULL);
label = ip - il_code;
if (dh->indenter) {
void
mono_method_print_code (MonoMethod *method)
{
+ MonoError error;
char *code;
- MonoMethodHeader *header = mono_method_get_header (method);
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
if (!header) {
- printf ("METHOD HEADER NOT FOUND\n");
+ printf ("METHOD HEADER NOT FOUND DUE TO: %s\n", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
return;
}
code = mono_disasm_code (0, method, header->code, header->code + header->code_size);
--- /dev/null
+#ifndef _MONO_METADATA_EXCEPTION_INTERNALS_H_
+#define _MONO_METADATA_EXCEPTION_INTERNALS_H_
+
+#include <glib.h>
+
+#include <mono/metadata/object.h>
+#include <mono/utils/mono-error.h>
+
+MonoException *
+mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error);
+
+MonoException *
+mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *exceptions, MonoError *error);
+
+MonoException *
+mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error);
+
+#endif
\ No newline at end of file
#include <glib.h>
#include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/metadata-internals.h>
}
static MonoException *
-create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2)
+create_exception_two_strings (MonoClass *klass, MonoString *a1, MonoString *a2, MonoError *error)
{
- MonoError error;
MonoDomain *domain = mono_domain_get ();
MonoMethod *method = NULL;
MonoObject *o;
if (a2 != NULL)
count++;
- o = mono_object_new_checked (domain, klass, &error);
- mono_error_assert_ok (&error);
+ o = mono_object_new_checked (domain, klass, error);
+ mono_error_assert_ok (error);
iter = NULL;
while ((m = mono_class_get_methods (klass, &iter))) {
args [0] = a1;
args [1] = a2;
- mono_runtime_invoke_checked (method, o, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (method, o, args, error);
+ return_val_if_nok (error, NULL);
return (MonoException *) o;
}
mono_exception_from_name_two_strings (MonoImage *image, const char *name_space,
const char *name, MonoString *a1, MonoString *a2)
{
- MonoClass *klass = mono_class_load_from_name (image, name_space, name);
+ MonoError error;
+ MonoClass *klass;
+ MonoException *ret;
- return create_exception_two_strings (klass, a1, a2);
+ klass = mono_class_load_from_name (image, name_space, name);
+
+ ret = create_exception_two_strings (klass, a1, a2, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return ret;
}
/**
MonoString *a1, MonoString *a2)
{
MonoError error;
- MonoClass *klass = mono_class_get_checked (image, token, &error);
- g_assert (mono_error_ok (&error)); /* FIXME handle the error. */
+ MonoClass *klass;
+ MonoException *ret;
+
+ klass = mono_class_get_checked (image, token, &error);
+ mono_error_assert_ok (&error); /* FIXME handle the error. */
+
+ ret = create_exception_two_strings (klass, a1, a2, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
- return create_exception_two_strings (klass, a1, a2);
+ return ret;
}
/**
mono_get_exception_type_initialization (const gchar *type_name, MonoException *inner)
{
MonoError error;
+ MonoException *ret = mono_get_exception_type_initialization_checked (type_name, inner, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ return NULL;
+ }
+
+ return ret;
+}
+
+MonoException *
+mono_get_exception_type_initialization_checked (const gchar *type_name, MonoException *inner, MonoError *error)
+{
MonoClass *klass;
gpointer args [2];
MonoObject *exc;
args [0] = mono_string_new (mono_domain_get (), type_name);
args [1] = inner;
- exc = mono_object_new_checked (mono_domain_get (), klass, &error);
- mono_error_assert_ok (&error);
- mono_runtime_invoke_checked (method, exc, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ exc = mono_object_new_checked (mono_domain_get (), klass, error);
+ mono_error_assert_ok (error);
+
+ mono_runtime_invoke_checked (method, exc, args, error);
+ return_val_if_nok (error, NULL);
return (MonoException *) exc;
}
mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions)
{
MonoError error;
+ MonoException *ret = mono_get_exception_reflection_type_load_checked (types, exceptions, &error);
+ if (is_ok (&error)) {
+ mono_error_cleanup (&error);
+ return NULL;
+ }
+
+ return ret;
+}
+
+MonoException *
+mono_get_exception_reflection_type_load_checked (MonoArray *types, MonoArray *exceptions, MonoError *error)
+{
MonoClass *klass;
gpointer args [2];
MonoObject *exc;
args [0] = types;
args [1] = exceptions;
- exc = mono_object_new_checked (mono_domain_get (), klass, &error);
- mono_error_assert_ok (&error);
+ exc = mono_object_new_checked (mono_domain_get (), klass, error);
+ mono_error_assert_ok (error);
- mono_runtime_invoke_checked (method, exc, args, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (method, exc, args, error);
+ return_val_if_nok (error, NULL);
return (MonoException *) exc;
}
mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception)
{
MonoError error;
+ MonoException *ret = mono_get_exception_runtime_wrapped_checked (wrapped_exception, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ return NULL;
+ }
+
+ return ret;
+}
+
+MonoException *
+mono_get_exception_runtime_wrapped_checked (MonoObject *wrapped_exception, MonoError *error)
+{
MonoClass *klass;
MonoObject *o;
MonoMethod *method;
klass = mono_class_load_from_name (mono_get_corlib (), "System.Runtime.CompilerServices", "RuntimeWrappedException");
- o = mono_object_new_checked (domain, klass, &error);
- g_assert (o != NULL && mono_error_ok (&error)); /* FIXME don't swallow the error */
+ o = mono_object_new_checked (domain, klass, error);
+ mono_error_assert_ok (error);
+ g_assert (o != NULL);
method = mono_class_get_method_from_name (klass, ".ctor", 1);
g_assert (method);
params [0] = wrapped_exception;
- mono_runtime_invoke_checked (method, o, params, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (method, o, params, error);
+ return_val_if_nok (error, NULL);
return (MonoException *)o;
}
MONO_API MonoException *
mono_get_exception_file_not_found2 (const char *msg, MonoString *fname);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoException *
mono_get_exception_type_initialization (const char *type_name, MonoException *inner);
MONO_API MonoException *
mono_get_exception_method_access (void);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoException *
mono_get_exception_reflection_type_load (MonoArray *types, MonoArray *exceptions);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoException *
mono_get_exception_runtime_wrapped (MonoObject *wrapped_exception);
/* useful until we keep track of gc-references in corlib etc. */
#define IS_GC_REFERENCE(class,t) (mono_gc_is_moving () ? FALSE : ((t)->type == MONO_TYPE_U && (class)->image == mono_defaults.corlib))
-void mono_object_register_finalizer (MonoObject *obj);
+void mono_object_register_finalizer (MonoObject *obj, MonoError *error);
void ves_icall_System_GC_InternalCollect (int generation);
gint64 ves_icall_System_GC_GetTotalMemory (MonoBoolean forceCollection);
void ves_icall_System_GC_KeepAlive (MonoObject *obj);
static MonoInternalThread *gc_thread;
-static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*));
+static void object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*), MonoError *error);
static void reference_queue_proccess_all (void);
static void mono_reference_queue_cleanup (void);
#endif
/* make sure the finalizer is not called again if the object is resurrected */
- object_register_finalizer ((MonoObject *)obj, NULL);
+ object_register_finalizer ((MonoObject *)obj, NULL, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if (log_finalizers)
g_log ("mono-gc-finalizers", G_LOG_LEVEL_MESSAGE, "<%s at %p> Registered finalizer as processed.", o->vtable->klass->name, o);
void
mono_gc_finalize_threadpool_threads (void)
{
+ MonoError error;
while (threads_to_finalize) {
MonoInternalThread *thread = (MonoInternalThread*) mono_mlist_get_data (threads_to_finalize);
/* Force finalization of the thread. */
thread->threadpool_thread = FALSE;
- mono_object_register_finalizer ((MonoObject*)thread);
+ mono_object_register_finalizer ((MonoObject*)thread, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
mono_gc_run_finalize (thread, NULL);
* since that, too, can cause the underlying pointer to be offset.
*/
static void
-object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*))
+object_register_finalizer (MonoObject *obj, void (*callback)(void *, void*), MonoError *error)
{
MonoDomain *domain;
- if (obj == NULL)
- mono_raise_exception (mono_get_exception_argument_null ("obj"));
+ mono_error_init (error);
+
+ if (obj == NULL) {
+ mono_error_set_argument_null (error, "obj", "");
+ return;
+ }
domain = obj->vtable->domain;
*
*/
void
-mono_object_register_finalizer (MonoObject *obj)
+mono_object_register_finalizer (MonoObject *obj, MonoError *error)
{
/* g_print ("Registered finalizer on %p %s.%s\n", obj, mono_object_class (obj)->name_space, mono_object_class (obj)->name); */
- object_register_finalizer (obj, mono_gc_run_finalize);
+ object_register_finalizer (obj, mono_gc_run_finalize, error);
}
/**
void
ves_icall_System_GC_ReRegisterForFinalize (MonoObject *obj)
{
+ MonoError error;
+
MONO_CHECK_ARG_NULL (obj,);
- object_register_finalizer (obj, mono_gc_run_finalize);
+ object_register_finalizer (obj, mono_gc_run_finalize, &error);
+ mono_error_set_pending_exception (&error);
}
void
ves_icall_System_GC_SuppressFinalize (MonoObject *obj)
{
+ MonoError error;
+
MONO_CHECK_ARG_NULL (obj,);
/* delegates have no finalizers, but we register them to deal with the
* generated for it that needs cleaned up, but user wants to suppress
* their derived object finalizer. */
- object_register_finalizer (obj, NULL);
+ object_register_finalizer (obj, NULL, &error);
+ mono_error_set_pending_exception (&error);
}
void
gboolean
mono_gc_reference_queue_add (MonoReferenceQueue *queue, MonoObject *obj, void *user_data)
{
+ MonoError error;
RefQueueEntry *entry;
if (queue->should_be_deleted)
return FALSE;
entry->domain = mono_object_domain (obj);
entry->gchandle = mono_gchandle_new_weakref (obj, TRUE);
- mono_object_register_finalizer (obj);
+ mono_object_register_finalizer (obj, &error);
+ mono_error_assert_ok (&error);
ref_list_push (&queue->queue, entry);
return TRUE;
ICALL_TYPE(MTYPE, "System.MonoType", MTYPE_1)
ICALL(MTYPE_1, "GetCorrespondingInflatedConstructor", ves_icall_MonoType_GetCorrespondingInflatedMethod)
ICALL(MTYPE_2, "GetCorrespondingInflatedMethod", ves_icall_MonoType_GetCorrespondingInflatedMethod)
-ICALL(MTYPE_3, "type_from_obj", mono_type_type_from_obj)
+ICALL(MTYPE_3, "type_from_obj", ves_icall_MonoType_type_from_obj)
#ifndef DISABLE_SOCKETS
ICALL_TYPE(NDNS, "System.Net.Dns", NDNS_1)
ICALL(MCMETH_2, "InternalInvoke", ves_icall_InternalInvoke)
ICALL_TYPE(MEVIN, "System.Reflection.MonoEventInfo", MEVIN_1)
-ICALL(MEVIN_1, "get_event_info", ves_icall_get_event_info)
+ICALL(MEVIN_1, "get_event_info", ves_icall_MonoEventInfo_get_event_info)
ICALL_TYPE(MFIELD, "System.Reflection.MonoField", MFIELD_1)
ICALL(MFIELD_1, "GetFieldOffset", ves_icall_MonoField_GetFieldOffset)
ICALL(MMETHI_3, "get_retval_marshal", ves_icall_System_MonoMethodInfo_get_retval_marshal)
ICALL_TYPE(MPROPI, "System.Reflection.MonoPropertyInfo", MPROPI_1)
-ICALL(MPROPI_1, "GetTypeModifiers", property_info_get_type_modifiers)
+ICALL(MPROPI_1, "GetTypeModifiers", ves_icall_MonoPropertyInfo_GetTypeModifiers)
ICALL(MPROPI_3, "get_default_value", property_info_get_default_value)
-ICALL(MPROPI_2, "get_property_info", ves_icall_get_property_info)
+ICALL(MPROPI_2, "get_property_info", ves_icall_MonoPropertyInfo_get_property_info)
ICALL_TYPE(PARAMI, "System.Reflection.ParameterInfo", PARAMI_1)
ICALL(PARAMI_1, "GetMetadataToken", mono_reflection_get_token)
-ICALL(PARAMI_2, "GetTypeModifiers", param_info_get_type_modifiers)
+ICALL(PARAMI_2, "GetTypeModifiers", ves_icall_ParameterInfo_GetTypeModifiers)
ICALL_TYPE(RTFIELD, "System.Reflection.RtFieldInfo", RTFIELD_1)
ICALL(RTFIELD_1, "UnsafeGetValue", ves_icall_MonoField_GetValueInternal)
ICALL(RFH_2, "SetValueInternal", ves_icall_MonoField_SetValueInternal)
ICALL_TYPE(MHAN, "System.RuntimeMethodHandle", MHAN_1)
-ICALL(MHAN_1, "GetFunctionPointer", ves_icall_RuntimeMethod_GetFunctionPointer)
+ICALL(MHAN_1, "GetFunctionPointer", ves_icall_RuntimeMethodHandle_GetFunctionPointer)
ICALL_TYPE(RT, "System.RuntimeType", RT_1)
ICALL(RT_1, "CreateInstanceInternal", ves_icall_System_Activator_CreateInstanceInternal)
ICALL(RT_27, "make_byref_type", ves_icall_Type_make_byref_type)
ICALL_TYPE(RTH, "System.RuntimeTypeHandle", RTH_1)
-ICALL(RTH_1, "GetArrayRank", ves_icall_MonoType_GetArrayRank)
-ICALL(RTH_2, "GetAssembly", ves_icall_MonoType_get_Assembly)
-ICALL(RTH_3, "GetAttributes", ves_icall_get_attributes)
-ICALL(RTH_4, "GetBaseType", ves_icall_get_type_parent)
-ICALL(RTH_5, "GetElementType", ves_icall_MonoType_GetElementType)
-ICALL(RTH_6, "GetGenericTypeDefinition_impl", ves_icall_Type_GetGenericTypeDefinition_impl)
+ICALL(RTH_1, "GetArrayRank", ves_icall_RuntimeTypeHandle_GetArrayRank)
+ICALL(RTH_2, "GetAssembly", ves_icall_RuntimeTypeHandle_GetAssembly)
+ICALL(RTH_3, "GetAttributes", ves_icall_RuntimeTypeHandle_GetAttributes)
+ICALL(RTH_4, "GetBaseType", ves_icall_RuntimeTypeHandle_GetBaseType)
+ICALL(RTH_5, "GetElementType", ves_icall_RuntimeTypeHandle_GetElementType)
+ICALL(RTH_6, "GetGenericTypeDefinition_impl", ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl)
ICALL(RTH_7, "GetMetadataToken", mono_reflection_get_token)
-ICALL(RTH_8, "GetModule", ves_icall_MonoType_get_Module)
-ICALL(RTH_9, "HasInstantiation", ves_icall_Type_get_IsGenericType)
-ICALL(RTH_10, "IsArray", ves_icall_Type_IsArrayImpl)
-ICALL(RTH_11, "IsByRef", ves_icall_type_isbyref)
-ICALL(RTH_12, "IsComObject", ves_icall_type_iscomobject)
-ICALL(RTH_13, "IsGenericTypeDefinition", ves_icall_Type_get_IsGenericTypeDefinition)
-ICALL(RTH_14, "IsGenericVariable", ves_icall_MonoType_get_IsGenericParameter)
-ICALL(RTH_15, "IsInstanceOfType", ves_icall_type_IsInstanceOfType)
-ICALL(RTH_16, "IsPointer", ves_icall_type_ispointer)
-ICALL(RTH_17, "IsPrimitive", ves_icall_type_isprimitive)
-ICALL(RTH_18, "type_is_assignable_from", ves_icall_type_is_assignable_from)
+ICALL(RTH_8, "GetModule", ves_icall_RuntimeTypeHandle_GetModule)
+ICALL(RTH_9, "HasInstantiation", ves_icall_RuntimeTypeHandle_HasInstantiation)
+ICALL(RTH_10, "IsArray", ves_icall_RuntimeTypeHandle_IsArray)
+ICALL(RTH_11, "IsByRef", ves_icall_RuntimeTypeHandle_IsByRef)
+ICALL(RTH_12, "IsComObject", ves_icall_RuntimeTypeHandle_IsComObject)
+ICALL(RTH_13, "IsGenericTypeDefinition", ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition)
+ICALL(RTH_14, "IsGenericVariable", ves_icall_RuntimeTypeHandle_IsGenericVariable)
+ICALL(RTH_15, "IsInstanceOfType", ves_icall_RuntimeTypeHandle_IsInstanceOfType)
+ICALL(RTH_16, "IsPointer", ves_icall_RuntimeTypeHandle_IsPointer)
+ICALL(RTH_17, "IsPrimitive", ves_icall_RuntimeTypeHandle_IsPrimitive)
+ICALL(RTH_18, "type_is_assignable_from", ves_icall_RuntimeTypeHandle_type_is_assignable_from)
ICALL_TYPE(RNG, "System.Security.Cryptography.RNGCryptoServiceProvider", RNG_1)
ICALL(RNG_1, "RngClose", ves_icall_System_Security_Cryptography_RNGCryptoServiceProvider_RngClose)
ICALL(TENC_1, "InternalCodePage", ves_icall_System_Text_EncodingHelper_InternalCodePage)
ICALL_TYPE(UNORM, "System.Text.Normalization", UNORM_1)
-ICALL(UNORM_1, "load_normalization_resource", load_normalization_resource)
+ICALL(UNORM_1, "load_normalization_resource", ves_icall_System_Text_Normalization_load_normalization_resource)
ICALL_TYPE(ILOCK, "System.Threading.Interlocked", ILOCK_1)
ICALL(ILOCK_1, "Add(int&,int)", ves_icall_System_Threading_Interlocked_Add_Int)
ICALL(WAITH_4, "WaitOne_internal", ves_icall_System_Threading_WaitHandle_WaitOne_internal)
ICALL_TYPE(TYPE, "System.Type", TYPE_1)
-ICALL(TYPE_1, "internal_from_handle", ves_icall_type_from_handle)
-ICALL(TYPE_2, "internal_from_name", ves_icall_type_from_name)
+ICALL(TYPE_1, "internal_from_handle", ves_icall_System_Type_internal_from_handle)
+ICALL(TYPE_2, "internal_from_name", ves_icall_System_Type_internal_from_name)
ICALL_TYPE(TYPEDR, "System.TypedReference", TYPEDR_1)
ICALL(TYPEDR_1, "InternalToObject", mono_TypedReference_ToObject)
#include <mono/metadata/assembly.h>
#include <mono/metadata/tabledefs.h>
#include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
#include <mono/metadata/file-io.h>
#include <mono/metadata/console-io.h>
#include <mono/metadata/mono-route.h>
static GENERATE_GET_CLASS_WITH_CACHE (module, System.Reflection, Module)
static MonoArray*
-type_array_from_modifiers (MonoImage *image, MonoType *type, int optional);
+type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error);
static inline MonoBoolean
is_generic_parameter (MonoType *type)
}
static void
-mono_class_init_or_throw (MonoClass *klass)
+mono_class_init_checked (MonoClass *klass, MonoError *error)
{
+ mono_error_init (error);
+
if (!mono_class_init (klass))
- mono_raise_exception (mono_class_get_exception_for_failure (klass));
+ mono_error_set_exception_instance (error, mono_class_get_exception_for_failure (klass));
}
ICALL_EXPORT MonoObject *
}
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint32, 0) != 0))
/* vectors are not the same as one dimensional arrays with no-zero bounds */
}
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
if (bounds && (mono_array_length (bounds) == 1) && (mono_array_get (bounds, gint64, 0) != 0))
/* vectors are not the same as one dimensional arrays with no-zero bounds */
}
ICALL_EXPORT void
-mono_type_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
+ves_icall_MonoType_type_from_obj (MonoReflectionType *mtype, MonoObject *obj)
{
mtype->type = &obj->vtable->klass->byval_arg;
g_assert (mtype->type->type);
}
ICALL_EXPORT MonoReflectionType*
-ves_icall_type_from_name (MonoString *name,
- MonoBoolean throwOnError,
- MonoBoolean ignoreCase)
+ves_icall_System_Type_internal_from_name (MonoString *name,
+ MonoBoolean throwOnError,
+ MonoBoolean ignoreCase)
{
MonoError error;
char *str = mono_string_to_utf8 (name);
ICALL_EXPORT MonoReflectionType*
-ves_icall_type_from_handle (MonoType *handle)
+ves_icall_System_Type_internal_from_handle (MonoType *handle)
{
MonoError error;
MonoReflectionType *ret;
}
ICALL_EXPORT guint32
-ves_icall_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
+ves_icall_RuntimeTypeHandle_type_is_assignable_from (MonoReflectionType *type, MonoReflectionType *c)
{
MonoClass *klass;
MonoClass *klassc;
}
ICALL_EXPORT guint32
-ves_icall_type_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
+ves_icall_RuntimeTypeHandle_IsInstanceOfType (MonoReflectionType *type, MonoObject *obj)
{
+ MonoError error;
MonoClass *klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
return mono_object_isinst (obj, klass) != NULL;
}
ICALL_EXPORT guint32
-ves_icall_get_attributes (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetAttributes (MonoReflectionType *type)
{
MonoClass *klass = mono_class_from_mono_type (type->type);
return klass->flags;
{
MonoError error;
MonoType *type = mono_field_get_type_checked (field->field, &error);
+ MonoArray *res;
+
if (!mono_error_ok (&error)) {
mono_error_set_pending_exception (&error);
return NULL;
}
- return type_array_from_modifiers (field->field->parent->image, type, optional);
+ res = type_array_from_modifiers (field->field->parent->image, type, optional, &error);
+ mono_error_raise_exception (&error);
+ return res;
}
ICALL_EXPORT int
} PInfo;
ICALL_EXPORT void
-ves_icall_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
+ves_icall_MonoPropertyInfo_get_property_info (const MonoReflectionProperty *property, MonoPropertyInfo *info, PInfo req_info)
{
MonoError error;
MonoReflectionType *rt;
}
ICALL_EXPORT void
-ves_icall_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
+ves_icall_MonoEventInfo_get_event_info (MonoReflectionMonoEvent *event, MonoEventInfo *info)
{
MonoError error;
MonoReflectionType *rt;
MonoDomain *domain;
MonoError error;
- mono_class_init_or_throw (klass);
- mono_class_init_or_throw (iclass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
+ mono_class_init_checked (iclass, &error);
+ mono_error_raise_exception (&error);
mono_class_setup_vtable (klass);
ICALL_EXPORT void
ves_icall_Type_GetPacking (MonoReflectionType *type, guint32 *packing, guint32 *size)
{
+ MonoError error;
MonoClass *klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
if (image_is_dynamic (klass->image)) {
MonoReflectionTypeBuilder *tb = (MonoReflectionTypeBuilder*)type;
}
ICALL_EXPORT MonoReflectionType*
-ves_icall_MonoType_GetElementType (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetElementType (MonoReflectionType *type)
{
MonoError error;
MonoReflectionType *ret;
}
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
// GetElementType should only return a type for:
// Array Pointer PassedByRef
}
ICALL_EXPORT MonoReflectionType*
-ves_icall_get_type_parent (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetBaseType (MonoReflectionType *type)
{
MonoError error;
MonoReflectionType *ret;
}
ICALL_EXPORT MonoBoolean
-ves_icall_type_ispointer (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_IsPointer (MonoReflectionType *type)
{
return type->type->type == MONO_TYPE_PTR;
}
ICALL_EXPORT MonoBoolean
-ves_icall_type_isprimitive (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_IsPrimitive (MonoReflectionType *type)
{
return (!type->type->byref && (((type->type->type >= MONO_TYPE_BOOLEAN) && (type->type->type <= MONO_TYPE_R8)) || (type->type->type == MONO_TYPE_I) || (type->type->type == MONO_TYPE_U)));
}
ICALL_EXPORT MonoBoolean
-ves_icall_type_isbyref (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_IsByRef (MonoReflectionType *type)
{
return type->type->byref;
}
ICALL_EXPORT MonoBoolean
-ves_icall_type_iscomobject (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_IsComObject (MonoReflectionType *type)
{
+ MonoError error;
MonoClass *klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
return mono_class_is_com_object (klass);
}
+ICALL_EXPORT guint32
+ves_icall_RuntimeTypeHandle_GetMetadataToken (MonoReflectionType *obj)
+{
+ return mono_reflection_get_token ((MonoObject*)obj);
+}
+
ICALL_EXPORT MonoReflectionModule*
-ves_icall_MonoType_get_Module (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetModule (MonoReflectionType *type)
{
MonoError error;
MonoReflectionModule *result = NULL;
}
ICALL_EXPORT MonoReflectionAssembly*
-ves_icall_MonoType_get_Assembly (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetAssembly (MonoReflectionType *type)
{
MonoError error;
MonoDomain *domain = mono_domain_get ();
}
ICALL_EXPORT gint32
-ves_icall_MonoType_GetArrayRank (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetArrayRank (MonoReflectionType *type)
{
MonoClass *klass;
}
ICALL_EXPORT gboolean
-ves_icall_Type_get_IsGenericTypeDefinition (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_IsGenericTypeDefinition (MonoReflectionType *type)
{
MonoClass *klass;
}
ICALL_EXPORT MonoReflectionType*
-ves_icall_Type_GetGenericTypeDefinition_impl (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_GetGenericTypeDefinition_impl (MonoReflectionType *type)
{
MonoError error;
MonoReflectionType *ret;
int i, count;
g_assert (IS_MONOTYPE (type));
- mono_class_init_or_throw (mono_class_from_mono_type (type->type));
+ mono_class_init_checked (mono_class_from_mono_type (type->type), &error);
+ mono_error_raise_exception (&error);
count = mono_array_length (type_array);
types = g_new0 (MonoType *, count);
}
ICALL_EXPORT gboolean
-ves_icall_Type_get_IsGenericType (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_HasInstantiation (MonoReflectionType *type)
{
MonoClass *klass;
}
ICALL_EXPORT MonoBoolean
-ves_icall_MonoType_get_IsGenericParameter (MonoReflectionType *type)
+ves_icall_RuntimeTypeHandle_IsGenericVariable (MonoReflectionType *type)
{
return is_generic_parameter (type->type);
}
domain = ((MonoObject *)type)->vtable->domain;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
iter = NULL;
while ((method = mono_class_get_methods (klass, &iter))) {
domain = mono_object_domain (enumType);
enumc = mono_class_from_mono_type (enumType->type);
- mono_class_init_or_throw (enumc);
+ mono_class_init_checked (enumc, &error);
+ mono_error_raise_exception (&error);
etype = mono_class_enum_basetype (enumc);
MonoClass *klass;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
etype = mono_class_enum_basetype (klass);
if (!etype) {
ICALL_EXPORT MonoBoolean
ves_icall_System_Enum_GetEnumValuesAndNames (MonoReflectionType *type, MonoArray **values, MonoArray **names)
{
+ MonoError error;
MonoDomain *domain = mono_object_domain (type);
MonoClass *enumc = mono_class_from_mono_type (type->type);
guint j = 0, nvalues;
guint64 field_value, previous_value = 0;
gboolean sorted = TRUE;
- mono_class_init_or_throw (enumc);
+ mono_class_init_checked (enumc, &error);
+ mono_error_raise_exception (&error);
if (!enumc->enumtype) {
mono_set_pending_exception (mono_get_exception_argument ("enumType", "Type provided must be an Enum."));
ICALL_EXPORT int
vell_icall_MonoType_get_core_clr_security_level (MonoReflectionType *rfield)
{
+ MonoError error;
MonoClass *klass = mono_class_from_mono_type (rfield->type);
- mono_class_init_or_throw (klass);
+
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
return mono_security_core_clr_class_level (klass);
}
g_list_free (list);
list = NULL;
- exc = mono_get_exception_reflection_type_load (res, exl);
+ exc = mono_get_exception_reflection_type_load_checked (res, exl, &error);
+ if (!is_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
mono_loader_clear_error ();
mono_set_pending_exception (exc);
return NULL;
}
ICALL_EXPORT MonoBoolean
-ves_icall_Type_IsArrayImpl (MonoReflectionType *t)
+ves_icall_RuntimeTypeHandle_IsArray (MonoReflectionType *t)
{
MonoType *type;
MonoBoolean res;
}
static void
-check_for_invalid_type (MonoClass *klass)
+check_for_invalid_type (MonoClass *klass, MonoError *error)
{
char *name;
MonoString *str;
+
+ mono_error_init (error);
+
if (klass->byval_arg.type != MONO_TYPE_TYPEDBYREF)
return;
name = mono_type_get_full_name (klass);
str = mono_string_new (mono_domain_get (), name);
g_free (name);
- mono_raise_exception ((MonoException*)mono_get_exception_type_load (str, NULL));
+ mono_error_set_exception_instance (error, mono_get_exception_type_load (str, NULL));
}
ICALL_EXPORT MonoReflectionType *
MonoClass *klass, *aklass;
klass = mono_class_from_mono_type (type->type);
- check_for_invalid_type (klass);
+ check_for_invalid_type (klass, &error);
+ mono_error_raise_exception (&error);
if (rank == 0) //single dimentional array
aklass = mono_array_class_get (klass, 1);
MonoClass *klass;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
- check_for_invalid_type (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
+ check_for_invalid_type (klass, &error);
+ mono_error_raise_exception (&error);
ret = mono_type_get_object_checked (mono_object_domain (type), &klass->this_arg, &error);
mono_error_raise_exception (&error);
MonoClass *klass, *pklass;
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
- check_for_invalid_type (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
+ check_for_invalid_type (klass, &error);
+ mono_error_raise_exception (&error);
pklass = mono_ptr_class_get (type->type);
gpointer func;
MonoMethod *method = info->method;
- mono_class_init_or_throw (delegate_class);
+ mono_class_init_checked (delegate_class, &error);
+ mono_error_raise_exception (&error);
mono_assert (delegate_class->parent == mono_defaults.multicastdelegate_class);
method = rmethod->method;
klass = mono_class_from_mono_type (rtype->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
if (MONO_CLASS_IS_INTERFACE (klass))
return NULL;
domain = mono_object_domain (type);
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
if (MONO_CLASS_IS_INTERFACE (klass) || (klass->flags & TYPE_ATTRIBUTE_ABSTRACT)) {
mono_set_pending_exception (mono_get_exception_argument ("type", "Type cannot be instantiated"));
#endif
ICALL_EXPORT gpointer
-ves_icall_RuntimeMethod_GetFunctionPointer (MonoMethod *method)
+ves_icall_RuntimeMethodHandle_GetFunctionPointer (MonoMethod *method)
{
return mono_compile_method (method);
}
domain = mono_object_domain (type);
klass = mono_class_from_mono_type (type->type);
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
if (mono_class_is_nullable (klass))
/* No arguments -> null */
}
static void
-prelink_method (MonoMethod *method)
+prelink_method (MonoMethod *method, MonoError *error)
{
const char *exc_class, *exc_arg;
+
+ mono_error_init (error);
if (!(method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
return;
mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
if (exc_class) {
- mono_raise_exception(
- mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg ) );
+ mono_error_set_exception_instance (error,
+ mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
+ return;
}
/* create the wrapper, too? */
}
ICALL_EXPORT void
ves_icall_System_Runtime_InteropServices_Marshal_Prelink (MonoReflectionMethod *method)
{
- prelink_method (method->method);
+ MonoError error;
+
+ prelink_method (method->method, &error);
+ mono_error_raise_exception (&error);
}
ICALL_EXPORT void
ves_icall_System_Runtime_InteropServices_Marshal_PrelinkAll (MonoReflectionType *type)
{
+ MonoError error;
MonoClass *klass = mono_class_from_mono_type (type->type);
MonoMethod* m;
gpointer iter = NULL;
- mono_class_init_or_throw (klass);
+ mono_class_init_checked (klass, &error);
+ mono_error_raise_exception (&error);
- while ((m = mono_class_get_methods (klass, &iter)))
- prelink_method (m);
+ while ((m = mono_class_get_methods (klass, &iter))) {
+ prelink_method (m, &error);
+ mono_error_raise_exception (&error);
+ }
}
/* These parameters are "readonly" in corlib/System/NumberFormatter.cs */
/*
* We return NULL for no modifiers so the corlib code can return Type.EmptyTypes
* and avoid useless allocations.
- *
- * MAY THROW
*/
static MonoArray*
-type_array_from_modifiers (MonoImage *image, MonoType *type, int optional)
+type_array_from_modifiers (MonoImage *image, MonoType *type, int optional, MonoError *error)
{
- MonoError error;
MonoReflectionType *rt;
MonoArray *res;
int i, count = 0;
+
+ mono_error_init (error);
for (i = 0; i < type->num_mods; ++i) {
if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required))
count++;
count = 0;
for (i = 0; i < type->num_mods; ++i) {
if ((optional && !type->modifiers [i].required) || (!optional && type->modifiers [i].required)) {
- MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, &error);
- mono_error_raise_exception (&error); /* this is safe, no cleanup needed on callers */
+ MonoClass *klass = mono_class_get_checked (image, type->modifiers [i].token, error);
+ return_val_if_nok (error, NULL);
- rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, &error);
- mono_error_raise_exception (&error);
+ rt = mono_type_get_object_checked (mono_domain_get (), &klass->byval_arg, error);
+ return_val_if_nok (error, NULL);
mono_array_setref (res, count, rt);
count++;
}
ICALL_EXPORT MonoArray*
-param_info_get_type_modifiers (MonoReflectionParameter *param, MonoBoolean optional)
+ves_icall_ParameterInfo_GetTypeModifiers (MonoReflectionParameter *param, MonoBoolean optional)
{
+ MonoError error;
MonoType *type = param->ClassImpl->type;
MonoClass *member_class = mono_object_class (param->MemberImpl);
MonoMethod *method = NULL;
MonoImage *image;
int pos;
MonoMethodSignature *sig;
+ MonoArray *res;
if (mono_class_is_reflection_method_or_constructor (member_class)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
else
type = sig->params [pos];
- return type_array_from_modifiers (image, type, optional);
+ res = type_array_from_modifiers (image, type, optional, &error);
+ mono_error_raise_exception (&error);
+ return res;
}
static MonoType*
}
ICALL_EXPORT MonoArray*
-property_info_get_type_modifiers (MonoReflectionProperty *property, MonoBoolean optional)
+ves_icall_MonoPropertyInfo_GetTypeModifiers (MonoReflectionProperty *property, MonoBoolean optional)
{
+ MonoError error;
MonoType *type = get_property_type (property->property);
MonoImage *image = property->klass->image;
+ MonoArray *res;
if (!type)
return NULL;
- return type_array_from_modifiers (image, type, optional);
+ res = type_array_from_modifiers (image, type, optional, &error);
+ mono_error_raise_exception (&error);
+ return res;
}
/*
MonoCustomAttrInfo *cinfo;
gboolean found;
- mono_class_init_or_throw (attr_class);
+ mono_class_init_checked (attr_class, &error);
+ mono_error_raise_exception (&error);
cinfo = mono_reflection_get_custom_attrs_info_checked (obj, &error);
if (!is_ok (&error)) {
MonoArray *res;
MonoError error;
- if (attr_class)
- mono_class_init_or_throw (attr_class);
+ if (attr_class) {
+ mono_class_init_checked (attr_class, &error);
+ mono_error_raise_exception (&error);
+ }
res = mono_reflection_get_custom_attrs_by_type (obj, attr_class, &error);
if (!mono_error_ok (&error)) {
*table_ptr = new_table;
mono_memory_barrier ();
domain->num_jit_info_tables++;
- mono_thread_hazardous_free_or_queue (table, (MonoHazardousFreeFunc)mono_jit_info_table_free, TRUE, FALSE);
+ mono_thread_hazardous_free_or_queue (table, (MonoHazardousFreeFunc)mono_jit_info_table_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
table = new_table;
goto restart;
if (domain->num_jit_info_tables <= 1) {
/* Can it actually happen that we only have one table
but ji is still hazardous? */
- mono_thread_hazardous_free_or_queue (ji, g_free, TRUE, FALSE);
+ mono_thread_hazardous_free_or_queue (ji, g_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
} else {
domain->jit_info_free_queue = g_slist_prepend (domain->jit_info_free_queue, ji);
}
}
/* FIXME: This needs a cache, especially for generic instances, since
- * mono_metadata_parse_type () allocates everything from a mempool.
+ * we ask mono_metadata_parse_type_checked () to allocates everything from a mempool.
+ * FIXME part2, mono_metadata_parse_type_checked actually allows for a transient type instead.
+ * FIXME part3, transient types are not 100% transient, so we need to take care of that first.
*/
sig_type = (MonoType *)find_cached_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE]);
if (!sig_type) {
- sig_type = mono_metadata_parse_type (image, MONO_PARSE_TYPE, 0, ptr, &ptr);
+ MonoError inner_error;
+ sig_type = mono_metadata_parse_type_checked (image, NULL, 0, FALSE, ptr, &ptr, &inner_error);
if (sig_type == NULL) {
- mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x", fname, token);
+ mono_error_set_field_load (error, klass, fname, "Could not parse field '%s' signature %08x due to: %s", fname, token, mono_error_get_message (&inner_error));
+ mono_error_cleanup (&inner_error);
return NULL;
}
sig_type = (MonoType *)cache_memberref_sig (image, cols [MONO_MEMBERREF_SIGNATURE], sig_type);
}
static MonoMethodHeader*
-inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context)
+inflate_generic_header (MonoMethodHeader *header, MonoGenericContext *context, MonoError *error)
{
MonoMethodHeader *res;
int i;
res->init_locals = header->init_locals;
res->num_locals = header->num_locals;
res->clauses = header->clauses;
- for (i = 0; i < header->num_locals; ++i)
- res->locals [i] = mono_class_inflate_generic_type (header->locals [i], context);
+
+ mono_error_init (error);
+
+ for (i = 0; i < header->num_locals; ++i) {
+ res->locals [i] = mono_class_inflate_generic_type_checked (header->locals [i], context, error);
+ if (!is_ok (error))
+ goto fail;
+ }
if (res->num_clauses) {
res->clauses = (MonoExceptionClause *)g_memdup (header->clauses, sizeof (MonoExceptionClause) * res->num_clauses);
for (i = 0; i < header->num_clauses; ++i) {
MonoExceptionClause *clause = &res->clauses [i];
if (clause->flags != MONO_EXCEPTION_CLAUSE_NONE)
continue;
- clause->data.catch_class = mono_class_inflate_generic_class (clause->data.catch_class, context);
+ clause->data.catch_class = mono_class_inflate_generic_class_checked (clause->data.catch_class, context, error);
+ if (!is_ok (error))
+ goto fail;
}
}
return res;
+fail:
+ g_free (res);
+ return NULL;
}
/*
{
MonoError error;
MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, context, &error);
- g_assert (mono_error_ok (&error));
+ mono_error_cleanup (&error);
return res;
}
if (table == MONO_TABLE_METHODSPEC) {
/* the verifier (do_invoke_method) will turn the NULL into a verifier error */
- if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated)
+ if ((method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL) || !method->is_inflated) {
+ mono_error_set_bad_image (error, image, "Method is a pinvoke or open generic");
return NULL;
+ }
return mono_method_signature_checked (method, error);
}
{
MonoError error;
MonoMethodSignature *res = mono_method_get_signature_checked (method, image, token, NULL, &error);
- g_assert (mono_error_ok (&error));
+ mono_error_cleanup (&error);
return res;
}
}
MonoMethodHeader*
-mono_method_get_header (MonoMethod *method)
+mono_method_get_header_checked (MonoMethod *method, MonoError *error)
{
int idx;
guint32 rva;
MonoImage* img;
gpointer loc;
- MonoMethodHeader *header;
MonoGenericContainer *container;
- if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL))
- return NULL;
-
+ mono_error_init (error);
img = method->klass->image;
+ if ((method->flags & METHOD_ATTRIBUTE_ABSTRACT) || (method->iflags & METHOD_IMPL_ATTRIBUTE_RUNTIME) || (method->iflags & METHOD_IMPL_ATTRIBUTE_INTERNAL_CALL) || (method->flags & METHOD_ATTRIBUTE_PINVOKE_IMPL)) {
+ mono_error_set_bad_image (error, img, "Method has no body");
+ return NULL;
+ }
+
if (method->is_inflated) {
MonoMethodInflated *imethod = (MonoMethodInflated *) method;
MonoMethodHeader *header, *iheader;
- header = mono_method_get_header (imethod->declaring);
+ header = mono_method_get_header_checked (imethod->declaring, error);
if (!header)
return NULL;
- iheader = inflate_generic_header (header, mono_method_get_context (method));
+ iheader = inflate_generic_header (header, mono_method_get_context (method), error);
mono_metadata_free_mh (header);
+ if (!iheader) {
+ return NULL;
+ }
mono_image_lock (img);
idx = mono_metadata_token_index (method->token);
rva = mono_metadata_decode_row_col (&img->tables [MONO_TABLE_METHOD], idx - 1, MONO_METHOD_RVA);
- if (!mono_verifier_verify_method_header (img, rva, NULL))
+ if (!mono_verifier_verify_method_header (img, rva, NULL)) {
+ mono_error_set_bad_image (error, img, "Invalid method header, failed verification");
return NULL;
+ }
loc = mono_image_rva_map (img, rva);
- if (!loc)
+ if (!loc) {
+ mono_error_set_bad_image (error, img, "Method has zero rva");
return NULL;
+ }
/*
* When parsing the types of local variables, we must pass any container available
container = mono_method_get_generic_container (method);
if (!container)
container = method->klass->generic_container;
- header = mono_metadata_parse_mh_full (img, container, (const char *)loc);
+ return mono_metadata_parse_mh_full (img, container, (const char *)loc, error);
+}
+MonoMethodHeader*
+mono_method_get_header (MonoMethod *method)
+{
+ MonoError error;
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
+ mono_error_cleanup (&error);
return header;
}
+
guint32
mono_method_get_flags (MonoMethod *method, guint32 *iflags)
{
#include <mono/metadata/metadata.h>
#include <mono/metadata/image.h>
+#include <mono/utils/mono-error.h>
MONO_BEGIN_DECLS
MONO_API void
mono_free_method (MonoMethod *method);
-MONO_API MonoMethodSignature*
+MONO_RT_EXTERNAL_ONLY MONO_API MonoMethodSignature*
mono_method_get_signature_full (MonoMethod *method, MonoImage *image, uint32_t token,
MonoGenericContext *context);
-MONO_API MonoMethodSignature*
+MONO_RT_EXTERNAL_ONLY MONO_API MonoMethodSignature*
mono_method_get_signature (MonoMethod *method, MonoImage *image, uint32_t token);
MONO_API MonoMethodSignature*
mono_method_signature (MonoMethod *method);
-MONO_API MonoMethodHeader*
+MONO_RT_EXTERNAL_ONLY MONO_API MonoMethodHeader*
mono_method_get_header (MonoMethod *method);
MONO_API const char*
MONO_API void
mono_stack_walk_async_safe (MonoStackWalkAsyncSafe func, void *initial_sig_context, void* user_data);
+MONO_API MonoMethodHeader*
+mono_method_get_header_checked (MonoMethod *method, MonoError *error);
+
MONO_END_DECLS
#endif
}
}
-void load_normalization_resource (guint8 **argProps,
- guint8 **argMappedChars,
- guint8 **argCharMapIndex,
- guint8 **argHelperIndex,
- guint8 **argMapIdxToComposite,
- guint8 **argCombiningClass)
+void ves_icall_System_Text_Normalization_load_normalization_resource (guint8 **argProps,
+ guint8 **argMappedChars,
+ guint8 **argCharMapIndex,
+ guint8 **argHelperIndex,
+ guint8 **argMapIdxToComposite,
+ guint8 **argCombiningClass)
{
#ifdef DISABLE_NORMALIZATION
mono_set_pending_exception (mono_get_exception_not_supported ("This runtime has been compiled without string normalization support."));
extern MonoString *ves_icall_System_String_InternalToUpper_Comp (MonoString *this_obj, MonoCultureInfo *cult);
extern gunichar2 ves_icall_System_Char_InternalToUpper_Comp (gunichar2 c, MonoCultureInfo *cult);
extern gunichar2 ves_icall_System_Char_InternalToLower_Comp (gunichar2 c, MonoCultureInfo *cult);
-extern void load_normalization_resource (guint8 **argProps, guint8** argMappedChars, guint8** argCharMapIndex, guint8** argHelperIndex, guint8** argMapIdxToComposite, guint8** argCombiningClass);
+extern void ves_icall_System_Text_Normalization_load_normalization_resource (guint8 **argProps, guint8** argMappedChars, guint8** argCharMapIndex, guint8** argHelperIndex, guint8** argMapIdxToComposite, guint8** argCombiningClass);
#endif /* _MONO_METADATA_FILEIO_H_ */
mono_marshal_unlock ();
}
+/* This is a JIT icall, it sets the pending exception and return NULL on error */
gpointer
mono_delegate_to_ftnptr (MonoDelegate *delegate)
{
+ MonoError error;
MonoMethod *method, *wrapper;
MonoClass *klass;
uint32_t target_handle = 0;
ftnptr = mono_lookup_pinvoke_call (method, &exc_class, &exc_arg);
if (!ftnptr) {
g_assert (exc_class);
- mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
+ mono_set_pending_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System", exc_class, exc_arg));
+ return NULL;
}
return ftnptr;
}
delegate_hash_table_add (delegate);
/* when the object is collected, collect the dynamic method, too */
- mono_object_register_finalizer ((MonoObject*)delegate);
+ mono_object_register_finalizer ((MonoObject*)delegate, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return delegate->delegate_trampoline;
}
static void
parse_unmanaged_function_pointer_attr (MonoClass *klass, MonoMethodPInvoke *piinfo)
{
+ MonoError error;
MonoCustomAttrInfo *cinfo;
MonoReflectionUnmanagedFunctionPointerAttribute *attr;
* The pinvoke attributes are stored in a real custom attribute so we have to
* construct it.
*/
- cinfo = mono_custom_attrs_from_class (klass);
+ cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+ if (!mono_error_ok (&error)) {
+ g_warning ("Could not load UnmanagedFunctionPointerAttribute due to %s", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ }
if (cinfo && !mono_runtime_get_no_exec ()) {
- MonoError error;
attr = (MonoReflectionUnmanagedFunctionPointerAttribute*)mono_custom_attrs_get_attr_checked (cinfo, mono_class_try_get_unmanaged_function_pointer_attribute_class (), &error);
if (attr) {
piinfo->piflags = (attr->call_conv << 8) | (attr->charset ? (attr->charset - 1) * 2 : 1) | attr->set_last_error;
}
}
+/* This is a JIT icall, it sets the pending exception and returns NULL on error */
MonoDelegate*
mono_ftnptr_to_delegate (MonoClass *klass, gpointer ftn)
{
}
d = (MonoDelegate*)mono_object_new_checked (mono_domain_get (), klass, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
mono_delegate_ctor_with_method ((MonoObject*)d, this_obj, mono_compile_method (wrapper), wrapper);
}
- if (d->object.vtable->domain != mono_domain_get ())
- mono_raise_exception (mono_get_exception_not_supported ("Delegates cannot be marshalled from native code into a domain other than their home domain"));
+ if (d->object.vtable->domain != mono_domain_get ()) {
+ mono_set_pending_exception (mono_get_exception_not_supported ("Delegates cannot be marshalled from native code into a domain other than their home domain"));
+ return NULL;
+ }
return d;
}
return mono_string_new_len (domain, data, len);
}
+/* This is a JIT icall, it sets the pending exception and return NULL on error */
static MonoString *
mono_string_from_byvalwstr (gunichar2 *data, int max_len)
{
while (data [len]) len++;
res = mono_string_new_utf16_checked (domain, data, MIN (len, max_len), &error);
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return res;
}
mono_byvalarray_to_array (arr, native_arr, mono_defaults.byte_class, elnum);
}
+/* This is a JIT icall, it sets the pending exception and returns on error */
static void
mono_array_to_byvalarray (gpointer native_arr, MonoArray *arr, MonoClass *elclass, guint32 elnum)
{
as = g_utf16_to_utf8 (mono_array_addr (arr, gunichar2, 0), mono_array_length (arr), NULL, NULL, &error);
if (error) {
- MonoException *exc = mono_get_exception_argument ("string", error->message);
+ mono_set_pending_exception (mono_get_exception_argument ("string", error->message));
g_error_free (error);
- mono_raise_exception (exc);
+ return;
}
memcpy (native_arr, as, MIN (strlen (as), elnum));
* Returns: a utf8 string with the contents of the StringBuilder.
*
* The return value must be released with g_free.
+ *
+ * This is a JIT icall, it sets the pending exception and returns NULL on error.
*/
gchar*
mono_string_builder_to_utf8 (MonoStringBuilder *sb)
if (!sb)
return NULL;
-
gunichar2 *str_utf16 = mono_string_builder_to_utf16 (sb);
guint str_len = mono_string_builder_string_length (sb);
if (gerror) {
g_error_free (gerror);
g_free (str_utf16);
- mono_raise_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8"));
+ mono_set_pending_exception (mono_get_exception_execution_engine ("Failed to convert StringBuilder from utf16 to utf8"));
return NULL;
} else {
guint len = mono_string_builder_capacity (sb) + 1;
if (!mono_error_ok (&error)) {
g_free (str_utf16);
g_free (tmp);
- mono_error_raise_exception (&error);
+ mono_error_set_pending_exception (&error);
+ return NULL;
}
g_assert (str_len < len);
* Returns: a utf16 string with the contents of the StringBuilder.
*
* The return value must not be freed.
+ * This is a JIT icall, it sets the pending exception and returns NULL on error.
*/
gunichar2*
mono_string_builder_to_utf16 (MonoStringBuilder *sb)
len = 1;
gunichar2 *str = (gunichar2 *)mono_marshal_alloc ((len + 1) * sizeof (gunichar2), &error);
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
str[len] = '\0';
return str;
}
+/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static gpointer
mono_string_to_lpstr (MonoString *s)
{
if (error) {
MonoException *exc = mono_get_exception_argument ("string", error->message);
g_error_free (error);
- mono_raise_exception(exc);
+ mono_set_pending_exception (exc);
return NULL;
} else {
as = CoTaskMemAlloc (len + 1);
#endif /* DISABLE_JIT */
+/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static MonoAsyncResult *
mono_delegate_begin_invoke (MonoDelegate *delegate, gpointer *params)
{
+ MonoError error;
MonoMulticastDelegate *mcast_delegate;
MonoClass *klass;
MonoMethod *method;
g_assert (delegate);
mcast_delegate = (MonoMulticastDelegate *) delegate;
- if (mcast_delegate->delegates != NULL)
- mono_raise_exception (mono_get_exception_argument (NULL, "The delegate must have only one target"));
+ if (mcast_delegate->delegates != NULL) {
+ mono_set_pending_exception (mono_get_exception_argument (NULL, "The delegate must have only one target"));
+ return NULL;
+ }
#ifndef DISABLE_REMOTING
if (delegate->target && mono_object_class (delegate->target) == mono_defaults.transparent_proxy_class) {
-
MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target;
if (!mono_class_is_contextbound (tp->remote_class->proxy_class) || tp->rp->context != (MonoObject *) mono_context_get ()) {
-
/* If the target is a proxy, make a direct call. Is proxy's work
// to make the call asynchronous.
*/
msg->call_type = CallType_BeginInvoke;
exc = NULL;
- mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args);
+ mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
if (exc)
- mono_raise_exception ((MonoException *) exc);
+ mono_set_pending_exception ((MonoException *) exc);
return ares;
}
}
return res;
}
+/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static MonoObject *
mono_delegate_end_invoke (MonoDelegate *delegate, gpointer *params)
{
if (!delegate->method_info) {
g_assert (delegate->method);
MonoReflectionMethod *rm = mono_method_get_object_checked (domain, delegate->method, NULL, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
MONO_OBJECT_SETREF (delegate, method_info, rm);
}
ares = (MonoAsyncResult *)mono_array_get (msg->args, gpointer, sig->param_count - 1);
if (ares == NULL) {
- mono_raise_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingException", "The async result object is null or of an unexpected type."));
+ mono_set_pending_exception (mono_exception_from_name_msg (mono_defaults.corlib, "System.Runtime.Remoting", "RemotingException", "The async result object is null or of an unexpected type."));
return NULL;
}
if (ares->async_delegate != (MonoObject*)delegate) {
- mono_raise_exception (mono_get_exception_invalid_operation (
+ mono_set_pending_exception (mono_get_exception_invalid_operation (
"The IAsyncResult object provided does not match this delegate."));
return NULL;
}
if (delegate->target && mono_object_is_transparent_proxy (delegate->target)) {
MonoTransparentProxy* tp = (MonoTransparentProxy *)delegate->target;
msg = (MonoMethodMessage *)mono_object_new_checked (domain, mono_defaults.mono_method_message_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
mono_message_init (domain, msg, delegate->method_info, NULL);
msg->call_type = CallType_EndInvoke;
MONO_OBJECT_SETREF (msg, async_result, ares);
- res = mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args);
+ res = mono_remoting_invoke ((MonoObject *)tp->rp, msg, &exc, &out_args, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
} else
#endif
{
MONO_OBJECT_SETREF (((MonoException*)exc), stack_trace, mono_string_new (domain, tmp));
g_free (tmp);
}
- mono_raise_exception ((MonoException*)exc);
+ mono_set_pending_exception ((MonoException*)exc);
}
mono_method_return_message_restore (method, params, out_args);
if (callvirt) {
subtype = WRAPPER_SUBTYPE_DELEGATE_INVOKE_VIRTUAL;
if (target_method->is_inflated) {
+ MonoError error;
MonoType *target_type;
g_assert (method->signature->hasthis);
- target_type = mono_class_inflate_generic_type (method->signature->params [0],
- mono_method_get_context (method));
+ target_type = mono_class_inflate_generic_type_checked (method->signature->params [0],
+ mono_method_get_context (method), &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
target_class = mono_class_from_mono_type (target_type);
} else {
target_class = target_method->klass;
MonoMethod *
mono_marshal_get_managed_wrapper (MonoMethod *method, MonoClass *delegate_klass, uint32_t target_handle)
{
+ MonoError error;
MonoMethodSignature *sig, *csig, *invoke_sig;
MonoMethodBuilder *mb;
MonoMethod *res, *invoke;
* contents of the attribute without constructing it, as that might not be
* possible when running in cross-compiling mode.
*/
- cinfo = mono_custom_attrs_from_class (delegate_klass);
+ cinfo = mono_custom_attrs_from_class_checked (delegate_klass, &error);
+ mono_error_assert_ok (&error);
attr = NULL;
if (cinfo) {
for (i = 0; i < cinfo->num_attrs; ++i) {
return res;
}
+/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static void*
ves_icall_marshal_alloc (gulong size)
{
MonoError error;
void *ret = mono_marshal_alloc (size, &error);
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return ret;
}
return s ? mono_string_chars (s) : NULL;
}
+/* This is a JIT icall, it sets the pending exception and returns NULL on error. */
static void *
mono_marshal_string_to_utf16_copy (MonoString *s)
{
} else {
MonoError error;
gunichar2 *res = (gunichar2 *)mono_marshal_alloc ((mono_string_length (s) * 2) + 2, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
memcpy (res, mono_string_chars (s), mono_string_length (s) * 2);
res [mono_string_length (s)] = 0;
return res;
len++;
res = mono_string_new_utf16_checked (domain, ptr, len, &error);
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return res;
}
pa [2] = &delete_old;
mono_runtime_invoke_checked (method, NULL, pa, &error);
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
}
static void
-ptr_to_structure (gpointer src, MonoObject *dst)
+ptr_to_structure (gpointer src, MonoObject *dst, MonoError *error)
{
- MonoError error;
MonoMethod *method;
gpointer pa [2];
+ mono_error_init (error);
+
method = mono_marshal_get_ptr_to_struct (dst->vtable->klass);
pa [0] = &src;
pa [1] = dst;
- mono_runtime_invoke_checked (method, NULL, pa, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_invoke_checked (method, NULL, pa, error);
}
void
ves_icall_System_Runtime_InteropServices_Marshal_PtrToStructure (gpointer src, MonoObject *dst)
{
MonoType *t;
+ MonoError error;
MONO_CHECK_ARG_NULL (src,);
MONO_CHECK_ARG_NULL (dst,);
return;
}
- ptr_to_structure (src, dst);
+ ptr_to_structure (src, dst, &error);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
}
MonoObject *
}
res = mono_object_new_checked (domain, klass, &error);
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
- ptr_to_structure (src, res);
+ ptr_to_structure (src, res, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
return res;
}
#else
res = g_try_malloc (s);
#endif
- if (!res)
- mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
+ if (!res) {
+ mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
+ return NULL;
+ }
return res;
}
size_t s = (size_t)size;
if (ptr == NULL) {
- mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
+ mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
return NULL;
}
#else
res = g_try_realloc (ptr, s);
#endif
- if (!res)
- mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
+ if (!res) {
+ mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
+ return NULL;
+ }
return res;
}
res = g_try_malloc ((gulong)size);
#endif
- if (!res)
- mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
+ if (!res) {
+ mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
+ return NULL;
+ }
return res;
}
#else
res = g_try_realloc (ptr, (gulong)size);
#endif
- if (!res)
- mono_raise_exception (mono_domain_get ()->out_of_memory_ex);
+ if (!res) {
+ mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
+ return NULL;
+ }
return res;
}
return 0;
}
+/* This is a JIT icall, it sets the pending exception and return NULL on error */
gpointer
mono_marshal_asany (MonoObject *o, MonoMarshalNative string_encoding, int param_attrs)
{
return mono_object_unbox (o);
res = mono_marshal_alloc (mono_class_native_size (klass, NULL), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
if (!((param_attrs & PARAM_ATTRIBUTE_OUT) && !(param_attrs & PARAM_ATTRIBUTE_IN))) {
method = mono_marshal_get_struct_to_ptr (o->vtable->klass);
pa [2] = &delete_old;
mono_runtime_invoke_checked (method, NULL, pa, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
}
return res;
default:
break;
}
- mono_raise_exception (mono_get_exception_argument ("", "No PInvoke conversion exists for value passed to Object-typed parameter."));
+ mono_set_pending_exception (mono_get_exception_argument ("", "No PInvoke conversion exists for value passed to Object-typed parameter."));
return NULL;
}
+/* This is a JIT icall, it sets the pending exception */
void
mono_marshal_free_asany (MonoObject *o, gpointer ptr, MonoMarshalNative string_encoding, int param_attrs)
{
pa [1] = o;
mono_runtime_invoke_checked (method, NULL, pa, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return;
+ }
}
if (!((param_attrs & PARAM_ATTRIBUTE_OUT) && !(param_attrs & PARAM_ATTRIBUTE_IN))) {
MonoGenericContext *context,
MonoError *error);
-MONO_API MonoType *
-mono_metadata_parse_type_full (MonoImage *image,
- MonoGenericContainer *container,
- short opt_attrs,
- const char *ptr,
- const char **rptr);
-
MONO_API MonoMethodSignature *
mono_metadata_parse_method_signature_full (MonoImage *image,
MonoGenericContainer *generic_container,
MONO_API MonoMethodHeader *
mono_metadata_parse_mh_full (MonoImage *image,
MonoGenericContainer *container,
- const char *ptr);
+ const char *ptr,
+ MonoError *error);
gboolean
mono_method_get_header_summary (MonoMethod *method, MonoMethodHeaderSummary *summary);
{
MonoError error;
MonoArrayType *ret = mono_metadata_parse_array_internal (m, NULL, FALSE, ptr, rptr, &error);
- if (!ret) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /*FIXME don't swallow the error message*/
- }
+ mono_error_cleanup (&error);
+
return ret;
}
return mono_metadata_parse_type_internal (m, container, opt_attrs, transient, ptr, rptr, error);
}
-
-MonoType*
-mono_metadata_parse_type_full (MonoImage *m, MonoGenericContainer *container,
- short opt_attrs, const char *ptr, const char **rptr)
-{
- MonoError error;
- MonoType * type = mono_metadata_parse_type_internal (m, container, opt_attrs, FALSE, ptr, rptr, &error);
- mono_loader_assert_no_error ();
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error);
- }
-
- return type;
-}
-
/*
* LOCKING: Acquires the loader lock.
*/
mono_metadata_parse_type (MonoImage *m, MonoParseTypeMode mode, short opt_attrs,
const char *ptr, const char **rptr)
{
- return mono_metadata_parse_type_full (m, NULL, opt_attrs, ptr, rptr);
+ MonoError error;
+ MonoType * type = mono_metadata_parse_type_internal (m, NULL, opt_attrs, FALSE, ptr, rptr, &error);
+ mono_error_cleanup (&error);
+ return type;
}
gboolean
/*
* mono_metadata_parse_generic_param:
* @generic_container: Our MonoClass's or MonoMethod's MonoGenericContainer;
- * see mono_metadata_parse_type_full() for details.
+ * see mono_metadata_parse_type_checked() for details.
* Internal routine to parse a generic type parameter.
* LOCKING: Acquires the loader lock
*/
* @ptr: Points to the beginning of the Section Data (25.3)
*/
static MonoExceptionClause*
-parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr)
+parse_section_data (MonoImage *m, int *num_clauses, const unsigned char *ptr, MonoError *error)
{
unsigned char sect_data_flags;
int is_fat;
guint32 sect_data_len;
MonoExceptionClause* clauses = NULL;
+
+ mono_error_init (error);
while (1) {
/* align on 32-bit boundary */
} else if (ec->flags == MONO_EXCEPTION_CLAUSE_NONE) {
ec->data.catch_class = NULL;
if (tof_value) {
- MonoError error;
- ec->data.catch_class = mono_class_get_checked (m, tof_value, &error);
- if (!mono_error_ok (&error)) {
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ ec->data.catch_class = mono_class_get_checked (m, tof_value, error);
+ if (!is_ok (error)) {
g_free (clauses);
return NULL;
}
return FALSE;
ptr = mono_image_rva_map (img, rva);
- g_assert (ptr);
+ if (!ptr)
+ return FALSE;
flags = *(const unsigned char *)ptr;
format = flags & METHOD_HEADER_FORMAT_MASK;
* Returns: a transient MonoMethodHeader allocated from the heap.
*/
MonoMethodHeader *
-mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr)
+mono_metadata_parse_mh_full (MonoImage *m, MonoGenericContainer *container, const char *ptr, MonoError *error)
{
MonoMethodHeader *mh = NULL;
unsigned char flags = *(const unsigned char *) ptr;
MonoTableInfo *t = &m->tables [MONO_TABLE_STANDALONESIG];
guint32 cols [MONO_STAND_ALONE_SIGNATURE_SIZE];
- g_return_val_if_fail (ptr != NULL, NULL);
+ mono_error_init (error);
+
+ if (!ptr) {
+ mono_error_set_bad_image (error, m, "Method header with null pointer");
+ return NULL;
+ }
switch (format) {
case METHOD_HEADER_TINY_FORMAT:
ptr = (char*)code + code_size;
break;
default:
+ mono_error_set_bad_image (error, m, "Invalid method header format %d", format);
return NULL;
}
if (local_var_sig_tok) {
int idx = (local_var_sig_tok & 0xffffff)-1;
- if (idx >= t->rows || idx < 0)
+ if (idx >= t->rows || idx < 0) {
+ mono_error_set_bad_image (error, m, "Invalid method header local vars signature token 0x%8x", idx);
goto fail;
+ }
mono_metadata_decode_row (t, idx, cols, 1);
- if (!mono_verifier_verify_standalone_signature (m, cols [MONO_STAND_ALONE_SIGNATURE], NULL))
+ if (!mono_verifier_verify_standalone_signature (m, cols [MONO_STAND_ALONE_SIGNATURE], NULL)) {
+ mono_error_set_bad_image (error, m, "Method header locals signature 0x%8x verification failed", idx);
+ goto fail;
+ }
+ }
+ if (fat_flags & METHOD_HEADER_MORE_SECTS) {
+ clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr, error);
+ if (!is_ok (error))
goto fail;
}
- if (fat_flags & METHOD_HEADER_MORE_SECTS)
- clauses = parse_section_data (m, &num_clauses, (const unsigned char*)ptr);
if (local_var_sig_tok) {
const char *locals_ptr;
int len=0, i;
mh = (MonoMethodHeader *)g_malloc0 (MONO_SIZEOF_METHOD_HEADER + len * sizeof (MonoType*) + num_clauses * sizeof (MonoExceptionClause));
mh->num_locals = len;
for (i = 0; i < len; ++i) {
- MonoError error;
- mh->locals [i] = mono_metadata_parse_type_internal (m, container, 0, TRUE, locals_ptr, &locals_ptr, &error);
- if (!mono_error_ok (&error)) {
- mono_loader_set_error_from_mono_error (&error);
- mono_error_cleanup (&error); /* FIXME don't swallow the error */
- }
-
- if (!mh->locals [i])
+ mh->locals [i] = mono_metadata_parse_type_internal (m, container, 0, TRUE, locals_ptr, &locals_ptr, error);
+ if (!is_ok (error))
goto fail;
}
} else {
MonoMethodHeader *
mono_metadata_parse_mh (MonoImage *m, const char *ptr)
{
- return mono_metadata_parse_mh_full (m, NULL, ptr);
+ MonoError error;
+ MonoMethodHeader *header = mono_metadata_parse_mh_full (m, NULL, ptr, &error);
+ mono_error_cleanup (&error);
+ return header;
}
/*
MonoType *
mono_metadata_parse_field_type (MonoImage *m, short field_flags, const char *ptr, const char **rptr)
{
- return mono_metadata_parse_type (m, MONO_PARSE_FIELD, field_flags, ptr, rptr);
+ MonoError error;
+ MonoType * type = mono_metadata_parse_type_internal (m, NULL, field_flags, FALSE, ptr, rptr, &error);
+ mono_error_cleanup (&error);
+ return type;
}
/**
MonoType *
mono_metadata_parse_param (MonoImage *m, const char *ptr, const char **rptr)
{
- return mono_metadata_parse_type (m, MONO_PARSE_PARAM, 0, ptr, rptr);
+ MonoError error;
+ MonoType * type = mono_metadata_parse_type_internal (m, NULL, 0, FALSE, ptr, rptr, &error);
+ mono_error_cleanup (&error);
+ return type;
}
/*
MonoCustomMod *dest,
const char *ptr,
const char **rptr);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoArrayType *mono_metadata_parse_array (MonoImage *m,
const char *ptr,
const char **rptr);
MONO_API void mono_metadata_free_array (MonoArrayType *array);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoType *mono_metadata_parse_type (MonoImage *m,
MonoParseTypeMode mode,
short opt_attrs,
const char *ptr,
const char **rptr);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoType *mono_metadata_parse_param (MonoImage *m,
const char *ptr,
const char **rptr);
MONO_API MonoType *mono_metadata_parse_ret_type (MonoImage *m,
const char *ptr,
const char **rptr);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoType *mono_metadata_parse_field_type (MonoImage *m,
short field_flags,
const char *ptr,
MONO_API unsigned int mono_signature_hash (MonoMethodSignature *sig);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoMethodHeader *mono_metadata_parse_mh (MonoImage *m, const char *ptr);
MONO_API void mono_metadata_free_mh (MonoMethodHeader *mh);
#ifndef DISABLE_JIT
mb->code_size = 40;
mb->code = (unsigned char *)g_malloc (mb->code_size);
+ mb->init_locals = TRUE;
#endif
/* placeholder for the wrapper always at index 1 */
mono_mb_add_data (mb, NULL);
header->code_size = mb->pos;
header->num_locals = mb->locals;
- header->init_locals = TRUE;
+ header->init_locals = mb->init_locals;
header->num_clauses = mb->num_clauses;
header->clauses = mb->clauses;
GList *locals_list;
int locals;
gboolean dynamic;
- gboolean skip_visibility;
+ gboolean skip_visibility, init_locals;
guint32 code_size, pos;
unsigned char *code;
int num_clauses;
MonoSimpleBasicBlock*
mono_basic_block_split (MonoMethod *method, MonoError *error)
{
+ MonoError inner_error;
MonoSimpleBasicBlock *bb, *root;
const unsigned char *start, *end;
- MonoMethodHeader *header = mono_method_get_header (method);
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &inner_error);
mono_error_init (error);
if (!header) {
- mono_error_set_not_verifiable (error, method, "Could not decode header");
+ mono_error_set_not_verifiable (error, method, "Could not decode header due to %s", mono_error_get_message (&inner_error));
+ mono_error_cleanup (&inner_error);
return NULL;
}
return retval; \
}; }G_STMT_END
+/* Use this as MONO_ARG_NULL (arg,) in functions returning void */
+#define MONO_CHECK_NULL(arg, retval) G_STMT_START{ \
+ if (G_UNLIKELY (arg == NULL)) \
+ { \
+ MonoException *ex; \
+ if (arg) {} /* check if the name exists */ \
+ ex = mono_get_exception_null_reference (); \
+ mono_set_pending_exception (ex); \
+ return retval; \
+ }; }G_STMT_END
+
#define mono_string_builder_capacity(sb) sb->chunkOffset + sb->chunkChars->max_length
#define mono_string_builder_string_length(sb) sb->chunkOffset + sb->chunkLength
#ifndef DISABLE_REMOTING
MonoObject *
-mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
- MonoObject **exc, MonoArray **out_args);
+mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, MonoObject **exc, MonoArray **out_args, MonoError *error);
gpointer
mono_remote_class_vtable (MonoDomain *domain, MonoRemoteClass *remote_class, MonoRealProxy *real_proxy);
gboolean
mono_monitor_is_il_fastpath_wrapper (MonoMethod *method);
+MonoString*
+mono_string_intern_checked (MonoString *str, MonoError *error);
+
char *
mono_exception_get_native_backtrace (MonoException *exc);
#include <mono/metadata/object.h>
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
#include <mono/metadata/domain-internals.h>
#include "mono/metadata/metadata-internals.h"
#include "mono/metadata/class-internals.h"
{
MONO_REQ_GC_UNSAFE_MODE;
+ MonoError error;
MonoDomain *domain = vtable->domain;
MonoClass *klass = vtable->klass;
MonoException *ex;
full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
else
full_name = g_strdup (klass->name);
- ex = mono_get_exception_type_initialization (full_name, NULL);
+ ex = mono_get_exception_type_initialization_checked (full_name, NULL, &error);
g_free (full_name);
+ return_val_if_nok (&error, NULL);
}
return ex;
full_name = g_strdup_printf ("%s.%s", klass->name_space, klass->name);
else
full_name = g_strdup (klass->name);
- mono_error_set_exception_instance (error, mono_get_exception_type_initialization (full_name, exc));
+
+ MonoException *exc_to_throw = mono_get_exception_type_initialization_checked (full_name, exc, error);
g_free (full_name);
+ return_val_if_nok (error, FALSE);
+
+ mono_error_set_exception_instance (error, exc_to_throw);
MonoException *exc_to_store = mono_error_convert_to_exception (error);
/* What we really want to do here is clone the error object and store one copy in the
{
MONO_REQ_GC_NEUTRAL_MODE;
+ MonoError error;
MonoCustomAttrInfo *ainfo;
int i;
- ainfo = mono_custom_attrs_from_field (fklass, field);
+ ainfo = mono_custom_attrs_from_field_checked (fklass, field, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error? */
if (!ainfo)
return FALSE;
for (i = 0; i < ainfo->num_attrs; ++i) {
cm = klass->vtable [i];
if (cm) {
- vt->vtable [i] = callbacks.create_jit_trampoline (domain, cm, &error);
- if (!mono_error_ok (&error))
- mono_error_raise_exception (&error); /* FIXME: Don't raise here */
+ vt->vtable [i] = callbacks.create_jit_trampoline (domain, cm, error);
+ if (!is_ok (error)) {
+ mono_domain_unlock (domain);
+ mono_loader_unlock ();
+ return NULL;
+ }
}
}
}
}
}
- cinfo = mono_custom_attrs_from_method (method);
+ cinfo = mono_custom_attrs_from_method_checked (method, &error);
+ mono_error_cleanup (&error); /* FIXME warn here? */
if (cinfo) {
has_stathread_attribute = mono_custom_attrs_has_attr (cinfo, mono_class_get_sta_thread_attribute_class ());
if (!cinfo->cached)
if (G_UNLIKELY (!o))
mono_error_set_out_of_memory (error, "Could not allocate %i bytes", mono_class_instance_size (klass));
else if (G_UNLIKELY (vtable->klass->has_finalize))
- mono_object_register_finalizer (o);
+ mono_object_register_finalizer (o, error);
return o;
}
if (G_UNLIKELY (!o))
mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
else if (G_UNLIKELY (vtable->klass->has_finalize))
- mono_object_register_finalizer (o);
+ mono_object_register_finalizer (o, error);
return o;
}
if (G_UNLIKELY (!o))
mono_error_set_out_of_memory (error, "Could not allocate %i bytes", vtable->klass->instance_size);
else if (G_UNLIKELY (vtable->klass->has_finalize))
- mono_object_register_finalizer (o);
+ mono_object_register_finalizer (o, error);
return o;
}
mono_gc_wbarrier_object_copy (o, obj);
if (obj->vtable->klass->has_finalize)
- mono_object_register_finalizer (o);
+ mono_object_register_finalizer (o, error);
return o;
}
}
#endif
#endif
- if (klass->has_finalize)
- mono_object_register_finalizer (res);
+ if (klass->has_finalize) {
+ mono_object_register_finalizer (res, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+ }
return res;
}
}
static MonoString*
-mono_string_is_interned_lookup (MonoString *str, int insert)
+mono_string_is_interned_lookup (MonoString *str, int insert, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
MonoGHashTable *ldstr_table;
MonoString *s, *res;
MonoDomain *domain;
+ mono_error_init (error);
+
domain = ((MonoObject *)str)->vtable->domain;
ldstr_table = domain->ldstr_table;
ldstr_lock ();
if (insert) {
/* Allocate outside the lock */
ldstr_unlock ();
- s = mono_string_get_pinned (str, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ s = mono_string_get_pinned (str, error);
+ return_val_if_nok (error, NULL);
if (s) {
ldstr_lock ();
res = (MonoString *)mono_g_hash_table_lookup (ldstr_table, str);
MonoString*
mono_string_is_interned (MonoString *o)
{
- MONO_REQ_GC_UNSAFE_MODE;
-
- return mono_string_is_interned_lookup (o, FALSE);
+ MonoError error;
+ MonoString *result = mono_string_is_interned_lookup (o, FALSE, &error);
+ /* This function does not fail. */
+ mono_error_assert_ok (&error);
+ return result;
}
/**
*/
MonoString*
mono_string_intern (MonoString *str)
+{
+ MonoError error;
+ MonoString *result = mono_string_intern_checked (str, &error);
+ mono_error_assert_ok (&error);
+ return result;
+}
+
+/**
+ * mono_string_intern_checked:
+ * @o: String to intern
+ * @error: set on error.
+ *
+ * Interns the string passed.
+ * Returns: The interned string. On failure returns NULL and sets @error
+ */
+MonoString*
+mono_string_intern_checked (MonoString *str, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- return mono_string_is_interned_lookup (str, TRUE);
+ mono_error_init (error);
+
+ return mono_string_is_interned_lookup (str, TRUE, error);
}
/**
* Returns: the result object.
*/
MonoObject *
-mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg,
- MonoObject **exc, MonoArray **out_args)
+mono_remoting_invoke (MonoObject *real_proxy, MonoMethodMessage *msg, MonoObject **exc, MonoArray **out_args, MonoError *error)
{
MONO_REQ_GC_UNSAFE_MODE;
- MonoError error;
MonoObject *o;
MonoMethod *im = real_proxy->vtable->domain->private_invoke_method;
gpointer pa [4];
+ g_assert (exc);
+
+ mono_error_init (error);
+
/*static MonoObject *(*invoke) (gpointer, gpointer, MonoObject **, MonoArray **) = NULL;*/
if (!im) {
im = mono_class_get_method_from_name (mono_defaults.real_proxy_class, "PrivateInvoke", 4);
- if (!im)
- mono_raise_exception (mono_get_exception_not_supported ("Linked away."));
+ if (!im) {
+ mono_error_set_generic_error (error, "System", "NotSupportedException", "Linked away.");
+ return NULL;
+ }
real_proxy->vtable->domain->private_invoke_method = im;
}
pa [2] = exc;
pa [3] = out_args;
- if (exc) {
- o = mono_runtime_try_invoke (im, NULL, pa, exc, &error);
- } else {
- o = mono_runtime_invoke_checked (im, NULL, pa, &error);
- }
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ o = mono_runtime_try_invoke (im, NULL, pa, exc, error);
+ return_val_if_nok (error, NULL);
return o;
}
if (mono_class_is_contextbound (tp->remote_class->proxy_class) && tp->rp->context == (MonoObject *) mono_context_get ()) {
target = tp->rp->unwrapped_server;
} else {
- return mono_remoting_invoke ((MonoObject *)tp->rp, msg, exc, out_args);
+ ret = mono_remoting_invoke ((MonoObject *)tp->rp, msg, exc, out_args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
+ return ret;
}
}
#endif
mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
g_free (full_name);
- mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+ mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (exc) mono_raise_exception ((MonoException *)exc);
mono_array_setref (msg->args, 1, mono_string_new (domain, mono_field_get_name (field)));
g_free (full_name);
- mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+ mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (exc) mono_raise_exception ((MonoException *)exc);
mono_array_setref (msg->args, 2, arg);
g_free (full_name);
- mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+ mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (exc) mono_raise_exception ((MonoException *)exc);
}
mono_array_setref (msg->args, 2, arg);
g_free (full_name);
- mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args);
+ mono_remoting_invoke ((MonoObject *)(tp->rp), msg, &exc, &out_args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (exc) mono_raise_exception ((MonoException *)exc);
}
MONO_API MonoString*
mono_string_is_interned (MonoString *str);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoString*
mono_string_intern (MonoString *str);
#include <shellapi.h>
#endif
-HANDLE ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
+HANDLE
+ves_icall_System_Diagnostics_Process_GetProcess_internal (guint32 pid)
{
HANDLE handle;
/* GetCurrentProcess returns a pseudo-handle, so use
* OpenProcess instead
*/
- handle=OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
-
- if(handle==NULL) {
+ handle = OpenProcess (PROCESS_ALL_ACCESS, TRUE, pid);
+ if (handle == NULL)
/* FIXME: Throw an exception */
- return(NULL);
- }
-
- return(handle);
+ return NULL;
+ return handle;
}
-#define STASH_SYS_ASS(this_obj) \
- if(system_assembly == NULL) { \
- system_assembly=this_obj->vtable->klass->image; \
- }
+static MonoImage *system_assembly;
-static MonoImage *system_assembly=NULL;
+static void
+stash_system_assembly (MonoObject *obj)
+{
+ if (!system_assembly)
+ system_assembly = obj->vtable->klass->image;
+}
//Hand coded version that loads from system
static MonoClass*
return klass;
}
-
-static guint32 unicode_chars (const gunichar2 *str)
+static guint32
+unicode_chars (const gunichar2 *str)
{
- guint32 len=0;
-
- do {
- if(str[len]=='\0') {
- return(len);
- }
- len++;
- } while(1);
+ guint32 len;
+
+ for (len = 0; str [len] != '\0'; ++len)
+ ;
+ return len;
}
-static void process_set_field_object (MonoObject *obj, const gchar *fieldname,
- MonoObject *data)
+static void
+process_set_field_object (MonoObject *obj, const gchar *fieldname,
+ MonoObject *data)
{
MonoClassField *field;
LOGDEBUG (g_message ("%s: Setting field %s to object at %p", __func__, fieldname, data));
- field=mono_class_get_field_from_name (mono_object_class (obj),
- fieldname);
+ field = mono_class_get_field_from_name (mono_object_class (obj),
+ fieldname);
mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, data);
}
-static void process_set_field_string (MonoObject *obj, const gchar *fieldname,
- const gunichar2 *val, guint32 len)
+static void
+process_set_field_string (MonoObject *obj, const gchar *fieldname,
+ const gunichar2 *val, guint32 len, MonoError *error)
{
- MonoError error;
MonoClassField *field;
MonoString *string;
+ mono_error_init (error);
+
LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, g_utf16_to_utf8 (val, len, NULL, NULL, NULL)));
- string = mono_string_new_utf16_checked (mono_object_domain (obj), val, len, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ string = mono_string_new_utf16_checked (mono_object_domain (obj), val, len, error);
- field=mono_class_get_field_from_name (mono_object_class (obj),
- fieldname);
+ field = mono_class_get_field_from_name (mono_object_class (obj),
+ fieldname);
mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string);
}
-static void process_set_field_string_char (MonoObject *obj, const gchar *fieldname,
- const gchar *val)
+static void
+process_set_field_string_char (MonoObject *obj, const gchar *fieldname,
+ const gchar *val)
{
MonoClassField *field;
MonoString *string;
LOGDEBUG (g_message ("%s: Setting field %s to [%s]", __func__, fieldname, val));
- string=mono_string_new (mono_object_domain (obj), val);
+ string = mono_string_new (mono_object_domain (obj), val);
- field=mono_class_get_field_from_name (mono_object_class (obj), fieldname);
+ field = mono_class_get_field_from_name (mono_object_class (obj), fieldname);
mono_gc_wbarrier_generic_store (((char *)obj) + field->offset, (MonoObject*)string);
}
-static void process_set_field_int (MonoObject *obj, const gchar *fieldname,
- guint32 val)
+static void
+process_set_field_int (MonoObject *obj, const gchar *fieldname,
+ guint32 val)
{
MonoClassField *field;
LOGDEBUG (g_message ("%s: Setting field %s to %d", __func__,fieldname, val));
- field=mono_class_get_field_from_name (mono_object_class (obj),
+ field = mono_class_get_field_from_name (mono_object_class (obj),
fieldname);
*(guint32 *)(((char *)obj) + field->offset)=val;
}
-static void process_set_field_intptr (MonoObject *obj, const gchar *fieldname,
- gpointer val)
+static void
+process_set_field_intptr (MonoObject *obj, const gchar *fieldname,
+ gpointer val)
{
MonoClassField *field;
LOGDEBUG (g_message ("%s: Setting field %s to %p", __func__, fieldname, val));
- field=mono_class_get_field_from_name (mono_object_class (obj),
- fieldname);
- *(gpointer *)(((char *)obj) + field->offset)=val;
+ field = mono_class_get_field_from_name (mono_object_class (obj),
+ fieldname);
+ *(gpointer *)(((char *)obj) + field->offset) = val;
}
-static void process_set_field_bool (MonoObject *obj, const gchar *fieldname,
- gboolean val)
+static void
+process_set_field_bool (MonoObject *obj, const gchar *fieldname,
+ gboolean val)
{
MonoClassField *field;
- LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val?"TRUE":"FALSE"));
+ LOGDEBUG (g_message ("%s: Setting field %s to %s", __func__, fieldname, val ? "TRUE":"FALSE"));
- field=mono_class_get_field_from_name (mono_object_class (obj),
- fieldname);
- *(guint8 *)(((char *)obj) + field->offset)=val;
+ field = mono_class_get_field_from_name (mono_object_class (obj),
+ fieldname);
+ *(guint8 *)(((char *)obj) + field->offset) = val;
}
#define SFI_COMMENTS "\\StringFileInfo\\%02X%02X%02X%02X\\Comments"
#define SFI_SPECIALBUILD "\\StringFileInfo\\%02X%02X%02X%02X\\SpecialBuild"
#define EMPTY_STRING (gunichar2*)"\000\000"
-static void process_module_string_read (MonoObject *filever, gpointer data,
- const gchar *fieldname,
- guchar lang_hi, guchar lang_lo,
- const gchar *key)
+static void
+process_module_string_read (MonoObject *filever, gpointer data,
+ const gchar *fieldname,
+ guchar lang_hi, guchar lang_lo,
+ const gchar *key, MonoError *error)
{
gchar *lang_key_utf8;
gunichar2 *lang_key, *buffer;
UINT chars;
+ mono_error_init (error);
+
lang_key_utf8 = g_strdup_printf (key, lang_lo, lang_hi, 0x04, 0xb0);
LOGDEBUG (g_message ("%s: asking for [%s]", __func__, lang_key_utf8));
if (VerQueryValue (data, lang_key, (gpointer *)&buffer, &chars) && chars > 0) {
LOGDEBUG (g_message ("%s: found %d chars of [%s]", __func__, chars, g_utf16_to_utf8 (buffer, chars, NULL, NULL, NULL)));
/* chars includes trailing null */
- process_set_field_string (filever, fieldname, buffer, chars - 1);
+ process_set_field_string (filever, fieldname, buffer, chars - 1, error);
} else {
- process_set_field_string (filever, fieldname, EMPTY_STRING, 0);
+ process_set_field_string (filever, fieldname, EMPTY_STRING, 0, error);
}
g_free (lang_key);
g_free (lang_key_utf8);
}
-static void process_module_stringtable (MonoObject *filever, gpointer data,
- guchar lang_hi, guchar lang_lo)
+typedef struct {
+ const char *name;
+ const char *id;
+} StringTableEntry;
+
+static StringTableEntry stringtable_entries [] = {
+ { "comments", SFI_COMMENTS },
+ { "companyname", SFI_COMPANYNAME },
+ { "filedescription", SFI_FILEDESCRIPTION },
+ { "fileversion", SFI_FILEVERSION },
+ { "internalname", SFI_INTERNALNAME },
+ { "legalcopyright", SFI_LEGALCOPYRIGHT },
+ { "legaltrademarks", SFI_LEGALTRADEMARKS },
+ { "originalfilename", SFI_ORIGINALFILENAME },
+ { "privatebuild", SFI_PRIVATEBUILD },
+ { "productname", SFI_PRODUCTNAME },
+ { "productversion", SFI_PRODUCTVERSION },
+ { "specialbuild", SFI_SPECIALBUILD }
+};
+
+static void
+process_module_stringtable (MonoObject *filever, gpointer data,
+ guchar lang_hi, guchar lang_lo, MonoError *error)
{
- process_module_string_read (filever, data, "comments", lang_hi, lang_lo,
- SFI_COMMENTS);
- process_module_string_read (filever, data, "companyname", lang_hi,
- lang_lo, SFI_COMPANYNAME);
- process_module_string_read (filever, data, "filedescription", lang_hi,
- lang_lo, SFI_FILEDESCRIPTION);
- process_module_string_read (filever, data, "fileversion", lang_hi,
- lang_lo, SFI_FILEVERSION);
- process_module_string_read (filever, data, "internalname", lang_hi,
- lang_lo, SFI_INTERNALNAME);
- process_module_string_read (filever, data, "legalcopyright", lang_hi,
- lang_lo, SFI_LEGALCOPYRIGHT);
- process_module_string_read (filever, data, "legaltrademarks", lang_hi,
- lang_lo, SFI_LEGALTRADEMARKS);
- process_module_string_read (filever, data, "originalfilename", lang_hi,
- lang_lo, SFI_ORIGINALFILENAME);
- process_module_string_read (filever, data, "privatebuild", lang_hi,
- lang_lo, SFI_PRIVATEBUILD);
- process_module_string_read (filever, data, "productname", lang_hi,
- lang_lo, SFI_PRODUCTNAME);
- process_module_string_read (filever, data, "productversion", lang_hi,
- lang_lo, SFI_PRODUCTVERSION);
- process_module_string_read (filever, data, "specialbuild", lang_hi,
- lang_lo, SFI_SPECIALBUILD);
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
+ process_module_string_read (filever, data, stringtable_entries [i].name, lang_hi, lang_lo,
+ stringtable_entries [i].id, error);
+ return_if_nok (error);
+ }
}
-static void process_get_fileversion (MonoObject *filever, gunichar2 *filename)
+static void
+process_get_fileversion (MonoObject *filever, gunichar2 *filename, MonoError *error)
{
DWORD verinfohandle;
VS_FIXEDFILEINFO *ffi;
gunichar2 lang_buf[128];
guint32 lang, lang_count;
+ mono_error_init (error);
+
datalen = GetFileVersionInfoSize (filename, &verinfohandle);
if (datalen) {
data = g_malloc0 (datalen);
*/
lang_count = VerLanguageName (lang & 0xFFFF, lang_buf, 128);
if (lang_count) {
- process_set_field_string (filever, "language", lang_buf, lang_count);
+ process_set_field_string (filever, "language", lang_buf, lang_count, error);
+ return_if_nok (error);
}
- process_module_stringtable (filever, data, trans_data[0], trans_data[1]);
+ process_module_stringtable (filever, data, trans_data[0], trans_data[1], error);
+ return_if_nok (error);
}
} else {
- /* No strings, so set every field to
- * the empty string
- */
- process_set_field_string (filever,
- "comments",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "companyname",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "filedescription",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "fileversion",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "internalname",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "legalcopyright",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "legaltrademarks",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "originalfilename",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "privatebuild",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "productname",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "productversion",
- EMPTY_STRING, 0);
- process_set_field_string (filever,
- "specialbuild",
- EMPTY_STRING, 0);
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (stringtable_entries); ++i) {
+ /* No strings, so set every field to
+ * the empty string
+ */
+ process_set_field_string (filever,
+ stringtable_entries [i].name,
+ EMPTY_STRING, 0, error);
+ return_if_nok (error);
+ }
/* And language seems to be set to
* en_US according to bug 374600
*/
lang_count = VerLanguageName (0x0409, lang_buf, 128);
if (lang_count) {
- process_set_field_string (filever, "language", lang_buf, lang_count);
+ process_set_field_string (filever, "language", lang_buf, lang_count, error);
+ return_if_nok (error);
}
}
}
}
-static void process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly)
+static void
+process_get_assembly_fileversion (MonoObject *filever, MonoAssembly *assembly)
{
process_set_field_int (filever, "filemajorpart", assembly->aname.major);
process_set_field_int (filever, "fileminorpart", assembly->aname.minor);
process_set_field_int (filever, "filebuildpart", assembly->aname.build);
}
-static MonoObject* get_process_module (MonoAssembly *assembly, MonoClass *proc_class)
+static MonoObject*
+get_process_module (MonoAssembly *assembly, MonoClass *proc_class, MonoError *error)
{
- MonoError error;
MonoObject *item, *filever;
MonoDomain *domain = mono_domain_get ();
char *filename;
const char *modulename = assembly->aname.name;
- filename = g_strdup_printf ("[In Memory] %s", modulename);
+ mono_error_init (error);
/* Build a System.Diagnostics.ProcessModule with the data.
*/
- item = mono_object_new_checked (domain, proc_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- filever = mono_object_new_checked (domain, mono_class_get_file_version_info_class (), &error);
- if (!mono_error_ok (&error)) goto leave;
+ item = mono_object_new_checked (domain, proc_class, error);
+ return_val_if_nok (error, NULL);
+ filever = mono_object_new_checked (domain, mono_class_get_file_version_info_class (), error);
+ return_val_if_nok (error, NULL);
+
+ filename = g_strdup_printf ("[In Memory] %s", modulename);
process_get_assembly_fileversion (filever, assembly);
process_set_field_string_char (filever, "filename", filename);
process_set_field_string_char (item, "filename", filename);
process_set_field_string_char (item, "modulename", modulename);
-leave:
g_free (filename);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
return item;
}
-static MonoObject* process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class)
+static MonoObject*
+process_add_module (HANDLE process, HMODULE mod, gunichar2 *filename, gunichar2 *modulename, MonoClass *proc_class, MonoError *error)
{
- MonoError error;
MonoObject *item, *filever;
- MonoDomain *domain=mono_domain_get ();
+ MonoDomain *domain = mono_domain_get ();
MODULEINFO modinfo;
BOOL ok;
-
+
+ mono_error_init (error);
+
/* Build a System.Diagnostics.ProcessModule with the data.
*/
- item=mono_object_new_checked (domain, proc_class, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
- filever = mono_object_new_checked (domain, mono_class_get_file_version_info_class (), &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ item = mono_object_new_checked (domain, proc_class, error);
+ return_val_if_nok (error, NULL);
+ filever = mono_object_new_checked (domain, mono_class_get_file_version_info_class (), error);
+ return_val_if_nok (error, NULL);
- process_get_fileversion (filever, filename);
+ process_get_fileversion (filever, filename, error);
+ return_val_if_nok (error, NULL);
process_set_field_string (filever, "filename", filename,
- unicode_chars (filename));
-
+ unicode_chars (filename), error);
+ return_val_if_nok (error, NULL);
ok = GetModuleInformation (process, mod, &modinfo, sizeof(MODULEINFO));
if (ok) {
process_set_field_intptr (item, "baseaddr",
modinfo.SizeOfImage);
}
process_set_field_string (item, "filename", filename,
- unicode_chars (filename));
+ unicode_chars (filename), error);
+ return_val_if_nok (error, NULL);
process_set_field_string (item, "modulename", modulename,
- unicode_chars (modulename));
+ unicode_chars (modulename), error);
+ return_val_if_nok (error, NULL);
process_set_field_object (item, "version_info", filever);
return item;
}
-static GPtrArray* get_domain_assemblies (MonoDomain *domain)
+static GPtrArray*
+get_domain_assemblies (MonoDomain *domain)
{
GSList *tmp;
GPtrArray *assemblies;
}
/* Returns an array of System.Diagnostics.ProcessModule */
-MonoArray *ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
+MonoArray *
+ves_icall_System_Diagnostics_Process_GetModules_internal (MonoObject *this_obj, HANDLE process)
{
+ MonoError error;
MonoArray *temp_arr = NULL;
MonoArray *arr;
HMODULE mods[1024];
current_process = ves_icall_System_Diagnostics_Process_GetProcess_internal (pid);
}
- STASH_SYS_ASS (this_obj);
+ stash_system_assembly (this_obj);
if (process == current_process) {
assemblies = get_domain_assemblies (mono_domain_get ());
if (GetModuleBaseName (process, mods[i], modname, MAX_PATH) &&
GetModuleFileNameEx (process, mods[i], filename, MAX_PATH)) {
MonoObject *module = process_add_module (process, mods[i],
- filename, modname, mono_class_get_process_module_class ());
+ filename, modname, mono_class_get_process_module_class (), &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
mono_array_setref (temp_arr, num_added++, module);
}
}
if (assemblies) {
for (i = 0; i < assembly_count; i++) {
MonoAssembly *ass = (MonoAssembly *)g_ptr_array_index (assemblies, i);
- MonoObject *module = get_process_module (ass, mono_class_get_process_module_class ());
+ MonoObject *module = get_process_module (ass, mono_class_get_process_module_class (), &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return NULL;
+ }
mono_array_setref (temp_arr, num_added++, module);
}
g_ptr_array_free (assemblies, TRUE);
return arr;
}
-void ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename)
+void
+ves_icall_System_Diagnostics_FileVersionInfo_GetVersionInfo_internal (MonoObject *this_obj, MonoString *filename)
{
- STASH_SYS_ASS (this_obj);
+ MonoError error;
+
+ stash_system_assembly (this_obj);
- process_get_fileversion (this_obj, mono_string_chars (filename));
+ process_get_fileversion (this_obj, mono_string_chars (filename), &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return;
+ }
process_set_field_string (this_obj, "filename",
- mono_string_chars (filename),
- mono_string_length (filename));
+ mono_string_chars (filename),
+ mono_string_length (filename), &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return;
+ }
}
/* Only used when UseShellExecute is false */
return TRUE;
}
-MonoBoolean ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
+MonoBoolean
+ves_icall_System_Diagnostics_Process_ShellExecuteEx_internal (MonoProcessStartInfo *proc_start_info, MonoProcInfo *process_info)
{
SHELLEXECUTEINFO shellex = {0};
gboolean ret;
shellex.fMask = (gulong)(SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS | SEE_MASK_UNICODE);
shellex.nShow = (gulong)proc_start_info->window_style;
shellex.nShow = (gulong)((shellex.nShow == 0) ? 1 : (shellex.nShow == 1 ? 0 : shellex.nShow));
-
-
+
if (proc_start_info->filename != NULL) {
shellex.lpFile = mono_string_chars (proc_start_info->filename);
}
process_info->tid = 0;
}
- return (ret);
+ return ret;
}
-MonoBoolean ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info)
+MonoBoolean
+ves_icall_System_Diagnostics_Process_CreateProcess_internal (MonoProcessStartInfo *proc_start_info, HANDLE stdin_handle, HANDLE stdout_handle, HANDLE stderr_handle, MonoProcInfo *process_info)
{
gboolean ret;
gunichar2 *dir;
MonoString *cmd = proc_start_info->arguments;
guint32 creation_flags, logon_flags;
- startinfo.cb=sizeof(STARTUPINFO);
- startinfo.dwFlags=STARTF_USESTDHANDLES;
- startinfo.hStdInput=stdin_handle;
- startinfo.hStdOutput=stdout_handle;
- startinfo.hStdError=stderr_handle;
+ startinfo.cb = sizeof(STARTUPINFO);
+ startinfo.dwFlags = STARTF_USESTDHANDLES;
+ startinfo.hStdInput = stdin_handle;
+ startinfo.hStdOutput = stdout_handle;
+ startinfo.hStdError = stderr_handle;
creation_flags = CREATE_UNICODE_ENVIRONMENT;
if (proc_start_info->create_no_window)
#endif
g_free (spath);
- if (process_info->env_keys != NULL) {
+ if (process_info->env_keys) {
gint i, len;
MonoString *ms;
MonoString *key, *value;
/* The default dir name is "". Turn that into NULL to mean
* "current directory"
*/
- if(proc_start_info->working_directory == NULL || mono_string_length (proc_start_info->working_directory)==0) {
- dir=NULL;
- } else {
- dir=mono_string_chars (proc_start_info->working_directory);
- }
+ if (proc_start_info->working_directory == NULL || mono_string_length (proc_start_info->working_directory) == 0)
+ dir = NULL;
+ else
+ dir = mono_string_chars (proc_start_info->working_directory);
if (process_info->username) {
logon_flags = process_info->load_user_profile ? LOGON_WITH_PROFILE : 0;
cmd ? mono_string_chars (cmd) : NULL,
creation_flags, env_vars, dir, &startinfo, &procinfo);
} else {
- ret=CreateProcess (shell_path, cmd? mono_string_chars (cmd): NULL, NULL, NULL, TRUE, creation_flags, env_vars, dir, &startinfo, &procinfo);
+ ret = CreateProcess (shell_path, cmd ? mono_string_chars (cmd): NULL, NULL, NULL, TRUE, creation_flags, env_vars, dir, &startinfo, &procinfo);
}
g_free (env_vars);
if (free_shell_path)
g_free (shell_path);
- if(ret) {
- process_info->process_handle=procinfo.hProcess;
+ if (ret) {
+ process_info->process_handle = procinfo.hProcess;
/*process_info->thread_handle=procinfo.hThread;*/
- process_info->thread_handle=NULL;
+ process_info->thread_handle = NULL;
if (procinfo.hThread != NULL && procinfo.hThread != INVALID_HANDLE_VALUE)
- CloseHandle(procinfo.hThread);
- process_info->pid=procinfo.dwProcessId;
- process_info->tid=procinfo.dwThreadId;
+ CloseHandle (procinfo.hThread);
+ process_info->pid = procinfo.dwProcessId;
+ process_info->tid = procinfo.dwThreadId;
} else {
process_info->pid = -GetLastError ();
}
- return(ret);
+ return ret;
}
-MonoString *ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
+MonoString *
+ves_icall_System_Diagnostics_Process_ProcessName_internal (HANDLE process)
{
MonoError error;
MonoString *string;
DWORD needed;
guint32 len;
- ok=EnumProcessModules (process, &mod, sizeof(mod), &needed);
- if(ok==FALSE) {
- return(NULL);
- }
+ ok = EnumProcessModules (process, &mod, sizeof(mod), &needed);
+ if (!ok)
+ return NULL;
- len=GetModuleBaseName (process, mod, name, MAX_PATH);
- if(len==0) {
- return(NULL);
- }
+ len = GetModuleBaseName (process, mod, name, MAX_PATH);
+ if (len == 0)
+ return NULL;
LOGDEBUG (g_message ("%s: process name is [%s]", __func__, g_utf16_to_utf8 (name, -1, NULL, NULL, NULL)));
string = mono_string_new_utf16_checked (mono_domain_get (), name, len, &error);
-
- mono_error_raise_exception (&error);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
- return(string);
+ return string;
}
/* Returns an array of pids */
*error = perror;
return res;
}
-
void
mono_profiler_coverage_get (MonoProfiler *prof, MonoMethod *method, MonoProfileCoverageFunc func)
{
+ MonoError error;
MonoProfileCoverageInfo* info = NULL;
int i, offset;
guint32 code_size;
if (!info)
return;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_assert_ok (&error);
start = mono_method_header_get_code (header, &code_size, NULL);
debug_minfo = mono_debug_lookup_method (method);
MonoArray*
mono_reflection_get_custom_attrs_data_checked (MonoObject *obj, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_index_checked (MonoImage *image, uint32_t idx, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_method_checked (MonoMethod *method, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *property, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, MonoError *error);
+MonoCustomAttrInfo*
+mono_custom_attrs_from_param_checked (MonoMethod *method, uint32_t param, MonoError *error);
+
+
char*
mono_identifier_unescape_type_name_chars (char* identifier);
{
MONO_REQ_GC_NEUTRAL_MODE;
- if (!ainfo->cached)
+ if (ainfo && !ainfo->cached)
g_free (ainfo);
}
return NULL;
image = method->klass->image;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (!image_is_dynamic (image)) {
/* Obtain local vars signature token */
*/
MonoCustomAttrInfo*
mono_custom_attrs_from_index (MonoImage *image, guint32 idx)
+{
+ MonoError error;
+ MonoCustomAttrInfo *result = mono_custom_attrs_from_index_checked (image, idx, &error);
+ mono_error_cleanup (&error); /* FIXME a better public API that doesn't swallow the error. */
+ return result;
+}
+/**
+ * mono_custom_attrs_from_index_checked:
+ *
+ * Returns: NULL if no attributes are found. On error returns NULL and sets @error.
+ */
+MonoCustomAttrInfo*
+mono_custom_attrs_from_index_checked (MonoImage *image, guint32 idx, MonoError *error)
{
guint32 mtoken, i, len;
guint32 cols [MONO_CUSTOM_ATTR_SIZE];
const char *data;
MonoCustomAttrEntry* attr;
+ mono_error_init (error);
+
ca = &image->tables [MONO_TABLE_CUSTOMATTRIBUTE];
i = mono_metadata_custom_attrs_from_index (image, idx);
ainfo->num_attrs = len;
ainfo->image = image;
for (i = len, tmp = list; i != 0; --i, tmp = tmp->next) {
- MonoError error;
mono_metadata_decode_row (ca, GPOINTER_TO_UINT (tmp->data), cols, MONO_CUSTOM_ATTR_SIZE);
mtoken = cols [MONO_CUSTOM_ATTR_TYPE] >> MONO_CUSTOM_ATTR_TYPE_BITS;
switch (cols [MONO_CUSTOM_ATTR_TYPE] & MONO_CUSTOM_ATTR_TYPE_MASK) {
break;
}
attr = &ainfo->attrs [i - 1];
- attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, &error);
+ attr->ctor = mono_get_method_checked (image, mtoken, NULL, NULL, error);
if (!attr->ctor) {
- g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (&error));
- mono_loader_set_error_from_mono_error (&error);
+ g_warning ("Can't find custom attr constructor image: %s mtoken: 0x%08x due to %s", image->name, mtoken, mono_error_get_message (error));
g_list_free (list);
g_free (ainfo);
return NULL;
MonoCustomAttrInfo*
mono_custom_attrs_from_method (MonoMethod *method)
+{
+ MonoError error;
+ MonoCustomAttrInfo* result = mono_custom_attrs_from_method_checked (method, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_method_checked (MonoMethod *method, MonoError *error)
{
guint32 idx;
+ mono_error_init (error);
+
/*
* An instantiated method has the same cattrs as the generic method definition.
*
idx = mono_method_get_index (method);
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_METHODDEF;
- return mono_custom_attrs_from_index (method->klass->image, idx);
+ return mono_custom_attrs_from_index_checked (method->klass->image, idx, error);
}
MonoCustomAttrInfo*
mono_custom_attrs_from_class (MonoClass *klass)
+{
+ MonoError error;
+ MonoCustomAttrInfo *result = mono_custom_attrs_from_class_checked (klass, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_class_checked (MonoClass *klass, MonoError *error)
{
guint32 idx;
+ mono_error_init (error);
+
if (klass->generic_class)
klass = klass->generic_class->container_class;
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_TYPEDEF;
}
- return mono_custom_attrs_from_index (klass->image, idx);
+ return mono_custom_attrs_from_index_checked (klass->image, idx, error);
}
MonoCustomAttrInfo*
mono_custom_attrs_from_assembly (MonoAssembly *assembly)
+{
+ MonoError error;
+ MonoCustomAttrInfo *result = mono_custom_attrs_from_assembly_checked (assembly, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_assembly_checked (MonoAssembly *assembly, MonoError *error)
{
guint32 idx;
+ mono_error_init (error);
+
if (image_is_dynamic (assembly->image))
return lookup_custom_attr (assembly->image, assembly);
idx = 1; /* there is only one assembly */
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_ASSEMBLY;
- return mono_custom_attrs_from_index (assembly->image, idx);
+ return mono_custom_attrs_from_index_checked (assembly->image, idx, error);
}
static MonoCustomAttrInfo*
-mono_custom_attrs_from_module (MonoImage *image)
+mono_custom_attrs_from_module (MonoImage *image, MonoError *error)
{
guint32 idx;
idx = 1; /* there is only one module */
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_MODULE;
- return mono_custom_attrs_from_index (image, idx);
+ return mono_custom_attrs_from_index_checked (image, idx, error);
}
MonoCustomAttrInfo*
mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property)
+{
+ MonoError error;
+ MonoCustomAttrInfo * result = mono_custom_attrs_from_property_checked (klass, property, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_property_checked (MonoClass *klass, MonoProperty *property, MonoError *error)
{
guint32 idx;
idx = find_property_index (klass, property);
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_PROPERTY;
- return mono_custom_attrs_from_index (klass->image, idx);
+ return mono_custom_attrs_from_index_checked (klass->image, idx, error);
}
MonoCustomAttrInfo*
mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event)
+{
+ MonoError error;
+ MonoCustomAttrInfo * result = mono_custom_attrs_from_event_checked (klass, event, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_event_checked (MonoClass *klass, MonoEvent *event, MonoError *error)
{
guint32 idx;
idx = find_event_index (klass, event);
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_EVENT;
- return mono_custom_attrs_from_index (klass->image, idx);
+ return mono_custom_attrs_from_index_checked (klass->image, idx, error);
}
MonoCustomAttrInfo*
mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field)
+{
+ MonoError error;
+ MonoCustomAttrInfo * result = mono_custom_attrs_from_field_checked (klass, field, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+MonoCustomAttrInfo*
+mono_custom_attrs_from_field_checked (MonoClass *klass, MonoClassField *field, MonoError *error)
{
guint32 idx;
+ mono_error_init (error);
+
if (image_is_dynamic (klass->image)) {
field = mono_metadata_get_corresponding_field_from_generic_type_definition (field);
return lookup_custom_attr (klass->image, field);
idx = find_field_index (klass, field);
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_FIELDDEF;
- return mono_custom_attrs_from_index (klass->image, idx);
+ return mono_custom_attrs_from_index_checked (klass->image, idx, error);
}
/**
*/
MonoCustomAttrInfo*
mono_custom_attrs_from_param (MonoMethod *method, guint32 param)
+{
+ MonoError error;
+ MonoCustomAttrInfo *result = mono_custom_attrs_from_param_checked (method, param, &error);
+ mono_error_cleanup (&error); /* FIXME want a better API that doesn't swallow the error */
+ return result;
+}
+
+/**
+ * mono_custom_attrs_from_param_checked:
+ * @method: handle to the method that we want to retrieve custom parameter information from
+ * @param: parameter number, where zero represent the return value, and one is the first parameter in the method
+ * @error: set on error
+ *
+ * The result must be released with mono_custom_attrs_free().
+ *
+ * Returns: the custom attribute object for the specified parameter, or NULL if there are none. On failure returns NULL and sets @error.
+ */
+MonoCustomAttrInfo*
+mono_custom_attrs_from_param_checked (MonoMethod *method, guint32 param, MonoError *error)
{
MonoTableInfo *ca;
guint32 i, idx, method_index;
MonoImage *image;
MonoReflectionMethodAux *aux;
+ mono_error_init (error);
+
/*
* An instantiated method has the same cattrs as the generic method definition.
*
idx = i;
idx <<= MONO_CUSTOM_ATTR_BITS;
idx |= MONO_CUSTOM_ATTR_PARAMDEF;
- return mono_custom_attrs_from_index (image, idx);
+ return mono_custom_attrs_from_index_checked (image, idx, error);
}
gboolean
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType *)obj);
klass = mono_class_from_mono_type (type);
/*We cannot mono_class_init the class from which we'll load the custom attributes since this must work with broken types.*/
- cinfo = mono_custom_attrs_from_class (klass);
+ cinfo = mono_custom_attrs_from_class_checked (klass, error);
+ return_val_if_nok (error, NULL);
} else if (strcmp ("Assembly", klass->name) == 0 || strcmp ("MonoAssembly", klass->name) == 0) {
MonoReflectionAssembly *rassembly = (MonoReflectionAssembly*)obj;
- cinfo = mono_custom_attrs_from_assembly (rassembly->assembly);
+ cinfo = mono_custom_attrs_from_assembly_checked (rassembly->assembly, error);
+ return_val_if_nok (error, NULL);
} else if (strcmp ("Module", klass->name) == 0 || strcmp ("MonoModule", klass->name) == 0) {
MonoReflectionModule *module = (MonoReflectionModule*)obj;
- cinfo = mono_custom_attrs_from_module (module->image);
+ cinfo = mono_custom_attrs_from_module (module->image, error);
+ return_val_if_nok (error, NULL);
} else if (strcmp ("MonoProperty", klass->name) == 0) {
MonoReflectionProperty *rprop = (MonoReflectionProperty*)obj;
- cinfo = mono_custom_attrs_from_property (rprop->property->parent, rprop->property);
+ cinfo = mono_custom_attrs_from_property_checked (rprop->property->parent, rprop->property, error);
+ return_val_if_nok (error, NULL);
} else if (strcmp ("MonoEvent", klass->name) == 0) {
MonoReflectionMonoEvent *revent = (MonoReflectionMonoEvent*)obj;
- cinfo = mono_custom_attrs_from_event (revent->event->parent, revent->event);
+ cinfo = mono_custom_attrs_from_event_checked (revent->event->parent, revent->event, error);
+ return_val_if_nok (error, NULL);
} else if (strcmp ("MonoField", klass->name) == 0) {
MonoReflectionField *rfield = (MonoReflectionField*)obj;
- cinfo = mono_custom_attrs_from_field (rfield->field->parent, rfield->field);
+ cinfo = mono_custom_attrs_from_field_checked (rfield->field->parent, rfield->field, error);
+ return_val_if_nok (error, NULL);
} else if ((strcmp ("MonoMethod", klass->name) == 0) || (strcmp ("MonoCMethod", klass->name) == 0)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
- cinfo = mono_custom_attrs_from_method (rmethod->method);
+ cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
+ return_val_if_nok (error, NULL);
} else if ((strcmp ("MonoGenericMethod", klass->name) == 0) || (strcmp ("MonoGenericCMethod", klass->name) == 0)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)obj;
- cinfo = mono_custom_attrs_from_method (rmethod->method);
+ cinfo = mono_custom_attrs_from_method_checked (rmethod->method, error);
+ return_val_if_nok (error, NULL);
} else if (strcmp ("ParameterInfo", klass->name) == 0 || strcmp ("MonoParameterInfo", klass->name) == 0) {
MonoReflectionParameter *param = (MonoReflectionParameter*)obj;
MonoClass *member_class = mono_object_class (param->MemberImpl);
if (mono_class_is_reflection_method_or_constructor (member_class)) {
MonoReflectionMethod *rmethod = (MonoReflectionMethod*)param->MemberImpl;
- cinfo = mono_custom_attrs_from_param (rmethod->method, param->PositionImpl + 1);
+ cinfo = mono_custom_attrs_from_param_checked (rmethod->method, param->PositionImpl + 1, error);
+ return_val_if_nok (error, NULL);
} else if (is_sr_mono_property (member_class)) {
MonoReflectionProperty *prop = (MonoReflectionProperty *)param->MemberImpl;
MonoMethod *method;
method = prop->property->set;
g_assert (method);
- cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+ cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+ return_val_if_nok (error, NULL);
}
#ifndef DISABLE_REFLECTION_EMIT
else if (is_sre_method_on_tb_inst (member_class)) {/*XXX This is a workaround for Compiler Context*/
MonoMethod *method = mono_reflection_method_on_tb_inst_get_handle ((MonoReflectionMethodOnTypeBuilderInst*)param->MemberImpl, error);
return_val_if_nok (error, NULL);
- cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+ cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+ return_val_if_nok (error, NULL);
} else if (is_sre_ctor_on_tb_inst (member_class)) { /*XX This is a workaround for Compiler Context*/
MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)param->MemberImpl;
MonoMethod *method = NULL;
else
g_error ("mono_reflection_get_custom_attrs_info:: can't handle a CTBI with base_method of type %s", mono_type_get_full_name (member_class));
- cinfo = mono_custom_attrs_from_param (method, param->PositionImpl + 1);
+ cinfo = mono_custom_attrs_from_param_checked (method, param->PositionImpl + 1, error);
+ return_val_if_nok (error, NULL);
}
#endif
else {
if (!cinfo->cached)
mono_custom_attrs_free (cinfo);
} else {
- /* FIXME add MonoError to mono_reflection_get_custom_attrs_info */
- if (mono_loader_get_last_error ()) {
- mono_error_set_from_loader_error (error);
- return NULL;
- }
+ mono_loader_assert_no_error ();
result = mono_array_new_cached (mono_domain_get (), mono_defaults.attribute_class, 0);
}
dgclass->field_generic_types = mono_image_set_new0 (gclass->owner, MonoType*, dgclass->count_fields);
for (i = 0; i < dgclass->count_fields; i++) {
+ MonoError error;
MonoObject *obj = (MonoObject *)mono_array_get (fields, gpointer, i);
MonoClassField *field, *inflated_field = NULL;
dgclass->fields [i] = *field;
dgclass->fields [i].parent = klass;
- dgclass->fields [i].type = mono_class_inflate_generic_type (
- field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass));
+ dgclass->fields [i].type = mono_class_inflate_generic_type_checked (
+ field->type, mono_generic_class_get_context ((MonoGenericClass *) dgclass), &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
dgclass->field_generic_types [i] = field->type;
MONO_GC_REGISTER_ROOT_IF_MOVING (dgclass->field_objects [i], MONO_ROOT_SOURCE_REFLECTION, "dynamic generic class field object");
dgclass->field_objects [i] = obj;
for (i = 0; i < gklass->interface_count; ++i) {
MonoError error;
- MonoType *iface_type = mono_class_inflate_generic_type (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass));
+ MonoType *iface_type = mono_class_inflate_generic_type_checked (&gklass->interfaces [i]->byval_arg, mono_class_get_context (klass), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
klass->interfaces [i] = mono_class_from_mono_type (iface_type);
mono_metadata_free_type (iface_type);
klass->fields = image_g_new0 (klass->image, MonoClassField, klass->field.count);
for (i = 0; i < klass->field.count; i++) {
+ MonoError error;
klass->fields [i] = gklass->fields [i];
klass->fields [i].parent = klass;
- klass->fields [i].type = mono_class_inflate_generic_type (gklass->fields [i].type, mono_class_get_context (klass));
+ klass->fields [i].type = mono_class_inflate_generic_type_checked (gklass->fields [i].type, mono_class_get_context (klass), &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
}
}
gpointer result = NULL;
if (strcmp (obj->vtable->klass->name, "String") == 0) {
- result = mono_string_intern ((MonoString*)obj);
+ result = mono_string_intern_checked ((MonoString*)obj, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
*handle_class = mono_defaults.string_class;
g_assert (result);
} else if (strcmp (obj->vtable->klass->name, "MonoType") == 0) {
mono_raise_exception (mono_class_get_exception_for_failure (mc));
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type (type, context);
+ MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
result = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
} else {
ensure_complete_type (field->parent);
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type (&field->parent->byval_arg, context);
+ MonoType *inflated = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
MonoClass *klass = mono_class_from_mono_type (inflated);
MonoClassField *inflated_field;
gpointer iter = NULL;
if (fb->handle && fb->handle->parent->generic_container) {
MonoClass *klass = fb->handle->parent;
- MonoType *type = mono_class_inflate_generic_type (&klass->byval_arg, context);
+ MonoType *type = mono_class_inflate_generic_type_checked (&klass->byval_arg, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
MonoClass *inflated = mono_class_from_mono_type (type);
result = mono_class_get_field_from_name (inflated, mono_field_get_name (fb->handle));
*handle_class = mono_defaults.methodhandle_class;
} else if (strcmp (obj->vtable->klass->name, "GenericTypeParameterBuilder") == 0) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
- type = mono_class_inflate_generic_type (type, context);
+ type = mono_class_inflate_generic_type_checked (type, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
result = mono_class_from_mono_type (type);
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
mono_metadata_free_type (type);
} else if (strcmp (obj->vtable->klass->name, "MonoGenericClass") == 0) {
MonoType *type = mono_reflection_type_get_handle ((MonoReflectionType*)obj);
- type = mono_class_inflate_generic_type (type, context);
+ type = mono_class_inflate_generic_type_checked (type, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
result = mono_class_from_mono_type (type);
*handle_class = mono_defaults.typehandle_class;
g_assert (result);
else
g_error ("resolve_object:: can't handle a FTBI with base_method of type %s", mono_type_get_full_name (mono_object_class (f->fb)));
- type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)f->inst), context);
+ type = mono_class_inflate_generic_type_checked (mono_reflection_type_get_handle ((MonoReflectionType*)f->inst), context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
inflated = mono_class_from_mono_type (type);
result = field = mono_class_get_field_from_name (inflated, mono_field_get_name (field));
*handle_class = mono_defaults.fieldhandle_class;
} else if (strcmp (obj->vtable->klass->name, "ConstructorOnTypeBuilderInst") == 0) {
MonoReflectionCtorOnTypeBuilderInst *c = (MonoReflectionCtorOnTypeBuilderInst*)obj;
- MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)c->inst), context);
+ MonoType *type = mono_class_inflate_generic_type_checked (mono_reflection_type_get_handle ((MonoReflectionType*)c->inst), context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
MonoClass *inflated_klass = mono_class_from_mono_type (type);
MonoMethod *method;
mono_error_assert_ok (&error);
}
} else {
- MonoType *type = mono_class_inflate_generic_type (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context);
+ MonoType *type = mono_class_inflate_generic_type_checked (mono_reflection_type_get_handle ((MonoReflectionType*)m->inst), context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
MonoClass *inflated_klass = mono_class_from_mono_type (type);
MonoMethod *method;
MonoType *type = mono_reflection_type_get_handle (ref_type);
if (context) {
- MonoType *inflated = mono_class_inflate_generic_type (type, context);
+ MonoType *inflated = mono_class_inflate_generic_type_checked (type, context, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
+
result = mono_class_from_mono_type (inflated);
mono_metadata_free_type (inflated);
} else {
MONO_API MonoCustomAttrInfo* mono_reflection_get_custom_attrs_info (MonoObject *obj);
MONO_RT_EXTERNAL_ONLY
MONO_API MonoArray* mono_custom_attrs_construct (MonoCustomAttrInfo *cinfo);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_index (MonoImage *image, uint32_t idx);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_method (MonoMethod *method);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_class (MonoClass *klass);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_assembly (MonoAssembly *assembly);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_property (MonoClass *klass, MonoProperty *property);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_event (MonoClass *klass, MonoEvent *event);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_field (MonoClass *klass, MonoClassField *field);
+MONO_RT_EXTERNAL_ONLY
MONO_API MonoCustomAttrInfo* mono_custom_attrs_from_param (MonoMethod *method, uint32_t param);
MONO_API mono_bool mono_custom_attrs_has_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass);
MONO_API MonoObject* mono_custom_attrs_get_attr (MonoCustomAttrInfo *ainfo, MonoClass *attr_klass);
msg = mono_method_call_message_new (method, params, NULL, NULL, NULL);
- res = mono_remoting_invoke ((MonoObject *)this_obj->rp, msg, &exc, &out_args);
+ res = mono_remoting_invoke ((MonoObject *)this_obj->rp, msg, &exc, &out_args, &error);
+ mono_error_raise_exception (&error); /* FIXME don't raise here */
if (exc)
mono_raise_exception ((MonoException *)exc);
info->d.alloc.gc_name = "sgen";
info->d.alloc.alloc_type = atype;
- res = mono_mb_create (mb, csig, 8, info);
- mono_mb_free (mb);
#ifndef DISABLE_JIT
- mono_method_get_header (res)->init_locals = FALSE;
+ mb->init_locals = FALSE;
#endif
+ res = mono_mb_create (mb, csig, 8, info);
+ mono_mb_free (mb);
+
return res;
}
void
sgen_client_scan_thread_data (void *start_nursery, void *end_nursery, gboolean precise, ScanCopyContext ctx)
{
- SgenThreadInfo *info;
-
scan_area_arg_start = start_nursery;
scan_area_arg_end = end_nursery;
}
}
}
- } END_FOREACH_THREAD
+ } FOREACH_THREAD_END
}
/*
{
SgenThreadInfo *cur_thread = mono_thread_info_current ();
kern_return_t ret;
- SgenThreadInfo *info;
int count = 0;
cur_thread->client_info.suspend_done = TRUE;
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (info == cur_thread || sgen_thread_pool_is_thread_pool_thread (mono_thread_info_get_tid (info)))
continue;
continue;
}
count ++;
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
return count;
}
sgen_thread_handshake (BOOL suspend)
{
int count, result;
- SgenThreadInfo *info;
int signum = suspend ? suspend_signal_num : restart_signal_num;
MonoNativeThreadId me = mono_native_thread_id_get ();
count = 0;
mono_thread_info_current ()->client_info.suspend_done = TRUE;
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (mono_native_thread_id_equals (mono_thread_info_get_tid (info), me)) {
continue;
}
} else {
info->client_info.skip = 1;
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
sgen_wait_for_suspend_ack (count);
int
sgen_thread_handshake (BOOL suspend)
{
- SgenThreadInfo *info;
SgenThreadInfo *current = mono_thread_info_current ();
int count = 0;
current->client_info.suspend_done = TRUE;
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (info == current)
continue;
info->client_info.suspend_done = FALSE;
continue;
}
++count;
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
return count;
}
static int
restart_threads_until_none_in_managed_allocator (void)
{
- SgenThreadInfo *info;
int num_threads_died = 0;
int sleep_duration = -1;
int restart_count = 0, restarted_count = 0;
/* restart all threads that stopped in the
allocator */
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
gboolean result;
if (info->client_info.skip || info->client_info.gc_disabled || info->client_info.suspend_done)
continue;
info->client_info.stopped_domain = NULL;
info->client_info.suspend_done = TRUE;
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
/* if no threads were restarted, we're done */
if (restart_count == 0)
break;
} else {
info->client_info.skip = 1;
}
- } END_FOREACH_THREAD
+ } FOREACH_THREAD_END
/* some threads might have died */
num_threads_died += restart_count - restarted_count;
/* wait for the threads to signal their suspension
void
sgen_client_restart_world (int generation, GGTimingInfo *timing)
{
- SgenThreadInfo *info;
TV_DECLARE (end_sw);
TV_DECLARE (start_handshake);
TV_DECLARE (end_bridge);
#else
memset (&info->client_info.regs, 0, sizeof (info->client_info.regs));
#endif
- } END_FOREACH_THREAD
+ } FOREACH_THREAD_END
TV_GETTIME (start_handshake);
sgen_unified_suspend_stop_world (void)
{
int restart_counter;
- SgenThreadInfo *info;
int sleep_duration = -1;
mono_threads_begin_global_suspend ();
THREADS_STW_DEBUG ("[GC-STW-BEGIN] *** BEGIN SUSPEND *** \n");
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
info->client_info.skip = FALSE;
info->client_info.suspend_done = FALSE;
if (sgen_is_thread_in_current_stw (info)) {
} else {
THREADS_STW_DEBUG ("[GC-STW-BEGIN-SUSPEND] IGNORE thread %p skip %d\n", mono_thread_info_get_tid (info), info->client_info.skip);
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
mono_thread_info_current ()->client_info.suspend_done = TRUE;
mono_threads_wait_pending_operations ();
for (;;) {
restart_counter = 0;
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (info->client_info.suspend_done || !sgen_is_thread_in_current_stw (info)) {
THREADS_STW_DEBUG ("[GC-STW-RESTART] IGNORE thread %p not been processed done %d current %d\n", mono_thread_info_get_tid (info), info->client_info.suspend_done, !sgen_is_thread_in_current_stw (info));
continue;
g_assert (!info->client_info.in_critical_region);
info->client_info.suspend_done = TRUE;
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
if (restart_counter == 0)
break;
sleep_duration += 10;
}
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (sgen_is_thread_in_current_stw (info) && mono_thread_info_is_running (info)) {
gboolean res = mono_thread_info_begin_suspend (info);
THREADS_STW_DEBUG ("[GC-STW-RESTART] SUSPEND thread %p skip %d\n", mono_thread_info_get_tid (info), res);
if (!res)
info->client_info.skip = TRUE;
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
mono_threads_wait_pending_operations ();
}
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (sgen_is_thread_in_current_stw (info)) {
THREADS_STW_DEBUG ("[GC-STW-SUSPEND-END] thread %p is suspended\n", mono_thread_info_get_tid (info));
g_assert (info->client_info.suspend_done);
} else {
g_assert (!info->client_info.suspend_done || info == mono_thread_info_current ());
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
}
static void
sgen_unified_suspend_restart_world (void)
{
- SgenThreadInfo *info;
-
THREADS_STW_DEBUG ("[GC-STW-END] *** BEGIN RESUME ***\n");
- FOREACH_THREAD_SAFE (info) {
+ FOREACH_THREAD (info) {
if (sgen_is_thread_in_current_stw (info)) {
g_assert (mono_thread_info_begin_resume (info));
THREADS_STW_DEBUG ("[GC-STW-RESUME-WORLD] RESUME thread %p\n", mono_thread_info_get_tid (info));
} else {
THREADS_STW_DEBUG ("[GC-STW-RESUME-WORLD] IGNORE thread %p\n", mono_thread_info_get_tid (info));
}
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_END
mono_threads_wait_pending_operations ();
mono_threads_end_global_suspend ();
case AddressFamily_Cluster:
case AddressFamily_Ieee12844:
case AddressFamily_NetworkDesigners:
- g_warning("System.Net.Sockets.AddressFamily has unsupported value 0x%x", mono_family);
+ g_warning ("System.Net.Sockets.AddressFamily has unsupported value 0x%x", mono_family);
return -1;
case AddressFamily_Unspecified:
return AF_UNSPEC;
return AddressFamily_Irda;
#endif
default:
- g_warning("unknown address family 0x%x", af_family);
+ g_warning ("unknown address family 0x%x", af_family);
return AddressFamily_Unknown;
}
}
case ProtocolType_SpxII:
case ProtocolType_Unknown:
/* These protocols arent */
- g_warning("System.Net.Sockets.ProtocolType has unsupported value 0x%x", mono_proto);
+ g_warning ("System.Net.Sockets.ProtocolType has unsupported value 0x%x", mono_proto);
return -1;
default:
return -1;
* -2 on non-fatal error (ie, must ignore)
*/
static gint32
-convert_sockopt_level_and_name(MonoSocketOptionLevel mono_level, MonoSocketOptionName mono_name, int *system_level, int *system_name)
+convert_sockopt_level_and_name (MonoSocketOptionLevel mono_level, MonoSocketOptionName mono_name, int *system_level, int *system_name)
{
switch (mono_level) {
case SocketOptionLevel_Socket:
*system_level = SOL_SOCKET;
- switch(mono_name) {
+ switch (mono_name) {
case SocketOptionName_DontLinger:
/* This is SO_LINGER, because the setsockopt
* internal call maps DontLinger to SO_LINGER
break;
#endif
default:
- g_warning("System.Net.Sockets.SocketOptionName 0x%x is not supported at Socket level", mono_name);
- return(-1);
+ g_warning ("System.Net.Sockets.SocketOptionName 0x%x is not supported at Socket level", mono_name);
+ return -1;
}
break;
case SocketOptionLevel_IP:
*system_level = mono_networking_get_ip_protocol ();
- switch(mono_name) {
+ switch (mono_name) {
case SocketOptionName_IPOptions:
*system_name = IP_OPTIONS;
break;
break;
#else
/* If the flag is not available on this system, we can ignore this error */
- return (-2);
+ return -2;
#endif /* HAVE_IP_DONTFRAGMENT */
case SocketOptionName_AddSourceMembership:
case SocketOptionName_DropSourceMembership:
* through
*/
default:
- g_warning("System.Net.Sockets.SocketOptionName 0x%x is not supported at IP level", mono_name);
- return(-1);
+ g_warning ("System.Net.Sockets.SocketOptionName 0x%x is not supported at IP level", mono_name);
+ return -1;
}
break;
case SocketOptionLevel_IPv6:
*system_level = mono_networking_get_ipv6_protocol ();
- switch(mono_name) {
+ switch (mono_name) {
case SocketOptionName_IpTimeToLive:
case SocketOptionName_HopLimit:
*system_name = IPV6_UNICAST_HOPS;
* through
*/
default:
- g_warning("System.Net.Sockets.SocketOptionName 0x%x is not supported at IPv6 level", mono_name);
- return(-1);
+ g_warning ("System.Net.Sockets.SocketOptionName 0x%x is not supported at IPv6 level", mono_name);
+ return -1;
}
-
break; /* SocketOptionLevel_IPv6 */
case SocketOptionLevel_Tcp:
*system_level = mono_networking_get_tcp_protocol ();
- switch(mono_name) {
+ switch (mono_name) {
case SocketOptionName_NoDelay:
*system_name = TCP_NODELAY;
break;
case SocketOptionName_Expedited:
#endif
default:
- g_warning("System.Net.Sockets.SocketOptionName 0x%x is not supported at TCP level", mono_name);
- return(-1);
+ g_warning ("System.Net.Sockets.SocketOptionName 0x%x is not supported at TCP level", mono_name);
+ return -1;
}
break;
case SocketOptionLevel_Udp:
- g_warning("System.Net.Sockets.SocketOptionLevel has unsupported value 0x%x", mono_level);
+ g_warning ("System.Net.Sockets.SocketOptionLevel has unsupported value 0x%x", mono_level);
switch(mono_name) {
case SocketOptionName_NoChecksum:
case SocketOptionName_ChecksumCoverage:
default:
- g_warning("System.Net.Sockets.SocketOptionName 0x%x is not supported at UDP level", mono_name);
- return(-1);
+ g_warning ("System.Net.Sockets.SocketOptionName 0x%x is not supported at UDP level", mono_name);
+ return -1;
}
- return(-1);
+ return -1;
break;
default:
- g_warning("System.Net.Sockets.SocketOptionLevel has unknown value 0x%x", mono_level);
- return(-1);
+ g_warning ("System.Net.Sockets.SocketOptionLevel has unknown value 0x%x", mono_level);
+ return -1;
}
- return(0);
+ return 0;
}
static MonoImage*
}
static gint32
-get_family_hint (void)
+get_family_hint (MonoError *error)
{
MonoDomain *domain = mono_domain_get ();
+ mono_error_init (error);
+
if (!domain->inet_family_hint) {
MonoImage *socket_assembly;
MonoClass *socket_class;
vtable = mono_class_vtable (mono_domain_get (), socket_class);
g_assert (vtable);
- MonoError error;
- mono_runtime_class_init_full (vtable, &error);
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ mono_runtime_class_init_full (vtable, error);
+ return_val_if_nok (error, -1);
mono_field_static_get_value (vtable, ipv4_field, &ipv4_enabled);
mono_field_static_get_value (vtable, ipv6_field, &ipv6_enabled);
}
gpointer
-ves_icall_System_Net_Sockets_Socket_Socket_internal (MonoObject *this_obj, gint32 family, gint32 type, gint32 proto, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Socket_internal (MonoObject *this_obj, gint32 family, gint32 type, gint32 proto, gint32 *werror)
{
SOCKET sock;
gint32 sock_family;
gint32 sock_proto;
gint32 sock_type;
- *error = 0;
+ *werror = 0;
sock_family = convert_family ((MonoAddressFamily)family);
- if(sock_family==-1) {
- *error = WSAEAFNOSUPPORT;
- return(NULL);
+ if (sock_family == -1) {
+ *werror = WSAEAFNOSUPPORT;
+ return NULL;
}
sock_proto = convert_proto ((MonoProtocolType)proto);
- if(sock_proto==-1) {
- *error = WSAEPROTONOSUPPORT;
- return(NULL);
+ if (sock_proto == -1) {
+ *werror = WSAEPROTONOSUPPORT;
+ return NULL;
}
sock_type = convert_type ((MonoSocketType)type);
- if(sock_type==-1) {
- *error = WSAESOCKTNOSUPPORT;
- return(NULL);
+ if (sock_type == -1) {
+ *werror = WSAESOCKTNOSUPPORT;
+ return NULL;
}
sock = _wapi_socket (sock_family, sock_type, sock_proto,
NULL, 0, WSA_FLAG_OVERLAPPED);
- if(sock==INVALID_SOCKET) {
- *error = WSAGetLastError ();
- return(NULL);
+ if (sock == INVALID_SOCKET) {
+ *werror = WSAGetLastError ();
+ return NULL;
}
- return(GUINT_TO_POINTER (sock));
+ return GUINT_TO_POINTER (sock);
}
/* FIXME: the SOCKET parameter (here and in other functions in this
* file) is really an IntPtr which needs to be converted to a guint32.
*/
void
-ves_icall_System_Net_Sockets_Socket_Close_internal (SOCKET sock, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Close_internal (SOCKET sock, gint32 *werror)
{
LOGDEBUG (g_message ("%s: closing 0x%x", __func__, sock));
- *error = 0;
+ *werror = 0;
/* Clear any pending work item from this socket if the underlying
* polling system does not notify when the socket is closed */
mono_threadpool_ms_io_remove_socket (GPOINTER_TO_INT (sock));
MONO_PREPARE_BLOCKING;
- closesocket(sock);
+ closesocket (sock);
MONO_FINISH_BLOCKING;
}
gint32
-ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal(void)
+ves_icall_System_Net_Sockets_SocketException_WSAGetLastError_internal (void)
{
- LOGDEBUG (g_message("%s: returning %d", __func__, WSAGetLastError()));
+ LOGDEBUG (g_message("%s: returning %d", __func__, WSAGetLastError ()));
- return(WSAGetLastError());
+ return WSAGetLastError ();
}
gint32
-ves_icall_System_Net_Sockets_Socket_Available_internal(SOCKET sock, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Available_internal (SOCKET sock, gint32 *werror)
{
int ret;
int amount;
- *error = 0;
+ *werror = 0;
/* FIXME: this might require amount to be unsigned long. */
- ret=ioctlsocket(sock, FIONREAD, &amount);
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- return(0);
+ ret = ioctlsocket (sock, FIONREAD, &amount);
+ if (ret == SOCKET_ERROR) {
+ *werror = WSAGetLastError ();
+ return 0;
}
- return(amount);
+ return amount;
}
void
-ves_icall_System_Net_Sockets_Socket_Blocking_internal(SOCKET sock, gboolean block, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Blocking_internal (SOCKET sock, gboolean block, gint32 *werror)
{
int ret;
- *error = 0;
+ *werror = 0;
/*
* block == TRUE/FALSE means we will block/not block.
*/
block = !block;
- ret = ioctlsocket (sock, FIONBIO, (gulong *) &block);
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- }
+ ret = ioctlsocket (sock, FIONBIO, (gulong *)&block);
+ if (ret == SOCKET_ERROR)
+ *werror = WSAGetLastError ();
}
gpointer
-ves_icall_System_Net_Sockets_Socket_Accept_internal (SOCKET sock, gint32 *error, gboolean blocking)
+ves_icall_System_Net_Sockets_Socket_Accept_internal (SOCKET sock, gint32 *werror, gboolean blocking)
{
gboolean interrupted;
SOCKET newsock;
- *error = 0;
+ *werror = 0;
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return NULL;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return NULL;
}
- if(newsock==INVALID_SOCKET) {
- *error = WSAGetLastError ();
- return(NULL);
+ if (newsock == INVALID_SOCKET) {
+ *werror = WSAGetLastError ();
+ return NULL;
}
- return(GUINT_TO_POINTER (newsock));
+ return GUINT_TO_POINTER (newsock);
}
void
-ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock, guint32 backlog, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Listen_internal(SOCKET sock, guint32 backlog, gint32 *werror)
{
int ret;
- *error = 0;
+ *werror = 0;
MONO_PREPARE_BLOCKING;
MONO_FINISH_BLOCKING;
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- }
+ if (ret == SOCKET_ERROR)
+ *werror = WSAGetLastError ();
}
// Check whether it's ::ffff::0:0.
}
static MonoObject*
-create_object_from_sockaddr(struct sockaddr *saddr, int sa_size, gint32 *error)
+create_object_from_sockaddr (struct sockaddr *saddr, int sa_size, gint32 *werror, MonoError *error)
{
- MonoError merror;
MonoDomain *domain = mono_domain_get ();
MonoObject *sockaddr_obj;
MonoArray *data;
MonoAddressFamily family;
+ mono_error_init (error);
+
/* Build a System.Net.SocketAddress object instance */
- if (!domain->sockaddr_class) {
+ if (!domain->sockaddr_class)
domain->sockaddr_class = mono_class_load_from_name (get_socket_assembly (), "System.Net", "SocketAddress");
- }
- sockaddr_obj=mono_object_new_checked(domain, domain->sockaddr_class, &merror);
- mono_error_raise_exception (&merror); /* FIXME don't raise here */
+ sockaddr_obj = mono_object_new_checked (domain, domain->sockaddr_class, error);
+ return_val_if_nok (error, NULL);
/* Locate the SocketAddress data buffer in the object */
if (!domain->sockaddr_data_field) {
- domain->sockaddr_data_field=mono_class_get_field_from_name (domain->sockaddr_class, "data");
+ domain->sockaddr_data_field = mono_class_get_field_from_name (domain->sockaddr_class, "data");
g_assert (domain->sockaddr_data_field);
}
* the length of the entire sockaddr_in/in6, including
* sizeof (unsigned short) of the family */
/* We can't really avoid the +2 as all code below depends on this size - INCLUDING unix domain sockets.*/
- data=mono_array_new_cached(domain, mono_get_byte_class (), sa_size+2);
+ data = mono_array_new_cached (domain, mono_get_byte_class (), sa_size + 2);
/* The data buffer is laid out as follows:
* bytes 0 and 1 are the address family
* the rest is the address info
*/
- family=convert_to_mono_family(saddr->sa_family);
- if(family==AddressFamily_Unknown) {
- *error = WSAEAFNOSUPPORT;
- return(NULL);
+ family = convert_to_mono_family (saddr->sa_family);
+ if (family == AddressFamily_Unknown) {
+ *werror = WSAEAFNOSUPPORT;
+ return NULL;
}
- mono_array_set(data, guint8, 0, family & 0x0FF);
- mono_array_set(data, guint8, 1, (family >> 8) & 0x0FF);
+ mono_array_set (data, guint8, 0, family & 0x0FF);
+ mono_array_set (data, guint8, 1, (family >> 8) & 0x0FF);
- if(saddr->sa_family==AF_INET) {
- struct sockaddr_in *sa_in=(struct sockaddr_in *)saddr;
- guint16 port=ntohs(sa_in->sin_port);
- guint32 address=ntohl(sa_in->sin_addr.s_addr);
+ if (saddr->sa_family == AF_INET) {
+ struct sockaddr_in *sa_in = (struct sockaddr_in *)saddr;
+ guint16 port = ntohs (sa_in->sin_port);
+ guint32 address = ntohl (sa_in->sin_addr.s_addr);
- if(sa_size<8) {
- mono_raise_exception((MonoException *)mono_exception_from_name(mono_get_corlib (), "System", "SystemException"));
+ if (sa_size < 8) {
+ mono_error_set_exception_instance (error, mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ return NULL;
}
- mono_array_set(data, guint8, 2, (port>>8) & 0xff);
- mono_array_set(data, guint8, 3, (port) & 0xff);
- mono_array_set(data, guint8, 4, (address>>24) & 0xff);
- mono_array_set(data, guint8, 5, (address>>16) & 0xff);
- mono_array_set(data, guint8, 6, (address>>8) & 0xff);
- mono_array_set(data, guint8, 7, (address) & 0xff);
+ mono_array_set (data, guint8, 2, (port>>8) & 0xff);
+ mono_array_set (data, guint8, 3, (port) & 0xff);
+ mono_array_set (data, guint8, 4, (address>>24) & 0xff);
+ mono_array_set (data, guint8, 5, (address>>16) & 0xff);
+ mono_array_set (data, guint8, 6, (address>>8) & 0xff);
+ mono_array_set (data, guint8, 7, (address) & 0xff);
mono_field_set_value (sockaddr_obj, domain->sockaddr_data_field, data);
- return(sockaddr_obj);
+ return sockaddr_obj;
} else if (saddr->sa_family == AF_INET6) {
- struct sockaddr_in6 *sa_in=(struct sockaddr_in6 *)saddr;
+ struct sockaddr_in6 *sa_in = (struct sockaddr_in6 *)saddr;
int i;
- guint16 port=ntohs(sa_in->sin6_port);
+ guint16 port = ntohs (sa_in->sin6_port);
- if(sa_size<28) {
- mono_raise_exception((MonoException *)mono_exception_from_name(mono_get_corlib (), "System", "SystemException"));
+ if (sa_size < 28) {
+ mono_error_set_exception_instance (error, mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ return NULL;
}
- mono_array_set(data, guint8, 2, (port>>8) & 0xff);
- mono_array_set(data, guint8, 3, (port) & 0xff);
+ mono_array_set (data, guint8, 2, (port>>8) & 0xff);
+ mono_array_set (data, guint8, 3, (port) & 0xff);
if (is_ipv4_mapped_any (&sa_in->sin6_addr)) {
// Map ::ffff:0:0 to :: (bug #5502)
- for(i=0; i<16; i++) {
- mono_array_set(data, guint8, 8+i, 0);
- }
+ for (i = 0; i < 16; i++)
+ mono_array_set (data, guint8, 8 + i, 0);
} else {
- for(i=0; i<16; i++) {
- mono_array_set(data, guint8, 8+i,
- sa_in->sin6_addr.s6_addr[i]);
+ for (i = 0; i < 16; i++) {
+ mono_array_set (data, guint8, 8 + i,
+ sa_in->sin6_addr.s6_addr [i]);
}
}
- mono_array_set(data, guint8, 24, sa_in->sin6_scope_id & 0xff);
- mono_array_set(data, guint8, 25,
- (sa_in->sin6_scope_id >> 8) & 0xff);
- mono_array_set(data, guint8, 26,
- (sa_in->sin6_scope_id >> 16) & 0xff);
- mono_array_set(data, guint8, 27,
- (sa_in->sin6_scope_id >> 24) & 0xff);
+ mono_array_set (data, guint8, 24, sa_in->sin6_scope_id & 0xff);
+ mono_array_set (data, guint8, 25,
+ (sa_in->sin6_scope_id >> 8) & 0xff);
+ mono_array_set (data, guint8, 26,
+ (sa_in->sin6_scope_id >> 16) & 0xff);
+ mono_array_set (data, guint8, 27,
+ (sa_in->sin6_scope_id >> 24) & 0xff);
mono_field_set_value (sockaddr_obj, domain->sockaddr_data_field, data);
- return(sockaddr_obj);
+ return sockaddr_obj;
}
#ifdef HAVE_SYS_UN_H
else if (saddr->sa_family == AF_UNIX) {
int i;
- for (i = 0; i < sa_size; i++) {
- mono_array_set (data, guint8, i+2, saddr->sa_data[i]);
- }
+ for (i = 0; i < sa_size; i++)
+ mono_array_set (data, guint8, i + 2, saddr->sa_data [i]);
mono_field_set_value (sockaddr_obj, domain->sockaddr_data_field, data);
}
#endif
else {
- *error = WSAEAFNOSUPPORT;
- return(NULL);
+ *werror = WSAEAFNOSUPPORT;
+ return NULL;
}
}
}
MonoObject*
-ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal (SOCKET sock, gint32 af, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal (SOCKET sock, gint32 af, gint32 *werror)
{
gchar *sa;
socklen_t salen;
int ret;
MonoObject *result;
+ MonoError error;
- *error = 0;
+ *werror = 0;
salen = get_sockaddr_size (convert_family ((MonoAddressFamily)af));
if (salen == 0) {
- *error = WSAEAFNOSUPPORT;
+ *werror = WSAEAFNOSUPPORT;
return NULL;
}
sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
MONO_FINISH_BLOCKING;
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
+ if (ret == SOCKET_ERROR) {
+ *werror = WSAGetLastError ();
if (salen > 128)
g_free (sa);
- return(NULL);
+ return NULL;
}
- LOGDEBUG (g_message("%s: bound to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)&sa)->sin_addr), ntohs(((struct sockaddr_in *)&sa)->sin_port)));
+ LOGDEBUG (g_message("%s: bound to %s port %d", __func__, inet_ntoa (((struct sockaddr_in *)&sa)->sin_addr), ntohs (((struct sockaddr_in *)&sa)->sin_port)));
- result = create_object_from_sockaddr((struct sockaddr *)sa, salen, error);
+ result = create_object_from_sockaddr ((struct sockaddr *)sa, salen, werror, &error);
if (salen > 128)
g_free (sa);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
return result;
}
MonoObject*
-ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal (SOCKET sock, gint32 af, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal (SOCKET sock, gint32 af, gint32 *werror)
{
gchar *sa;
socklen_t salen;
int ret;
MonoObject *result;
+ MonoError error;
- *error = 0;
+ *werror = 0;
salen = get_sockaddr_size (convert_family ((MonoAddressFamily)af));
if (salen == 0) {
- *error = WSAEAFNOSUPPORT;
+ *werror = WSAEAFNOSUPPORT;
return NULL;
}
sa = (salen <= 128) ? (gchar *)alloca (salen) : (gchar *)g_malloc0 (salen);
MONO_FINISH_BLOCKING;
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
+ if (ret == SOCKET_ERROR) {
+ *werror = WSAGetLastError ();
if (salen > 128)
g_free (sa);
- return(NULL);
+ return NULL;
}
- LOGDEBUG (g_message("%s: connected to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)&sa)->sin_addr), ntohs(((struct sockaddr_in *)&sa)->sin_port)));
+ LOGDEBUG (g_message("%s: connected to %s port %d", __func__, inet_ntoa (((struct sockaddr_in *)&sa)->sin_addr), ntohs (((struct sockaddr_in *)&sa)->sin_port)));
- result = create_object_from_sockaddr((struct sockaddr *)sa, salen, error);
+ result = create_object_from_sockaddr ((struct sockaddr *)sa, salen, werror, &error);
if (salen > 128)
g_free (sa);
+ if (!mono_error_ok (&error))
+ mono_error_set_pending_exception (&error);
return result;
}
static struct sockaddr*
-create_sockaddr_from_object(MonoObject *saddr_obj, socklen_t *sa_size, gint32 *error)
+create_sockaddr_from_object (MonoObject *saddr_obj, socklen_t *sa_size, gint32 *werror, MonoError *error)
{
MonoClassField *field;
MonoArray *data;
gint32 family;
int len;
+ mono_error_init (error);
+
/* Dig the SocketAddress data buffer out of the object */
- field=mono_class_get_field_from_name(saddr_obj->vtable->klass, "data");
- data=*(MonoArray **)(((char *)saddr_obj) + field->offset);
+ field = mono_class_get_field_from_name (saddr_obj->vtable->klass, "data");
+ data = *(MonoArray **)(((char *)saddr_obj) + field->offset);
/* The data buffer is laid out as follows:
* byte 0 is the address family low byte
*/
len = mono_array_length (data);
if (len < 2) {
- mono_raise_exception (mono_exception_from_name(mono_get_corlib (), "System", "SystemException"));
+ mono_error_set_exception_instance (error, mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ return NULL;
}
family = convert_family ((MonoAddressFamily)(mono_array_get (data, guint8, 0) + (mono_array_get (data, guint8, 1) << 8)));
guint32 address;
if (len < 8) {
- mono_raise_exception (mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ mono_error_set_exception_instance (error, mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ return NULL;
}
sa = g_new0 (struct sockaddr_in, 1);
sa->sin_addr.s_addr = htonl (address);
sa->sin_port = htons (port);
- *sa_size = sizeof(struct sockaddr_in);
- return((struct sockaddr *)sa);
+ *sa_size = sizeof (struct sockaddr_in);
+ return (struct sockaddr *)sa;
} else if (family == AF_INET6) {
struct sockaddr_in6 *sa;
int i;
guint32 scopeid;
if (len < 28) {
- mono_raise_exception (mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ mono_error_set_exception_instance (error, mono_exception_from_name (mono_get_corlib (), "System", "SystemException"));
+ return NULL;
}
sa = g_new0 (struct sockaddr_in6, 1);
sa->sin6_port = htons (port);
sa->sin6_scope_id = scopeid;
- for(i=0; i<16; i++) {
- sa->sin6_addr.s6_addr[i] = mono_array_get (data, guint8, 8+i);
- }
+ for (i = 0; i < 16; i++)
+ sa->sin6_addr.s6_addr [i] = mono_array_get (data, guint8, 8 + i);
- *sa_size = sizeof(struct sockaddr_in6);
- return((struct sockaddr *)sa);
+ *sa_size = sizeof (struct sockaddr_in6);
+ return (struct sockaddr *)sa;
}
#ifdef HAVE_SYS_UN_H
else if (family == AF_UNIX) {
/* Need a byte for the '\0' terminator/prefix, and the first
* two bytes hold the SocketAddress family
*/
- if (len - 2 >= sizeof(sock_un->sun_path)) {
- mono_raise_exception (mono_get_exception_index_out_of_range ());
+ if (len - 2 >= sizeof (sock_un->sun_path)) {
+ mono_error_set_exception_instance (error, mono_get_exception_index_out_of_range ());
+ return NULL;
}
sock_un = g_new0 (struct sockaddr_un, 1);
sock_un->sun_family = family;
- for (i = 0; i < len - 2; i++) {
- sock_un->sun_path [i] = mono_array_get (data, guint8,
- i + 2);
- }
+ for (i = 0; i < len - 2; i++)
+ sock_un->sun_path [i] = mono_array_get (data, guint8, i + 2);
*sa_size = len;
-
return (struct sockaddr *)sock_un;
}
#endif
else {
- *error = WSAEAFNOSUPPORT;
- return(0);
+ *werror = WSAEAFNOSUPPORT;
+ return 0;
}
}
void
-ves_icall_System_Net_Sockets_Socket_Bind_internal (SOCKET sock, MonoObject *sockaddr, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Bind_internal (SOCKET sock, MonoObject *sockaddr, gint32 *werror)
{
+ MonoError error;
struct sockaddr *sa;
socklen_t sa_size;
int ret;
- *error = 0;
+ *werror = 0;
- sa=create_sockaddr_from_object(sockaddr, &sa_size, error);
- if (*error != 0) {
+ sa = create_sockaddr_from_object (sockaddr, &sa_size, werror, &error);
+ if (*werror != 0)
+ return;
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
return;
}
- LOGDEBUG (g_message("%s: binding to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), ntohs (((struct sockaddr_in *)sa)->sin_port)));
+ LOGDEBUG (g_message("%s: binding to %s port %d", __func__, inet_ntoa (((struct sockaddr_in *)sa)->sin_addr), ntohs (((struct sockaddr_in *)sa)->sin_port)));
ret = _wapi_bind (sock, sa, sa_size);
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- }
+ if (ret == SOCKET_ERROR)
+ *werror = WSAGetLastError ();
- g_free(sa);
+ g_free (sa);
}
enum {
MonoBoolean
ves_icall_System_Net_Sockets_Socket_Poll_internal (SOCKET sock, gint mode,
- gint timeout, gint32 *error)
+ gint timeout, gint32 *werror)
{
MonoInternalThread *thread = mono_thread_internal_current ();
mono_pollfd *pfds;
gboolean interrupted;
time_t start;
- *error = 0;
+ *werror = 0;
pfds = g_new0 (mono_pollfd, 1);
pfds->fd = GPOINTER_TO_INT (sock);
switch (mode) {
- case SelectModeRead: pfds->events = MONO_POLLIN; break;
- case SelectModeWrite: pfds->events = MONO_POLLOUT; break;
- default: pfds->events = MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL; break;
+ case SelectModeRead:
+ pfds->events = MONO_POLLIN;
+ break;
+ case SelectModeWrite:
+ pfds->events = MONO_POLLOUT;
+ break;
+ default:
+ pfds->events = MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL;
+ break;
}
timeout = (timeout >= 0) ? (timeout / 1000) : -1;
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
g_free (pfds);
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return FALSE;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
g_free (pfds);
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return FALSE;
}
if (ret == -1) {
#ifdef HOST_WIN32
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
#else
- *error = errno_to_WSA (errno, __func__);
+ *werror = errno_to_WSA (errno, __func__);
#endif
g_free (pfds);
return FALSE;
}
void
-ves_icall_System_Net_Sockets_Socket_Connect_internal (SOCKET sock, MonoObject *sockaddr, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Connect_internal (SOCKET sock, MonoObject *sockaddr, gint32 *werror)
{
+ MonoError error;
struct sockaddr *sa;
socklen_t sa_size;
int ret;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
- sa = create_sockaddr_from_object(sockaddr, &sa_size, error);
- if (*error != 0)
+ sa = create_sockaddr_from_object (sockaddr, &sa_size, werror, &error);
+ if (*werror != 0)
+ return;
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
return;
+ }
- LOGDEBUG (g_message("%s: connecting to %s port %d", __func__, inet_ntoa(((struct sockaddr_in *)sa)->sin_addr), ntohs (((struct sockaddr_in *)sa)->sin_port)));
+ LOGDEBUG (g_message("%s: connecting to %s port %d", __func__, inet_ntoa (((struct sockaddr_in *)sa)->sin_addr), ntohs (((struct sockaddr_in *)sa)->sin_port)));
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
if (ret == SOCKET_ERROR)
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
- g_free(sa);
+ g_free (sa);
}
/* These #defines from mswsock.h from wine. Defining them here allows
#endif
void
-ves_icall_System_Net_Sockets_Socket_Disconnect_internal (SOCKET sock, MonoBoolean reuse, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Disconnect_internal (SOCKET sock, MonoBoolean reuse, gint32 *werror)
{
int ret;
glong output_bytes = 0;
LPFN_TRANSMITFILE _wapi_transmitfile = NULL;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
LOGDEBUG (g_message("%s: disconnecting from socket %p (reuse %d)", __func__, sock, reuse));
* pointers to functions in managed objects that still works
* on 64bit platforms.
*/
- ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, (gchar *)&disco_guid, sizeof(GUID),
- (gchar *)&_wapi_disconnectex, sizeof(void *), &output_bytes, NULL, NULL);
+ ret = WSAIoctl (sock, SIO_GET_EXTENSION_FUNCTION_POINTER, (gchar *)&disco_guid, sizeof (GUID),
+ (gchar *)&_wapi_disconnectex, sizeof (void *), &output_bytes, NULL, NULL);
MONO_FINISH_BLOCKING;
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
if (_wapi_disconnectex != NULL) {
if (!_wapi_disconnectex (sock, NULL, TF_REUSE_SOCKET, 0))
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
} else if (_wapi_transmitfile != NULL) {
if (!_wapi_transmitfile (sock, NULL, 0, 0, NULL, NULL, TF_DISCONNECT | TF_REUSE_SOCKET))
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
} else {
- *error = ERROR_NOT_SUPPORTED;
+ *werror = ERROR_NOT_SUPPORTED;
}
MONO_FINISH_BLOCKING;
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted)
- *error = WSAEINTR;
+ *werror = WSAEINTR;
}
gint32
-ves_icall_System_Net_Sockets_Socket_Receive_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Receive_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror)
{
int ret;
guchar *buf;
gint32 alen;
- int recvflags=0;
+ int recvflags = 0;
gboolean interrupted;
MonoInternalThread* curthread G_GNUC_UNUSED = mono_thread_internal_current ();
- *error = 0;
+ *werror = 0;
alen = mono_array_length (buffer);
- if (offset > alen - count) {
- return(0);
- }
+ if (offset > alen - count)
+ return 0;
- buf=mono_array_addr(buffer, guchar, offset);
+ buf = mono_array_addr (buffer, guchar, offset);
recvflags = convert_socketflags (flags);
if (recvflags == -1) {
- *error = WSAEOPNOTSUPP;
- return (0);
+ *werror = WSAEOPNOTSUPP;
+ return 0;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- return(0);
+ if (ret == SOCKET_ERROR) {
+ *werror = WSAGetLastError ();
+ return 0;
}
- return(ret);
+ return ret;
}
gint32
-ves_icall_System_Net_Sockets_Socket_Receive_array_internal (SOCKET sock, MonoArray *buffers, gint32 flags, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Receive_array_internal (SOCKET sock, MonoArray *buffers, gint32 flags, gint32 *werror)
{
int ret, count;
gboolean interrupted;
WSABUF *wsabufs;
DWORD recvflags = 0;
- *error = 0;
+ *werror = 0;
wsabufs = mono_array_addr (buffers, WSABUF, 0);
count = mono_array_length (buffers);
recvflags = convert_socketflags (flags);
if (recvflags == -1) {
- *error = WSAEOPNOTSUPP;
- return(0);
+ *werror = WSAEOPNOTSUPP;
+ return 0;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
if (ret == SOCKET_ERROR) {
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
return 0;
}
}
gint32
-ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject **sockaddr, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_ReceiveFrom_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject **sockaddr, gint32 *werror)
{
+ MonoError error;
int ret;
guchar *buf;
gint32 alen;
- int recvflags=0;
+ int recvflags = 0;
struct sockaddr *sa;
socklen_t sa_size;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
alen = mono_array_length (buffer);
- if (offset > alen - count) {
- return(0);
- }
+ if (offset > alen - count)
+ return 0;
- sa=create_sockaddr_from_object(*sockaddr, &sa_size, error);
- if (*error != 0) {
- return(0);
+ sa = create_sockaddr_from_object (*sockaddr, &sa_size, werror, &error);
+ if (*werror != 0)
+ return 0;
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return 0;
}
- buf=mono_array_addr(buffer, guchar, offset);
+ buf = mono_array_addr (buffer, guchar, offset);
recvflags = convert_socketflags (flags);
if (recvflags == -1) {
- *error = WSAEOPNOTSUPP;
- return (0);
+ *werror = WSAEOPNOTSUPP;
+ return 0;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- g_free(sa);
- *error = WSAEINTR;
+ g_free (sa);
+ *werror = WSAEINTR;
return 0;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- g_free(sa);
- *error = WSAEINTR;
+ g_free (sa);
+ *werror = WSAEINTR;
return 0;
}
- if(ret==SOCKET_ERROR) {
- g_free(sa);
- *error = WSAGetLastError ();
- return(0);
+ if (ret==SOCKET_ERROR) {
+ g_free (sa);
+ *werror = WSAGetLastError ();
+ return 0;
}
/* If we didn't get a socket size, then we're probably a
* connected connection-oriented socket and the stack hasn't
* returned the remote address. All we can do is return null.
*/
- if ( sa_size != 0 )
- *sockaddr=create_object_from_sockaddr(sa, sa_size, error);
- else
- *sockaddr=NULL;
+ if (sa_size) {
+ *sockaddr = create_object_from_sockaddr (sa, sa_size, werror, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ g_free (sa);
+ return 0;
+ }
+ } else {
+ *sockaddr = NULL;
+ }
- g_free(sa);
+ g_free (sa);
- return(ret);
+ return ret;
}
gint32
-ves_icall_System_Net_Sockets_Socket_Send_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Send_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, gint32 *werror)
{
int ret;
guchar *buf;
gint32 alen;
- int sendflags=0;
+ int sendflags = 0;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
alen = mono_array_length (buffer);
- if (offset > alen - count) {
- return(0);
- }
+ if (offset > alen - count)
+ return 0;
LOGDEBUG (g_message("%s: alen: %d", __func__, alen));
- buf=mono_array_addr(buffer, guchar, offset);
+ buf = mono_array_addr (buffer, guchar, offset);
LOGDEBUG (g_message("%s: Sending %d bytes", __func__, count));
sendflags = convert_socketflags (flags);
if (sendflags == -1) {
- *error = WSAEOPNOTSUPP;
- return (0);
+ *werror = WSAEOPNOTSUPP;
+ return 0;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- return(0);
+ if (ret == SOCKET_ERROR) {
+ *werror = WSAGetLastError ();
+ return 0;
}
- return(ret);
+ return ret;
}
gint32
-ves_icall_System_Net_Sockets_Socket_Send_array_internal(SOCKET sock, MonoArray *buffers, gint32 flags, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Send_array_internal (SOCKET sock, MonoArray *buffers, gint32 flags, gint32 *werror)
{
int ret, count;
DWORD sent;
DWORD sendflags = 0;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
wsabufs = mono_array_addr (buffers, WSABUF, 0);
count = mono_array_length (buffers);
sendflags = convert_socketflags (flags);
if (sendflags == -1) {
- *error = WSAEOPNOTSUPP;
- return(0);
+ *werror = WSAEOPNOTSUPP;
+ return 0;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
if (ret == SOCKET_ERROR) {
- *error = WSAGetLastError ();
- return(0);
+ *werror = WSAGetLastError ();
+ return 0;
}
- return(sent);
+ return sent;
}
gint32
-ves_icall_System_Net_Sockets_Socket_SendTo_internal(SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject *sockaddr, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_SendTo_internal (SOCKET sock, MonoArray *buffer, gint32 offset, gint32 count, gint32 flags, MonoObject *sockaddr, gint32 *werror)
{
+ MonoError error;
int ret;
guchar *buf;
gint32 alen;
- int sendflags=0;
+ int sendflags = 0;
struct sockaddr *sa;
socklen_t sa_size;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
alen = mono_array_length (buffer);
if (offset > alen - count) {
- return(0);
+ return 0;
}
- sa=create_sockaddr_from_object(sockaddr, &sa_size, error);
- if(*error != 0) {
- return(0);
+ sa = create_sockaddr_from_object(sockaddr, &sa_size, werror, &error);
+ if (*werror != 0)
+ return 0;
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return 0;
}
- LOGDEBUG (g_message("%s: alen: %d", __func__, alen));
+ LOGDEBUG (g_message ("%s: alen: %d", __func__, alen));
- buf=mono_array_addr(buffer, guchar, offset);
+ buf = mono_array_addr (buffer, guchar, offset);
LOGDEBUG (g_message("%s: Sending %d bytes", __func__, count));
sendflags = convert_socketflags (flags);
if (sendflags == -1) {
g_free (sa);
- *error = WSAEOPNOTSUPP;
- return (0);
+ *werror = WSAEOPNOTSUPP;
+ return 0;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
g_free (sa);
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
g_free (sa);
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return 0;
}
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- }
+ if (ret == SOCKET_ERROR)
+ *werror = WSAGetLastError ();
- g_free(sa);
+ g_free (sa);
- return(ret);
+ return ret;
}
-static SOCKET Socket_to_SOCKET(MonoObject *sockobj)
+static SOCKET
+Socket_to_SOCKET (MonoObject *sockobj)
{
MonoSafeHandle *safe_handle;
MonoClassField *field;
field = mono_class_get_field_from_name (sockobj->vtable->klass, "safe_handle");
- safe_handle = ((MonoSafeHandle*) (*(gpointer *)(((char *)sockobj)+field->offset)));
+ safe_handle = ((MonoSafeHandle *)(*(gpointer *)(((char *)sockobj) + field->offset)));
if (safe_handle == NULL)
return -1;
- return (SOCKET) safe_handle->handle;
+ return (SOCKET)safe_handle->handle;
}
#define POLL_ERRORS (MONO_POLLERR | MONO_POLLHUP | MONO_POLLNVAL)
+
void
-ves_icall_System_Net_Sockets_Socket_Select_internal (MonoArray **sockets, gint32 timeout, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Select_internal (MonoArray **sockets, gint32 timeout, gint32 *werror)
{
- MonoError monoerror;
+ MonoError error;
MonoInternalThread *thread = mono_thread_internal_current ();
MonoObject *obj;
mono_pollfd *pfds;
uintptr_t socks_size;
gboolean interrupted;
- *error = 0;
-
+ *werror = 0;
+
/* *sockets -> READ, null, WRITE, null, ERROR, null */
count = mono_array_length (*sockets);
nfds = count - 3; /* NULL separators */
if (idx >= nfds) {
/* The socket array was bogus */
g_free (pfds);
- *error = WSAEFAULT;
+ *werror = WSAEFAULT;
return;
}
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
g_free (pfds);
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
g_free (pfds);
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
if (ret == -1) {
#ifdef HOST_WIN32
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
#else
- *error = errno_to_WSA (errno, __func__);
+ *werror = errno_to_WSA (errno, __func__);
#endif
g_free (pfds);
return;
return;
}
- sock_arr_class= ((MonoObject *)*sockets)->vtable->klass;
+ sock_arr_class = ((MonoObject *)*sockets)->vtable->klass;
socks_size = ((uintptr_t)ret) + 3; /* space for the NULL delimiters */
- socks = mono_array_new_full_checked (mono_domain_get (), sock_arr_class, &socks_size, NULL, &monoerror);
- mono_error_raise_exception (&monoerror);
+ socks = mono_array_new_full_checked (mono_domain_get (), sock_arr_class, &socks_size, NULL, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ g_free (pfds);
+ return;
+ }
mode = idx = 0;
for (i = 0; i < count && ret > 0; i++) {
g_free (pfds);
}
-static MonoObject* int_to_object (MonoDomain *domain, int val)
+static MonoObject*
+int_to_object (MonoDomain *domain, int val)
{
return mono_value_box (domain, mono_get_int32_class (), &val);
}
-
void
-ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (SOCKET sock, gint32 level, gint32 name, MonoObject **obj_val, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_GetSocketOption_obj_internal (SOCKET sock, gint32 level, gint32 name, MonoObject **obj_val, gint32 *werror)
{
int system_level = 0;
int system_name = 0;
int ret;
int val;
- socklen_t valsize=sizeof(val);
+ socklen_t valsize = sizeof (val);
struct linger linger;
- socklen_t lingersize=sizeof(linger);
+ socklen_t lingersize = sizeof (linger);
int time_ms = 0;
socklen_t time_ms_size = sizeof (time_ms);
#ifdef SO_PEERCRED
# else
struct ucred cred;
# endif
- socklen_t credsize = sizeof(cred);
+ socklen_t credsize = sizeof (cred);
#endif
- MonoError merror;
- MonoDomain *domain=mono_domain_get();
+ MonoError error;
+ MonoDomain *domain = mono_domain_get ();
MonoObject *obj;
MonoClass *obj_class;
MonoClassField *field;
- *error = 0;
+ *werror = 0;
#if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR)
if (level == SocketOptionLevel_Socket && name == SocketOptionName_ExclusiveAddressUse) {
} else
#endif
{
-
ret = convert_sockopt_level_and_name ((MonoSocketOptionLevel)level, (MonoSocketOptionName)name, &system_level, &system_name);
}
- if(ret==-1) {
- *error = WSAENOPROTOOPT;
+ if (ret == -1) {
+ *werror = WSAENOPROTOOPT;
return;
}
if (ret == -2) {
* you cant getsockopt AddMembership or DropMembership (the
* int getsockopt will error, causing an exception)
*/
- switch(name) {
+ switch (name) {
case SocketOptionName_Linger:
case SocketOptionName_DontLinger:
- ret = _wapi_getsockopt(sock, system_level, system_name, &linger, &lingersize);
+ ret = _wapi_getsockopt (sock, system_level, system_name, &linger, &lingersize);
break;
case SocketOptionName_SendTimeout:
case SocketOptionName_ReceiveTimeout:
- ret = _wapi_getsockopt (sock, system_level, system_name, (char *) &time_ms, &time_ms_size);
+ ret = _wapi_getsockopt (sock, system_level, system_name, (char *)&time_ms, &time_ms_size);
break;
#ifdef SO_PEERCRED
MONO_FINISH_BLOCKING;
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
+ if (ret == SOCKET_ERROR) {
+ *werror = WSAGetLastError ();
return;
}
- switch(name) {
+ switch (name) {
case SocketOptionName_Linger:
/* build a System.Net.Sockets.LingerOption */
obj_class = mono_class_load_from_name (get_socket_assembly (),
- "System.Net.Sockets",
- "LingerOption");
- obj=mono_object_new_checked(domain, obj_class, &merror);
- mono_error_raise_exception (&merror); /* FIXME don't raise here */
+ "System.Net.Sockets",
+ "LingerOption");
+ obj = mono_object_new_checked (domain, obj_class, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return;
+ }
/* Locate and set the fields "bool enabled" and "int
* lingerTime"
*/
- field=mono_class_get_field_from_name(obj_class, "enabled");
- *(guint8 *)(((char *)obj)+field->offset)=linger.l_onoff;
+ field = mono_class_get_field_from_name(obj_class, "enabled");
+ *(guint8 *)(((char *)obj)+field->offset) = linger.l_onoff;
- field=mono_class_get_field_from_name(obj_class, "lingerTime");
+ field = mono_class_get_field_from_name(obj_class, "lingerTime");
*(guint32 *)(((char *)obj)+field->offset)=linger.l_linger;
-
break;
-
case SocketOptionName_DontLinger:
/* construct a bool int in val - true if linger is off */
obj = int_to_object (domain, !linger.l_onoff);
break;
-
case SocketOptionName_SendTimeout:
case SocketOptionName_ReceiveTimeout:
obj = int_to_object (domain, time_ms);
break;
#ifdef SO_PEERCRED
- case SocketOptionName_PeerCred:
- {
- /* build a Mono.Posix.PeerCred+PeerCredData if
+ case SocketOptionName_PeerCred: {
+ /*
+ * build a Mono.Posix.PeerCred+PeerCredData if
* possible
*/
static MonoImage *mono_posix_image = NULL;
MonoPeerCredData *cred_data;
if (mono_posix_image == NULL) {
- mono_posix_image=mono_image_loaded ("Mono.Posix");
+ mono_posix_image = mono_image_loaded ("Mono.Posix");
if (!mono_posix_image) {
MonoAssembly *sa = mono_assembly_open ("Mono.Posix.dll", NULL);
if (!sa) {
- *error = WSAENOPROTOOPT;
+ *werror = WSAENOPROTOOPT;
return;
} else {
mono_posix_image = mono_assembly_get_image (sa);
obj_class = mono_class_load_from_name (mono_posix_image,
"Mono.Posix",
"PeerCredData");
- obj = mono_object_new_checked(domain, obj_class, &merror);
- mono_error_raise_exception (&merror); /* FIXME don't raise here */
+ obj = mono_object_new_checked (domain, obj_class, &error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return;
+ }
cred_data = (MonoPeerCredData *)obj;
cred_data->pid = cred.pid;
cred_data->uid = cred.uid;
#endif
obj = int_to_object (domain, val);
}
- *obj_val=obj;
+
+ *obj_val = obj;
}
void
-ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal (SOCKET sock, gint32 level, gint32 name, MonoArray **byte_val, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_GetSocketOption_arr_internal (SOCKET sock, gint32 level, gint32 name, MonoArray **byte_val, gint32 *werror)
{
int system_level = 0;
int system_name = 0;
guchar *buf;
socklen_t valsize;
- *error = 0;
+ *werror = 0;
- ret=convert_sockopt_level_and_name((MonoSocketOptionLevel)level, (MonoSocketOptionName)name, &system_level,
- &system_name);
- if(ret==-1) {
- *error = WSAENOPROTOOPT;
+ ret = convert_sockopt_level_and_name((MonoSocketOptionLevel)level, (MonoSocketOptionName)name, &system_level,
+ &system_name);
+ if (ret == -1) {
+ *werror = WSAENOPROTOOPT;
return;
}
- if(ret==-2)
+ if (ret == -2)
return;
- valsize=mono_array_length(*byte_val);
- buf=mono_array_addr(*byte_val, guchar, 0);
+ valsize = mono_array_length (*byte_val);
+ buf = mono_array_addr (*byte_val, guchar, 0);
MONO_PREPARE_BLOCKING;
MONO_FINISH_BLOCKING;
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- }
+ if (ret == SOCKET_ERROR)
+ *werror = WSAGetLastError ();
}
#if defined(HAVE_STRUCT_IP_MREQN) || defined(HAVE_STRUCT_IP_MREQ)
-static struct in_addr ipaddress_to_struct_in_addr(MonoObject *ipaddr)
+static struct in_addr
+ipaddress_to_struct_in_addr (MonoObject *ipaddr)
{
struct in_addr inaddr;
MonoClassField *field;
- field=mono_class_get_field_from_name(ipaddr->vtable->klass, "m_Address");
+ field = mono_class_get_field_from_name (ipaddr->vtable->klass, "m_Address");
/* No idea why .net uses a 64bit type to hold a 32bit value...
*
* Internal value of IPAddess is in little-endian order
*/
- inaddr.s_addr=GUINT_FROM_LE ((guint32)*(guint64 *)(((char *)ipaddr)+field->offset));
+ inaddr.s_addr = GUINT_FROM_LE ((guint32)*(guint64 *)(((char *)ipaddr) + field->offset));
- return(inaddr);
+ return inaddr;
}
-static struct in6_addr ipaddress_to_struct_in6_addr(MonoObject *ipaddr)
+static struct in6_addr
+ipaddress_to_struct_in6_addr (MonoObject *ipaddr)
{
struct in6_addr in6addr;
MonoClassField *field;
MonoArray *data;
int i;
- field=mono_class_get_field_from_name(ipaddr->vtable->klass, "m_Numbers");
- data=*(MonoArray **)(((char *)ipaddr) + field->offset);
+ field = mono_class_get_field_from_name (ipaddr->vtable->klass, "m_Numbers");
+ data = *(MonoArray **)(((char *)ipaddr) + field->offset);
/* Solaris has only the 8 bit version. */
#ifndef s6_addr16
- for(i=0; i<8; i++) {
+ for (i = 0; i < 8; i++) {
guint16 s = mono_array_get (data, guint16, i);
in6addr.s6_addr[2 * i + 1] = (s >> 8) & 0xff;
in6addr.s6_addr[2 * i] = s & 0xff;
}
#else
- for(i=0; i<8; i++)
+ for (i = 0; i < 8; i++)
in6addr.s6_addr16[i] = mono_array_get (data, guint16, i);
#endif
- return(in6addr);
+ return in6addr;
}
#endif
struct ifaddrs *ifap = NULL, *ptr;
int idx = 0;
- if (getifaddrs (&ifap)) {
+ if (getifaddrs (&ifap))
return 0;
- }
for (ptr = ifap; ptr; ptr = ptr->ifa_next) {
if (!ptr->ifa_addr || !ptr->ifa_name)
#endif /* defined(__APPLE__) || defined(__FreeBSD__) */
void
-ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal (SOCKET sock, gint32 level, gint32 name, MonoObject *obj_val, MonoArray *byte_val, gint32 int_val, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_SetSocketOption_internal (SOCKET sock, gint32 level, gint32 name, MonoObject *obj_val, MonoArray *byte_val, gint32 int_val, gint32 *werror)
{
struct linger linger;
int system_level = 0;
int sol_ip;
int sol_ipv6;
- *error = 0;
+ *werror = 0;
sol_ipv6 = mono_networking_get_ipv6_protocol ();
sol_ip = mono_networking_get_ip_protocol ();
- ret=convert_sockopt_level_and_name((MonoSocketOptionLevel)level, (MonoSocketOptionName)name, &system_level,
- &system_name);
+ ret = convert_sockopt_level_and_name ((MonoSocketOptionLevel)level, (MonoSocketOptionName)name, &system_level,
+ &system_name);
#if !defined(SO_EXCLUSIVEADDRUSE) && defined(SO_REUSEADDR)
if (level == SocketOptionLevel_Socket && name == SocketOptionName_ExclusiveAddressUse) {
}
#endif
- if(ret==-1) {
- *error = WSAENOPROTOOPT;
+ if (ret == -1) {
+ *werror = WSAENOPROTOOPT;
return;
}
- if(ret==-2){
+ if (ret == -2)
return;
- }
/* Only one of obj_val, byte_val or int_val has data */
- if(obj_val!=NULL) {
+ if (obj_val) {
MonoClassField *field;
int valsize;
- switch(name) {
+ switch (name) {
case SocketOptionName_Linger:
/* Dig out "bool enabled" and "int lingerTime"
* fields
*/
- field=mono_class_get_field_from_name(obj_val->vtable->klass, "enabled");
- linger.l_onoff=*(guint8 *)(((char *)obj_val)+field->offset);
- field=mono_class_get_field_from_name(obj_val->vtable->klass, "lingerTime");
- linger.l_linger=*(guint32 *)(((char *)obj_val)+field->offset);
+ field = mono_class_get_field_from_name (obj_val->vtable->klass, "enabled");
+ linger.l_onoff = *(guint8 *)(((char *)obj_val) + field->offset);
+ field = mono_class_get_field_from_name (obj_val->vtable->klass, "lingerTime");
+ linger.l_linger = *(guint32 *)(((char *)obj_val) + field->offset);
- valsize=sizeof(linger);
+ valsize = sizeof (linger);
ret = _wapi_setsockopt (sock, system_level,
- system_name, &linger, valsize);
+ system_name, &linger, valsize);
break;
case SocketOptionName_AddMembership:
case SocketOptionName_DropMembership:
{
MonoObject *address = NULL;
- if(system_level == sol_ipv6) {
+ if (system_level == sol_ipv6) {
struct ipv6_mreq mreq6;
/*
field = mono_class_get_field_from_name (obj_val->vtable->klass, "m_Group");
address = *(MonoObject **)(((char *)obj_val) + field->offset);
- if(address) {
+ if (address)
mreq6.ipv6mr_multiaddr = ipaddress_to_struct_in6_addr (address);
- }
- field=mono_class_get_field_from_name(obj_val->vtable->klass, "m_Interface");
- mreq6.ipv6mr_interface =*(guint64 *)(((char *)obj_val)+field->offset);
+ field = mono_class_get_field_from_name (obj_val->vtable->klass, "m_Interface");
+ mreq6.ipv6mr_interface = *(guint64 *)(((char *)obj_val) + field->offset);
#if defined(__APPLE__) || defined(__FreeBSD__)
/*
#endif
ret = _wapi_setsockopt (sock, system_level,
- system_name, &mreq6,
- sizeof (mreq6));
- } else if(system_level == sol_ip) {
+ system_name, &mreq6,
+ sizeof (mreq6));
+ } else if (system_level == sol_ip) {
#ifdef HAVE_STRUCT_IP_MREQN
struct ip_mreqn mreq = {{0}};
#else
struct ip_mreq mreq = {{0}};
#endif /* HAVE_STRUCT_IP_MREQN */
- /* pain! MulticastOption holds two IPAddress
+ /*
+ * pain! MulticastOption holds two IPAddress
* members, so I have to dig the value out of
* those :-(
*/
/* address might not be defined and if so, set the address to ADDR_ANY.
*/
- if(address) {
+ if (address)
mreq.imr_multiaddr = ipaddress_to_struct_in_addr (address);
- }
field = mono_class_get_field_from_name (obj_val->vtable->klass, "localAddress");
address = *(MonoObject **)(((char *)obj_val) + field->offset);
#ifdef HAVE_STRUCT_IP_MREQN
- if(address) {
+ if (address)
mreq.imr_address = ipaddress_to_struct_in_addr (address);
- }
- field = mono_class_get_field_from_name(obj_val->vtable->klass, "ifIndex");
- mreq.imr_ifindex = *(gint32 *)(((char *)obj_val)+field->offset);
+ field = mono_class_get_field_from_name (obj_val->vtable->klass, "ifIndex");
+ mreq.imr_ifindex = *(gint32 *)(((char *)obj_val) + field->offset);
#else
- if(address) {
+ 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));
+ system_name, &mreq,
+ sizeof (mreq));
}
break;
}
#endif /* HAVE_STRUCT_IP_MREQN || HAVE_STRUCT_IP_MREQ */
default:
/* Cause an exception to be thrown */
- *error = WSAEINVAL;
+ *werror = WSAEINVAL;
return;
}
} else if (byte_val!=NULL) {
linger.l_linger = 0;
ret = _wapi_setsockopt (sock, system_level, system_name, &linger, sizeof (linger));
} else {
- *error = WSAEINVAL;
+ *werror = WSAEINVAL;
}
break;
default:
}
} else {
/* ReceiveTimeout/SendTimeout get here */
- switch(name) {
+ switch (name) {
case SocketOptionName_DontLinger:
linger.l_onoff = !int_val;
linger.l_linger = 0;
/* Fiddle with the value slightly if we're
* turning DF on
*/
- if (int_val == 1) {
+ if (int_val == 1)
int_val = IP_PMTUDISC_DO;
- }
/* Fall through */
#endif
}
}
- if(ret==SOCKET_ERROR) {
- *error = WSAGetLastError ();
- }
+ if (ret == SOCKET_ERROR)
+ *werror = WSAGetLastError ();
}
void
-ves_icall_System_Net_Sockets_Socket_Shutdown_internal(SOCKET sock, gint32 how, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_Shutdown_internal (SOCKET sock, gint32 how, gint32 *werror)
{
int ret;
gboolean interrupted;
- *error = 0;
+ *werror = 0;
mono_thread_info_install_interrupt (abort_syscall, (gpointer) (gsize) mono_native_thread_id_get (), &interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
mono_thread_info_uninstall_interrupt (&interrupted);
if (interrupted) {
- *error = WSAEINTR;
+ *werror = WSAEINTR;
return;
}
if (ret == SOCKET_ERROR)
- *error = WSAGetLastError ();
+ *werror = WSAGetLastError ();
}
gint
-ves_icall_System_Net_Sockets_Socket_IOControl_internal (SOCKET sock, gint32 code, MonoArray *input, MonoArray *output, gint32 *error)
+ves_icall_System_Net_Sockets_Socket_IOControl_internal (SOCKET sock, gint32 code, MonoArray *input, MonoArray *output, gint32 *werror)
{
glong output_bytes = 0;
gchar *i_buffer, *o_buffer;
gint i_len, o_len;
gint ret;
- *error = 0;
+ *werror = 0;
- if ((guint32)code == FIONBIO) {
+ if ((guint32)code == FIONBIO)
/* Invalid command. Must use Socket.Blocking */
return -1;
- }
if (input == NULL) {
i_buffer = NULL;
MONO_FINISH_BLOCKING;
if (ret == SOCKET_ERROR) {
- *error = WSAGetLastError ();
- return(-1);
+ *werror = WSAGetLastError ();
+ return -1;
}
- return (gint) output_bytes;
+ return (gint)output_bytes;
}
static gboolean
struct in6_addr *local_in6 = NULL;
int nlocal_in6 = 0;
int addr_index;
-
MonoDomain *domain = mono_domain_get ();
addr_index = 0;
- *h_aliases=mono_array_new(domain, mono_get_string_class (), 0);
+ *h_aliases = mono_array_new (domain, mono_get_string_class (), 0);
if (add_local_ips) {
local_in = (struct in_addr *) mono_get_local_interfaces (AF_INET, &nlocal_in);
local_in6 = (struct in6_addr *) mono_get_local_interfaces (AF_INET6, &nlocal_in6);
if (nlocal_in || nlocal_in6) {
char addr [INET6_ADDRSTRLEN];
- *h_addr_list=mono_array_new(domain, mono_get_string_class (), nlocal_in + nlocal_in6);
+ *h_addr_list = mono_array_new (domain, mono_get_string_class (), nlocal_in + nlocal_in6);
if (nlocal_in) {
MonoString *addr_string;
int i;
g_free (local_in);
g_free (local_in6);
- if (info) {
+ if (info)
mono_free_address_info (info);
- }
return TRUE;
}
for (count = 0, ai = info->entries; ai != NULL; ai = ai->next) {
if (ai->family != AF_INET && ai->family != AF_INET6)
continue;
-
count++;
}
- *h_addr_list=mono_array_new(domain, mono_get_string_class (), count);
+ *h_addr_list = mono_array_new (domain, mono_get_string_class (), count);
for (ai = info->entries, i = 0; ai != NULL; ai = ai->next) {
MonoAddress maddr;
MonoString *addr_string;
char buffer [INET6_ADDRSTRLEN]; /* Max. size for IPv6 */
- if((ai->family != PF_INET) && (ai->family != PF_INET6)) {
+ if ((ai->family != PF_INET) && (ai->family != PF_INET6))
continue;
- }
mono_address_init (&maddr, ai->family, &ai->address);
- if(mono_networking_addr_to_str (&maddr, buffer, sizeof (buffer))) {
- addr_string=mono_string_new(domain, buffer);
- } else {
- addr_string=mono_string_new(domain, "");
- }
+ if (mono_networking_addr_to_str (&maddr, buffer, sizeof (buffer)))
+ addr_string = mono_string_new (domain, buffer);
+ else
+ addr_string = mono_string_new (domain, "");
mono_array_setref (*h_addr_list, addr_index, addr_string);
- if(!i) {
+ if (!i) {
i++;
if (ai->canonical_name != NULL) {
- *h_name=mono_string_new(domain, ai->canonical_name);
+ *h_name = mono_string_new (domain, ai->canonical_name);
} else {
- *h_name=mono_string_new(domain, buffer);
+ *h_name = mono_string_new (domain, buffer);
}
}
addr_index++;
}
- if(info) {
+ if (info)
mono_free_address_info (info);
- }
- return(TRUE);
+ return TRUE;
}
static int
-get_addrinfo_family_hint (void)
+get_addrinfo_family_hint (MonoError *error)
{
- switch (get_family_hint ()) {
- case PF_UNSPEC: return MONO_HINT_UNSPECIFIED;
- case PF_INET: return MONO_HINT_IPV4;
+ int hint;
+
+ mono_error_init (error);
+
+ hint = get_family_hint (error);
+ return_val_if_nok (error, 0);
+
+ switch (hint) {
+ case PF_UNSPEC:
+ return MONO_HINT_UNSPECIFIED;
+ case PF_INET:
+ return MONO_HINT_IPV4;
#ifdef PF_INET6
- case PF_INET6: return MONO_HINT_IPV6;
+ case PF_INET6:
+ return MONO_HINT_IPV6;
#endif
default:
g_error ("invalid hint");
gchar this_hostname [256];
MonoAddressInfo *info = NULL;
char *hostname = mono_string_to_utf8 (host);
- int hint = get_addrinfo_family_hint ();
+ MonoError error;
+ int hint;
+
+ hint = get_addrinfo_family_hint (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return FALSE;
+ }
if (*hostname == '\0') {
add_local_ips = TRUE;
g_free(hostname);
if (add_info_ok)
- return addrinfo_to_IPHostEntry(info, h_name, h_aliases, h_addr_list, add_local_ips);
+ return addrinfo_to_IPHostEntry (info, h_name, h_aliases, h_addr_list, add_local_ips);
return FALSE;
}
struct sockaddr_in saddr;
struct sockaddr_in6 saddr6;
MonoAddressInfo *info = NULL;
- gint32 family;
- gchar hostname[NI_MAXHOST] = { 0 };
+ MonoError error;
+ gint32 family, hint;
+ gchar hostname [NI_MAXHOST] = { 0 };
gboolean ret;
address = mono_string_to_utf8 (addr);
#if HAVE_SOCKADDR_IN_SIN_LEN
saddr.sin_len = sizeof (saddr);
#endif
- ret = getnameinfo ((struct sockaddr*)&saddr, sizeof(saddr), hostname, sizeof(hostname), NULL, 0, 0) == 0;
+ ret = getnameinfo ((struct sockaddr*)&saddr, sizeof (saddr), hostname, sizeof (hostname), NULL, 0, 0) == 0;
break;
}
case AF_INET6: {
#if HAVE_SOCKADDR_IN6_SIN_LEN
saddr6.sin6_len = sizeof (saddr6);
#endif
- ret = getnameinfo ((struct sockaddr*)&saddr6, sizeof(saddr6), hostname, sizeof(hostname), NULL, 0, 0) == 0;
+ ret = getnameinfo ((struct sockaddr*)&saddr6, sizeof (saddr6), hostname, sizeof (hostname), NULL, 0, 0) == 0;
break;
}
default:
if (!ret)
return FALSE;
- if (mono_get_address_info (hostname, 0, get_addrinfo_family_hint () | MONO_HINT_CANONICAL_NAME | MONO_HINT_CONFIGURED_ONLY, &info) != 0)
+ hint = get_addrinfo_family_hint (&error);
+ if (!mono_error_ok (&error)) {
+ mono_error_set_pending_exception (&error);
+ return FALSE;
+ }
+ if (mono_get_address_info (hostname, 0, hint | MONO_HINT_CANONICAL_NAME | MONO_HINT_CONFIGURED_ONLY, &info) != 0)
return FALSE;
return addrinfo_to_IPHostEntry (info, h_name, h_aliases, h_addr_list, FALSE);
MonoBoolean
ves_icall_System_Net_Dns_GetHostName_internal (MonoString **h_name)
{
- gchar hostname[NI_MAXHOST] = { 0 };
+ gchar hostname [NI_MAXHOST] = { 0 };
int ret;
ret = gethostname (hostname, sizeof (hostname));
if (ret == -1)
return FALSE;
- *h_name = mono_string_new(mono_domain_get (), hostname);
+ *h_name = mono_string_new (mono_domain_get (), hostname);
return TRUE;
}
ves_icall_System_Net_Sockets_Socket_SendFile_internal (SOCKET sock, MonoString *filename, MonoArray *pre_buffer, MonoArray *post_buffer, gint flags)
{
HANDLE file;
- gint32 error;
+ gint32 werror;
gboolean ret;
gboolean interrupted;
TRANSMIT_FILE_BUFFERS buffers;
/* FIXME: replace file by a proper fd that we can call open and close on, as they are interruptible */
- file = ves_icall_System_IO_MonoIO_Open (filename, FileMode_Open, FileAccess_Read, FileShare_Read, 0, &error);
+ file = ves_icall_System_IO_MonoIO_Open (filename, FileMode_Open, FileAccess_Read, FileShare_Read, 0, &werror);
if (file == INVALID_HANDLE_VALUE) {
- SetLastError (error);
+ SetLastError (werror);
return FALSE;
}
}
void
-mono_network_init(void)
+mono_network_init (void)
{
mono_networking_init ();
}
void
-mono_network_cleanup(void)
+mono_network_cleanup (void)
{
_wapi_cleanup_networking ();
mono_networking_shutdown ();
MonoString *
ves_icall_System_String_InternalIntern (MonoString *str)
{
+ MonoError error;
MonoString *res;
- res = mono_string_intern(str);
+ res = mono_string_intern_checked (str, &error);
if (!res) {
- mono_set_pending_exception (mono_domain_get ()->out_of_memory_ex);
+ mono_error_set_pending_exception (&error);
return NULL;
}
return res;
MonoString *
ves_icall_System_String_InternalIsInterned (MonoString *str)
{
- return mono_string_is_interned(str);
+ return mono_string_is_interned (str);
}
int
ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject **location, MonoObject *value)
{
MonoObject *res;
+ MONO_CHECK_NULL (location, NULL);
res = (MonoObject *)InterlockedExchangePointer ((volatile gpointer *)location, value);
mono_gc_wbarrier_generic_nostore (location);
return res;
return ctx.list;
}
- ctx.header = mono_method_get_header (method);
+ ctx.header = mono_method_get_header_checked (method, &error);
if (!ctx.header) {
- ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Could not decode method header"));
+ ADD_VERIFY_ERROR (&ctx, g_strdup_printf ("Could not decode method header due to %s", mono_error_get_message (&error)));
+ mono_error_cleanup (&error);
finish_collect_stats ();
return ctx.list;
}
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/assembly.h>
#include <mono/metadata/metadata-internals.h>
+#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/marshal.h>
#include <mono/metadata/gc-internals.h>
#include <mono/metadata/mempool-internals.h>
if (method)
add_method (acfg, mono_marshal_get_delegate_end_invoke (method));
- cattr = mono_custom_attrs_from_class (klass);
+ cattr = mono_custom_attrs_from_class_checked (klass, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error);
+ continue;
+ }
if (cattr) {
int j;
* attribute named MonoPInvokeCallbackAttribute. We search for the attribute by
* name to avoid defining a new assembly to contain it.
*/
- cattr = mono_custom_attrs_from_method (method);
+ cattr = mono_custom_attrs_from_method_checked (method, &error);
+ if (!is_ok (&error)) {
+ char *name = mono_method_get_full_name (method);
+ report_loader_error (acfg, &error, "Failed to load custom attributes from method %s due to %s\n", name, mono_error_get_message (&error));
+ g_free (name);
+ }
if (cattr) {
for (j = 0; j < cattr->num_attrs; ++j)
/* Add the T[]/InternalEnumerator class */
if (!strcmp (klass->name, "IEnumerable`1") || !strcmp (klass->name, "IEnumerator`1")) {
+ MonoError error;
MonoClass *nclass;
iter = NULL;
break;
}
g_assert (nclass);
- nclass = mono_class_inflate_generic_class (nclass, mono_generic_class_get_context (klass->generic_class));
+ nclass = mono_class_inflate_generic_class_checked (nclass, mono_generic_class_get_context (klass->generic_class), &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
add_generic_class (acfg, nclass, FALSE, "ICollection<T>");
}
/* Add an instance of GenericComparer<T> which is created dynamically by Comparer<T> */
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "Comparer`1")) {
+ MonoError error;
MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
- MonoClass *icomparable, *gcomparer;
+ MonoClass *icomparable, *gcomparer, *icomparable_inst;
MonoGenericContext ctx;
MonoType *args [16];
args [0] = &tclass->byval_arg;
ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- if (mono_class_is_assignable_from (mono_class_inflate_generic_class (icomparable, &ctx), tclass)) {
+ icomparable_inst = mono_class_inflate_generic_class_checked (icomparable, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
+ if (mono_class_is_assignable_from (icomparable_inst, tclass)) {
+ MonoClass *gcomparer_inst;
gcomparer = mono_class_load_from_name (mono_defaults.corlib, "System.Collections.Generic", "GenericComparer`1");
- add_generic_class (acfg, mono_class_inflate_generic_class (gcomparer, &ctx), FALSE, "Comparer<T>");
+ gcomparer_inst = mono_class_inflate_generic_class_checked (gcomparer, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
+ add_generic_class (acfg, gcomparer_inst, FALSE, "Comparer<T>");
}
}
/* Add an instance of GenericEqualityComparer<T> which is created dynamically by EqualityComparer<T> */
if (klass->image == mono_defaults.corlib && !strcmp (klass->name_space, "System.Collections.Generic") && !strcmp (klass->name, "EqualityComparer`1")) {
+ MonoError error;
MonoClass *tclass = mono_class_from_mono_type (klass->generic_class->context.class_inst->type_argv [0]);
- MonoClass *iface, *gcomparer;
+ MonoClass *iface, *gcomparer, *iface_inst;
MonoGenericContext ctx;
MonoType *args [16];
args [0] = &tclass->byval_arg;
ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- if (mono_class_is_assignable_from (mono_class_inflate_generic_class (iface, &ctx), tclass)) {
+ iface_inst = mono_class_inflate_generic_class_checked (iface, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
+ if (mono_class_is_assignable_from (iface_inst, tclass)) {
+ MonoClass *gcomparer_inst;
+ MonoError error;
+
gcomparer = mono_class_load_from_name (mono_defaults.corlib, "System.Collections.Generic", "GenericEqualityComparer`1");
- add_generic_class (acfg, mono_class_inflate_generic_class (gcomparer, &ctx), FALSE, "EqualityComparer<T>");
+ gcomparer_inst = mono_class_inflate_generic_class_checked (gcomparer, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ add_generic_class (acfg, gcomparer_inst, FALSE, "EqualityComparer<T>");
}
}
MonoType *args [16];
if (mono_class_is_enum (tclass)) {
+ MonoClass *enum_comparer_inst;
+ MonoError error;
+
memset (&ctx, 0, sizeof (ctx));
args [0] = &tclass->byval_arg;
ctx.class_inst = mono_metadata_get_generic_inst (1, args);
enum_comparer = mono_class_load_from_name (mono_defaults.corlib, "System.Collections.Generic", "EnumEqualityComparer`1");
- add_generic_class (acfg, mono_class_inflate_generic_class (enum_comparer, &ctx), FALSE, "EqualityComparer<T>");
+ enum_comparer_inst = mono_class_inflate_generic_class_checked (enum_comparer, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ add_generic_class (acfg, enum_comparer_inst, FALSE, "EqualityComparer<T>");
}
}
MonoType *args [16];
if (mono_class_is_enum (tclass)) {
+ MonoClass *comparer_inst;
+ MonoError error;
+
memset (&ctx, 0, sizeof (ctx));
args [0] = &tclass->byval_arg;
ctx.class_inst = mono_metadata_get_generic_inst (1, args);
comparer = mono_class_load_from_name (mono_defaults.corlib, "System.Collections.Generic", "ObjectComparer`1");
- add_generic_class (acfg, mono_class_inflate_generic_class (comparer, &ctx), FALSE, "Comparer<T>");
+ comparer_inst = mono_class_inflate_generic_class_checked (comparer, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ add_generic_class (acfg, comparer_inst, FALSE, "Comparer<T>");
}
}
}
memset (&ctx, 0, sizeof (ctx));
for (i = 0; i < ninsts; ++i) {
+ MonoError error;
+ MonoClass *generic_inst;
args [0] = insts [i];
ctx.class_inst = mono_metadata_get_generic_inst (1, args);
- add_generic_class (acfg, mono_class_inflate_generic_class (klass, &ctx), force, "");
+ generic_inst = mono_class_inflate_generic_class_checked (klass, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+ add_generic_class (acfg, generic_inst, force, "");
}
}
static void
add_types_from_method_header (MonoAotCompile *acfg, MonoMethod *method)
{
+ MonoError error;
MonoMethodHeader *header;
MonoMethodSignature *sig;
int j, depth;
add_generic_class_with_depth (acfg, mono_class_from_mono_type (sig->params [j]), depth + 1, "arg");
}
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
if (header) {
for (j = 0; j < header->num_locals; ++j)
if (header->locals [j]->type == MONO_TYPE_GENERICINST)
add_generic_class_with_depth (acfg, mono_class_from_mono_type (header->locals [j]), depth + 1, "local");
} else {
- mono_loader_clear_error ();
+ mono_error_cleanup (&error); /* FIXME report the error */
}
}
}
/* Make a copy of the argument/local info */
{
+ MonoError error;
MonoInst **args, **locals;
MonoMethodSignature *sig;
MonoMethodHeader *header;
}
cfg->args = args;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
locals = (MonoInst **)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst*) * header->num_locals);
for (i = 0; i < header->num_locals; ++i) {
locals [i] = (MonoInst *)mono_mempool_alloc (acfg->mempool, sizeof (MonoInst));
g_assert (mono_error_ok (&error));
break;
case MONO_AOT_TYPEREF_GINST: {
+ MonoError error;
MonoClass *gclass;
MonoGenericContext ctx;
MonoType *type;
ctx.class_inst = decode_generic_inst (module, p, &p);
if (!ctx.class_inst)
return NULL;
- type = mono_class_inflate_generic_type (&gclass->byval_arg, &ctx);
+ type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
klass = mono_class_from_mono_type (type);
mono_metadata_free_type (type);
break;
t->data.type = decode_type (module, p, &p);
break;
case MONO_TYPE_GENERICINST: {
+ MonoError error;
MonoClass *gclass;
MonoGenericContext ctx;
MonoType *type;
ctx.class_inst = decode_generic_inst (module, p, &p);
if (!ctx.class_inst)
return NULL;
- type = mono_class_inflate_generic_type (&gclass->byval_arg, &ctx);
+ type = mono_class_inflate_generic_type_checked (&gclass->byval_arg, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
klass = mono_class_from_mono_type (type);
t->data.generic_class = klass->generic_class;
break;
if (!got [got_slots [pindex]] || ji->type == MONO_PATCH_INFO_SFLDA) {
/* In llvm-only made, we might encounter shared methods */
if (mono_llvm_only && ji->type == MONO_PATCH_INFO_METHOD && mono_method_check_context_used (ji->data.method)) {
- MonoError error;
-
g_assert (context);
- ji->data.method = mono_class_inflate_generic_method_checked (ji->data.method, context, &error);
+ ji->data.method = mono_class_inflate_generic_method_checked (ji->data.method, context, error);
+ if (!mono_error_ok (error)) {
+ g_free (got_slots);
+ mono_mempool_destroy (mp);
+ return FALSE;
+ }
}
/* This cannot be resolved in mono_resolve_patch_target () */
if (ji->type == MONO_PATCH_INFO_AOT_JIT_INFO) {
gboolean inited_ok = TRUE;
if (init_class)
- inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, init_class), &error);
+ inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, init_class), error);
else if (from_plt && klass && !klass->generic_container)
- inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, klass), &error);
+ inited_ok = mono_runtime_class_init_full (mono_class_vtable (domain, klass), error);
if (!inited_ok)
- mono_error_raise_exception (&error); /* FIXME don't raise here */
+ return FALSE;
return TRUE;
mono_debug_add_vg_method (MonoMethod *method, MonoDebugMethodJitInfo *jit)
{
#ifdef VALGRIND_ADD_LINE_INFO
+ MonoError error;
MonoMethodHeader *header;
MonoDebugMethodInfo *minfo;
int i;
if (!RUNNING_ON_VALGRIND)
return;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
full_name = mono_method_full_name (method, TRUE);
static MonoDebugMethodJitInfo *
deserialize_debug_info (MonoMethod *method, guint8 *code_start, guint8 *buf, guint32 buf_len)
{
+ MonoError error;
MonoMethodHeader *header;
gint32 offset, native_offset, prev_offset, prev_native_offset;
MonoDebugMethodJitInfo *jit;
guint8 *p;
int i;
- header = mono_method_get_header (method);
- g_assert (header);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
jit = g_new0 (MonoDebugMethodJitInfo, 1);
jit->code_start = code_start;
init_jit_info_dbg_attrs (MonoJitInfo *ji)
{
static MonoClass *hidden_klass, *step_through_klass, *non_user_klass;
+ MonoError error;
MonoCustomAttrInfo *ainfo;
if (ji->dbg_attrs_inited)
if (!non_user_klass)
non_user_klass = mono_class_load_from_name (mono_defaults.corlib, "System.Diagnostics", "DebuggerNonUserCodeAttribute");
- ainfo = mono_custom_attrs_from_method (jinfo_get_method (ji));
+ ainfo = mono_custom_attrs_from_method_checked (jinfo_get_method (ji), &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error? */
if (ainfo) {
if (mono_custom_attrs_has_attr (ainfo, hidden_klass))
ji->dbg_hidden = TRUE;
mono_custom_attrs_free (ainfo);
}
- ainfo = mono_custom_attrs_from_class (jinfo_get_method (ji)->klass);
+ ainfo = mono_custom_attrs_from_class_checked (jinfo_get_method (ji)->klass, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error? */
if (ainfo) {
if (mono_custom_attrs_has_attr (ainfo, step_through_klass))
ji->dbg_step_through = TRUE;
if (err != ERR_NONE)
return err;
- cinfo = mono_custom_attrs_from_class (klass);
+ cinfo = mono_custom_attrs_from_class_checked (klass, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+ return ERR_LOADER_ERROR;
+ }
err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
if (err != ERR_NONE)
if (err != ERR_NONE)
return err;
- cinfo = mono_custom_attrs_from_field (klass, field);
+ cinfo = mono_custom_attrs_from_field_checked (klass, field, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+ return ERR_LOADER_ERROR;
+ }
err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
if (err != ERR_NONE)
if (err != ERR_NONE)
return err;
- cinfo = mono_custom_attrs_from_property (klass, prop);
+ cinfo = mono_custom_attrs_from_property_checked (klass, prop, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+ return ERR_LOADER_ERROR;
+ }
err = buffer_add_cattrs (buf, domain, klass->image, attr_klass, cinfo);
if (err != ERR_NONE)
break;
}
case CMD_METHOD_GET_DEBUG_INFO: {
+ MonoError error;
MonoDebugMethodInfo *minfo;
char *source_file;
int i, j, n_il_offsets;
GPtrArray *source_file_list;
MonoSymSeqPoint *sym_seq_points;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
if (!header) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
buffer_add_int (buf, 0);
buffer_add_string (buf, "");
buffer_add_int (buf, 0);
break;
}
case CMD_METHOD_GET_LOCALS_INFO: {
+ MonoError error;
int i, num_locals;
MonoDebugLocalsInfo *locals;
int *locals_map = NULL;
- header = mono_method_get_header (method);
- if (!header)
+ header = mono_method_get_header_checked (method, &error);
+ if (!header) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
return ERR_INVALID_ARGUMENT;
+ }
locals = mono_debug_lookup_locals (method);
if (!locals) {
}
break;
case CMD_METHOD_GET_BODY: {
+ MonoError error;
int i;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
if (!header) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
buffer_add_int (buf, 0);
if (CHECK_PROTOCOL_VERSION (2, 18))
break;
}
case CMD_METHOD_GET_CATTRS: {
+ MonoError error;
MonoClass *attr_klass;
MonoCustomAttrInfo *cinfo;
if (err != ERR_NONE)
return err;
- cinfo = mono_custom_attrs_from_method (method);
+ cinfo = mono_custom_attrs_from_method_checked (method, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error message */
+ return ERR_LOADER_ERROR;
+ }
err = buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo);
if (err != ERR_NONE)
switch (command) {
case CMD_STACK_FRAME_GET_VALUES: {
+ MonoError error;
len = decode_int (p, &p, end);
- header = mono_method_get_header (frame->actual_method);
+ header = mono_method_get_header_checked (frame->actual_method, &error);
+ mono_error_assert_ok (&error); /* FIXME report error */
for (i = 0; i < len; ++i) {
pos = decode_int (p, &p, end);
break;
}
case CMD_STACK_FRAME_SET_VALUES: {
+ MonoError error;
guint8 *val_buf;
MonoType *t;
MonoDebugVarInfo *var;
len = decode_int (p, &p, end);
- header = mono_method_get_header (frame->actual_method);
+ header = mono_method_get_header_checked (frame->actual_method, &error);
+ mono_error_assert_ok (&error); /* FIXME report error */
for (i = 0; i < len; ++i) {
pos = decode_int (p, &p, end);
static char*
disasm_ins (MonoMethod *method, const guchar *ip, const guint8 **endip)
{
+ MonoError error;
char *dis;
MonoDisHelper dh;
- MonoMethodHeader *header = mono_method_get_header (method);
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
memset (&dh, 0, sizeof (dh));
dh.newline = "";
guint8 *code, guint32 code_size,
MonoDebugMethodJitInfo *debug_info)
{
+ MonoError error;
guint32 prev_line = 0;
guint32 prev_native_offset = 0;
int i, file_index, il_offset, prev_il_offset;
gboolean first = TRUE;
MonoDebugSourceLocation *loc;
char *prev_file_name = NULL;
- MonoMethodHeader *header = mono_method_get_header (method);
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
MonoDebugMethodInfo *minfo;
MonoDebugLineNumberEntry *ln_array;
int *native_to_il_offset = NULL;
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
if (!w->emit_line) {
mono_metadata_free_mh (header);
return;
mono_dwarf_writer_emit_method (MonoDwarfWriter *w, MonoCompile *cfg, MonoMethod *method, char *start_symbol, char *end_symbol, char *linkage_name,
guint8 *code, guint32 code_size, MonoInst **args, MonoInst **locals, GSList *unwind_info, MonoDebugMethodJitInfo *debug_info)
{
+ MonoError error;
char *name;
MonoMethodSignature *sig;
MonoMethodHeader *header;
emit_section_change (w, ".debug_info", 0);
sig = mono_method_signature (method);
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
/* Parameter types */
for (i = 0; i < sig->param_count + sig->hasthis; ++i) {
#include <mono/metadata/debug-mono-symfile.h>
#include <mono/utils/mono-compiler.h>
#include <mono/utils/mono-memory-model.h>
+#include <mono/utils/mono-error-internals.h>
#include <mono/metadata/mono-basic-block.h>
#include <mono/metadata/reflection-internals.h>
return -1;
}
+//XXX this ignores if t is byref
+#define MONO_TYPE_IS_PRIMITIVE_SCALAR(t) ((((((t)->type >= MONO_TYPE_BOOLEAN && (t)->type <= MONO_TYPE_U8) || ((t)->type >= MONO_TYPE_I && (t)->type <= MONO_TYPE_U)))))
+
/*
* target_type_is_incompatible:
* @cfg: MonoCompile context
if (target->byref) {
/* FIXME: check that the pointed to types match */
if (arg->type == STACK_MP) {
- MonoClass *base_class = mono_class_from_mono_type (target);
- /* This is needed to handle gshared types + ldaddr */
- simple_type = mini_get_underlying_type (&base_class->byval_arg);
- return target->type != MONO_TYPE_I && arg->klass != base_class && arg->klass != mono_class_from_mono_type (simple_type);
+ if (cfg->verbose_level) printf ("ok\n");
+ /* This is needed to handle gshared types + ldaddr. We lower the types so we can handle enums and other typedef-like types. */
+ MonoClass *target_class_lowered = mono_class_from_mono_type (mini_get_underlying_type (&mono_class_from_mono_type (target)->byval_arg));
+ MonoClass *source_class_lowered = mono_class_from_mono_type (mini_get_underlying_type (&arg->klass->byval_arg));
+
+ /* if the target is native int& or same type */
+ if (target->type == MONO_TYPE_I || target_class_lowered == source_class_lowered)
+ return 0;
+
+ /* Both are primitive type byrefs and the source points to a larger type that the destination */
+ if (MONO_TYPE_IS_PRIMITIVE_SCALAR (&target_class_lowered->byval_arg) && MONO_TYPE_IS_PRIMITIVE_SCALAR (&source_class_lowered->byval_arg) &&
+ mono_class_instance_size (target_class_lowered) <= mono_class_instance_size (source_class_lowered))
+ return 0;
+ return 1;
}
if (arg->type == STACK_PTR)
return 0;
inline_method (MonoCompile *cfg, MonoMethod *cmethod, MonoMethodSignature *fsig, MonoInst **sp,
guchar *ip, guint real_offset, gboolean inline_always)
{
+ MonoError error;
MonoInst *ins, *rvar = NULL;
MonoMethodHeader *cheader;
MonoBasicBlock *ebblock, *sbblock;
}
/* allocate local variables */
- cheader = mono_method_get_header (cmethod);
-
- if (cheader == NULL || mono_loader_get_last_error ()) {
- if (cheader)
- mono_metadata_free_mh (cheader);
- if (inline_always && mono_loader_get_last_error ()) {
+ cheader = mono_method_get_header_checked (cmethod, &error);
+ if (!cheader) {
+ if (inline_always) {
mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
- mono_error_set_from_loader_error (&cfg->error);
+ mono_error_move (&cfg->error, &error);
+ } else {
+ mono_error_cleanup (&error);
}
-
- mono_loader_clear_error ();
return 0;
}
if (method->wrapper_type != MONO_WRAPPER_NONE) {
klass = (MonoClass *)mono_method_get_wrapper_data (method, token);
- if (context)
- klass = mono_class_inflate_generic_class (klass, context);
+ if (context) {
+ klass = mono_class_inflate_generic_class_checked (klass, context, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
+ }
} else {
klass = mono_class_get_and_inflate_typespec_checked (method->klass->image, token, context, &error);
mono_error_cleanup (&error); /* FIXME don't swallow the error */
static void
set_exception_type_from_invalid_il (MonoCompile *cfg, MonoMethod *method, unsigned char *ip)
{
+ MonoError error;
char *method_fname = mono_method_full_name (method, TRUE);
char *method_code;
- MonoMethodHeader *header = mono_method_get_header (method);
+ MonoMethodHeader *header = mono_method_get_header_checked (method, &error);
- if (header->code_size == 0)
+ if (!header) {
+ method_code = g_strdup_printf ("could not parse method body due to %s", mono_error_get_message (&error));
+ mono_error_cleanup (&error);
+ } else if (header->code_size == 0)
method_code = g_strdup ("method body is empty.");
else
method_code = mono_disasm_code_one (NULL, method, ip, NULL);
static gboolean
is_jit_optimizer_disabled (MonoMethod *m)
{
+ MonoError error;
MonoAssembly *ass = m->klass->image->assembly;
MonoCustomAttrInfo* attrs;
MonoClass *klass;
return FALSE;
}
- attrs = mono_custom_attrs_from_assembly (ass);
+ attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (attrs) {
for (i = 0; i < attrs->num_attrs; ++i) {
MonoCustomAttrEntry *attr = &attrs->attrs [i];
dont_verify_stloc |= method->wrapper_type == MONO_WRAPPER_STELEMREF;
image = method->klass->image;
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &cfg->error);
if (!header) {
- if (mono_loader_get_last_error ()) {
- mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
- mono_error_set_from_loader_error (&cfg->error);
- } else {
- mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name));
- }
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
goto exception_exit;
}
generic_container = mono_method_get_generic_container (method);
/* STATIC CASE */
context_used = mini_class_check_context_used (cfg, klass);
- if (ftype->attrs & FIELD_ATTRIBUTE_LITERAL)
- UNVERIFIED;
+ if (ftype->attrs & FIELD_ATTRIBUTE_LITERAL) {
+ mono_error_set_field_load (&cfg->error, field->parent, field->name, "Using static instructions with literal field");
+ CHECK_CFG_ERROR;
+ }
/* The special_static_fields field is init'd in mono_class_vtable, so it needs
* to be called here.
amd64_alu_reg_imm (code, X86_CMP, AMD64_RAX, X86_FP_C0);
amd64_pop_reg (code, AMD64_RAX);
amd64_fstp (code, 0);
- EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, FALSE, "ArithmeticException");
+ EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, FALSE, "OverflowException");
amd64_alu_reg_imm (code, X86_ADD, AMD64_RSP, 16);
break;
case OP_TLS_GET: {
#endif
ARM_CMPD (code, vfp_scratch2, vfp_scratch1);
ARM_FMSTAT (code);
- EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_GT, "ArithmeticException");
+ EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_GT, "OverflowException");
ARM_CMPD (code, ins->sreg1, ins->sreg1);
ARM_FMSTAT (code);
- EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_VS, "ArithmeticException");
+ EMIT_COND_SYSTEM_EXCEPTION_FLAGS (ARMCOND_VS, "OverflowException");
ARM_CPYD (code, ins->dreg, ins->sreg1);
code = mono_arm_emit_vfp_scratch_restore (cfg, code, vfp_scratch1);
#include <mono/metadata/threads-types.h>
#include <mono/metadata/debug-helpers.h>
#include <mono/metadata/exception.h>
+#include <mono/metadata/exception-internals.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/reflection-internals.h>
#include <mono/metadata/gc-internals.h>
static MonoClass*
get_exception_catch_class (MonoJitExceptionInfo *ei, MonoJitInfo *ji, MonoContext *ctx)
{
+ MonoError error;
MonoClass *catch_class = ei->data.catch_class;
MonoType *inflated_type;
MonoGenericContext context;
when the exception is actually thrown, so as not to
waste space for exception clauses which might never
be encountered. */
- inflated_type = mono_class_inflate_generic_type (&catch_class->byval_arg, &context);
+ inflated_type = mono_class_inflate_generic_type_checked (&catch_class->byval_arg, &context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
catch_class = mono_class_from_mono_type (inflated_type);
mono_metadata_free_type (inflated_type);
static gboolean
wrap_non_exception_throws (MonoMethod *m)
{
+ MonoError error;
MonoAssembly *ass = m->klass->image->assembly;
MonoCustomAttrInfo* attrs;
MonoClass *klass;
klass = mono_class_get_runtime_compat_attr_class ();
- attrs = mono_custom_attrs_from_assembly (ass);
+ attrs = mono_custom_attrs_from_assembly_checked (ass, &error);
+ mono_error_cleanup (&error); /* FIXME don't swallow the error */
if (attrs) {
for (i = 0; i < attrs->num_attrs; ++i) {
MonoCustomAttrEntry *attr = &attrs->attrs [i];
if (!mono_object_isinst (obj, mono_defaults.exception_class)) {
non_exception = obj;
- obj = (MonoObject *)mono_get_exception_runtime_wrapped (obj);
+ obj = (MonoObject *)mono_get_exception_runtime_wrapped_checked (obj, &error);
+ mono_error_assert_ok (&error);
}
mono_ex = (MonoException*)obj;
static void
throw_exception (MonoObject *ex, gboolean rethrow)
{
+ MonoError error;
MonoJitTlsData *jit_tls = mono_get_jit_tls ();
MonoException *mono_ex;
- if (!mono_object_isinst (ex, mono_defaults.exception_class))
- mono_ex = mono_get_exception_runtime_wrapped (ex);
+ if (!mono_object_isinst (ex, mono_defaults.exception_class)) {
+ mono_ex = mono_get_exception_runtime_wrapped_checked (ex, &error);
+ mono_error_assert_ok (&error);
+ }
else
mono_ex = (MonoException*)ex;
catch_class = ei->data.catch_class;
if (catch_class->byval_arg.type == MONO_TYPE_VAR || catch_class->byval_arg.type == MONO_TYPE_MVAR || catch_class->byval_arg.type == MONO_TYPE_GENERICINST) {
+ MonoError error;
MonoGenericContext context;
MonoType *inflated_type;
g_assert (rgctx || this_obj);
context = get_generic_context_from_stack_frame (jinfo, rgctx ? rgctx : this_obj->vtable);
- inflated_type = mono_class_inflate_generic_type (&catch_class->byval_arg, &context);
+ inflated_type = mono_class_inflate_generic_type_checked (&catch_class->byval_arg, &context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
catch_class = mono_class_from_mono_type (inflated_type);
mono_metadata_free_type (inflated_type);
}
case MONO_RGCTX_INFO_METHOD_DELEGATE_CODE: {
MonoMethod *method = (MonoMethod *)data;
MonoMethod *inflated_method;
- MonoType *inflated_type = mono_class_inflate_generic_type (&method->klass->byval_arg, context);
+ MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
mono_metadata_free_type (inflated_type);
MonoJumpInfoGSharedVtCall *info = (MonoJumpInfoGSharedVtCall *)data;
MonoMethod *method = info->method;
MonoMethod *inflated_method;
- MonoType *inflated_type = mono_class_inflate_generic_type (&method->klass->byval_arg, context);
+ MonoType *inflated_type = mono_class_inflate_generic_type_checked (&method->klass->byval_arg, context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
MonoJumpInfoGSharedVtCall *res;
MonoDomain *domain = mono_domain_get ();
case MONO_RGCTX_INFO_CLASS_FIELD:
case MONO_RGCTX_INFO_FIELD_OFFSET: {
+ MonoError error;
MonoClassField *field = (MonoClassField *)data;
- MonoType *inflated_type = mono_class_inflate_generic_type (&field->parent->byval_arg, context);
+ MonoType *inflated_type = mono_class_inflate_generic_type_checked (&field->parent->byval_arg, context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
MonoClass *inflated_class = mono_class_from_mono_type (inflated_type);
int i = field - field->parent->fields;
gpointer dummy = NULL;
// FIXME: Temporary
res = (MonoJumpInfoVirtMethod *)mono_domain_alloc0 (domain, sizeof (MonoJumpInfoVirtMethod));
- t = mono_class_inflate_generic_type (&info->klass->byval_arg, context);
+ t = mono_class_inflate_generic_type_checked (&info->klass->byval_arg, context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
+
res->klass = mono_class_from_mono_type (t);
mono_metadata_free_type (t);
case MONO_TYPE_PTR:
return &mono_defaults.int_class->byval_arg;
case MONO_TYPE_GENERICINST: {
+ MonoError error;
MonoClass *klass;
MonoGenericContext ctx;
MonoGenericContext *orig_ctx;
args [i] = get_wrapper_shared_type (inst->type_argv [i]);
ctx.method_inst = mono_metadata_get_generic_inst (inst->type_argc, args);
}
- klass = mono_class_inflate_generic_class (klass->generic_class->container_class, &ctx);
+ klass = mono_class_inflate_generic_class_checked (klass->generic_class->container_class, &ctx, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
return &klass->byval_arg;
}
#if SIZEOF_VOID_P == 8
static G_GNUC_UNUSED gboolean
is_async_method (MonoMethod *method)
{
+ MonoError error;
MonoCustomAttrInfo *cattr;
MonoMethodSignature *sig;
gboolean res = FALSE;
(sig->ret->type == MONO_TYPE_CLASS && !strcmp (sig->ret->data.generic_class->container_class->name, "Task")) ||
(sig->ret->type == MONO_TYPE_GENERICINST && !strcmp (sig->ret->data.generic_class->container_class->name, "Task`1")))) {
//printf ("X: %s\n", mono_method_full_name (method, TRUE));
- cattr = mono_custom_attrs_from_method (method);
+ cattr = mono_custom_attrs_from_method_checked (method, &error);
+ if (!is_ok (&error)) {
+ mono_error_cleanup (&error); /* FIXME don't swallow the error? */
+ return FALSE;
+ }
if (cattr) {
if (mono_custom_attrs_has_attr (cattr, attr_class))
res = TRUE;
MonoTypeEnum ttype;
if (!type->byref && type->type == MONO_TYPE_GENERICINST && MONO_TYPE_ISSTRUCT (type)) {
+ MonoError error;
MonoGenericClass *gclass = type->data.generic_class;
MonoGenericContext context;
MonoClass *k;
if (gclass->context.method_inst)
context.method_inst = get_shared_inst (gclass->context.method_inst, gclass->container_class->generic_container->context.method_inst, NULL, FALSE, FALSE, TRUE);
- k = mono_class_inflate_generic_class (gclass->container_class, &context);
+ k = mono_class_inflate_generic_class_checked (gclass->container_class, &context, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
return mini_get_shared_gparam (t, &k->byval_arg);
} else if (MONO_TYPE_ISSTRUCT (type)) {
case OP_CKFINITE:
/* Quiet NaN */
ia64_fclass_m (code, 6, 7, ins->sreg1, 0x080);
- emit_cond_system_exception (cfg, code, "ArithmeticException", 6);
+ emit_cond_system_exception (cfg, code, "OverflowException", 6);
/* Signaling NaN */
ia64_fclass_m (code, 6, 7, ins->sreg1, 0x040);
- emit_cond_system_exception (cfg, code, "ArithmeticException", 6);
+ emit_cond_system_exception (cfg, code, "OverflowException", 6);
/* Positive infinity */
ia64_fclass_m (code, 6, 7, ins->sreg1, 0x021);
- emit_cond_system_exception (cfg, code, "ArithmeticException", 6);
+ emit_cond_system_exception (cfg, code, "OverflowException", 6);
/* Negative infinity */
ia64_fclass_m (code, 6, 7, ins->sreg1, 0x022);
- emit_cond_system_exception (cfg, code, "ArithmeticException", 6);
+ emit_cond_system_exception (cfg, code, "OverflowException", 6);
break;
/* Calls */
mips_bne (code, mips_at, mips_zero, 0);
mips_nop (code);
- EMIT_SYSTEM_EXCEPTION_NAME("ArithmeticException");
+ EMIT_SYSTEM_EXCEPTION_NAME("OverflowException");
mips_patch (branch_patch, (guint32)code);
mips_fmovd (code, ins->dreg, ins->sreg1);
break;
MONO_SIG_HANDLER_FUNC (static, sigprof_signal_handler)
{
- MonoThreadInfo *info;
int old_errno = errno;
int hp_save_index;
MONO_SIG_HANDLER_GET_CONTEXT;
mono_threads_add_async_job (info, MONO_SERVICE_REQUEST_SAMPLE);
mono_threads_pthread_kill (info, profiling_signal_in_use);
- } END_FOREACH_THREAD_SAFE;
+ } FOREACH_THREAD_SAFE_END
}
mono_thread_info_set_is_async_context (TRUE);
mono_counters_register ("JIT/linear_scan (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_linear_scan);
mono_counters_register ("JIT/arch_allocate_vars (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_arch_allocate_vars);
mono_counters_register ("JIT/spill_global_vars (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_spill_global_vars);
- mono_counters_register ("JIT/jit_local_cprop3 (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_local_cprop3);
- mono_counters_register ("JIT/jit_local_deadce3 (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_local_deadce3);
+ mono_counters_register ("JIT/local_cprop3 (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_local_cprop3);
+ mono_counters_register ("JIT/local_deadce3 (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_local_deadce3);
mono_counters_register ("JIT/codegen (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_codegen);
mono_counters_register ("JIT/create_jit_info (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_create_jit_info);
mono_counters_register ("JIT/gc_create_gc_map (sec)", MONO_COUNTER_JIT | MONO_COUNTER_DOUBLE, &mono_jit_stats.jit_gc_create_gc_map);
mono_call_inst_add_outarg_reg (cfg, call, dreg, ainfo->reg, TRUE);
} else {
+ MonoError error;
MonoMethodHeader *header;
int srcReg;
- header = mono_method_get_header (cfg->method);
+ header = mono_method_get_header_checked (cfg->method, &error);
+ mono_error_assert_ok (&error); /* FIXME don't swallow the error */
if ((cfg->flags & MONO_CFG_HAS_ALLOCA) || header->num_clauses)
srcReg = s390_r11;
else
s390_tcdb (code, ins->sreg1, 0, s390_r13, 0);
s390_jz (code, 0); CODEPTR(code, o);
mono_add_patch_info (cfg, code - cfg->native_code,
- MONO_PATCH_INFO_EXC, "ArithmeticException");
+ MONO_PATCH_INFO_EXC, "OverflowException");
s390_brasl (code, s390_r14,0);
PTRSLOT(code, o);
}
sparc_srl_imm (code, sparc_o7, 4, sparc_o7);
sparc_and_imm (code, FALSE, sparc_o7, 2047, sparc_o7);
sparc_cmp_imm (code, sparc_o7, 2047);
- EMIT_COND_SYSTEM_EXCEPTION (ins, sparc_be, "ArithmeticException");
+ EMIT_COND_SYSTEM_EXCEPTION (ins, sparc_be, "OverflowException");
#ifdef SPARCV9
sparc_fmovd (code, ins->sreg1, ins->dreg);
#else
x86_branch8 (code, X86_CC_NE, 0, FALSE);
x86_fstp (code, 0);
- EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, FALSE, "ArithmeticException");
+ EMIT_COND_SYSTEM_EXCEPTION (X86_CC_EQ, FALSE, "OverflowException");
x86_patch (br1, code);
break;
if (info->exception_type == MONO_EXCEPTION_METHOD_ACCESS)
mono_error_set_generic_error (&cfg->error, "System", "MethodAccessException", "%s", msg);
- else if (info->exception_type == info->exception_type == MONO_EXCEPTION_FIELD_ACCESS)
+ else if (info->exception_type == MONO_EXCEPTION_FIELD_ACCESS)
mono_error_set_generic_error (&cfg->error, "System", "FieldAccessException", "%s", msg);
else if (info->exception_type == MONO_EXCEPTION_UNVERIFIABLE_IL)
mono_error_set_generic_error (&cfg->error, "System.Security", "VerificationException", msg);
*/
ei->try_start = (guint8*)ei->try_start - cfg->backend->monitor_enter_adjustment;
}
- tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len];
+ if (ec->try_offset + ec->try_len < header->code_size)
+ tblock = cfg->cil_offset_to_bb [ec->try_offset + ec->try_len];
+ else
+ tblock = cfg->bb_exit;
+ if (G_UNLIKELY (cfg->verbose_level >= 4))
+ printf ("looking for end of try [%d, %d] -> %p (code size %d)\n", ec->try_offset, ec->try_len, tblock, header->code_size);
g_assert (tblock);
if (!tblock->native_offset) {
int j, end;
cfg = g_new0 (MonoCompile, 1);
cfg->method = method_to_compile;
- cfg->header = mono_method_get_header (cfg->method);
cfg->mempool = mono_mempool_new ();
cfg->opt = opts;
cfg->prof_options = mono_profiler_get_events ();
return cfg;
}
- header = cfg->header;
+ header = cfg->header = mono_method_get_header_checked (cfg->method, &cfg->error);
if (!header) {
- if (mono_loader_get_last_error ()) {
- mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
- mono_error_set_from_loader_error (&cfg->error);
- } else {
- mono_cfg_set_exception_invalid_program (cfg, g_strdup_printf ("Missing or incorrect header for method %s", cfg->method->name));
- }
+ mono_cfg_set_exception (cfg, MONO_EXCEPTION_MONO_ERROR);
if (MONO_METHOD_COMPILE_END_ENABLED ())
MONO_PROBE_METHOD_COMPILE_END (method, FALSE);
return cfg;
static gboolean
coverage_filter (MonoProfiler *prof, MonoMethod *method)
{
+ MonoError error;
MonoClass *klass;
MonoImage *image;
MonoAssembly *assembly;
}
COVERAGE_DEBUG(fprintf (stderr, " Handling coverage for %s\n", mono_method_get_name (method));)
- header = mono_method_get_header (method);
+ header = mono_method_get_header_checked (method, &error);
+ mono_error_cleanup (&error);
mono_method_header_get_code (header, &code_size, NULL);
void
sgen_clear_tlabs (void)
{
- SgenThreadInfo *info;
-
FOREACH_THREAD (info) {
/* A new TLAB will be allocated when the thread does its first allocation */
*info->tlab_start_addr = NULL;
*info->tlab_next_addr = NULL;
*info->tlab_temp_end_addr = NULL;
*info->tlab_real_end_addr = NULL;
- } END_FOREACH_THREAD
+ } FOREACH_THREAD_END
}
void
{
#ifndef SGEN_WITHOUT_MONO
int j;
- SgenThreadInfo *info;
char *endobj = obj + size;
FOREACH_THREAD (info) {
if (w >= (mword)obj && w < (mword)obj + size)
SGEN_LOG (0, "Object %p referenced in saved reg %d of thread %p (id %p)", obj, j, info, (gpointer)mono_thread_info_get_tid (info));
- } END_FOREACH_THREAD
- }
+ }
+ } FOREACH_THREAD_END
#endif
}
class Test {
static int sum = 0;
+ static int count = 0;
static void async_callback (IAsyncResult ar)
{
byte [] buf = (byte [])ar.AsyncState;
- sum += buf [0];
+ Interlocked.Add (ref sum, buf [0]);
+ Interlocked.Increment (ref count);
}
static int Main () {
AsyncCallback ac = new AsyncCallback (async_callback);
IAsyncResult ar;
int sum0 = 0;
+ int count0 = 0;
FileStream s = new FileStream ("async_read.exe", FileMode.Open, FileAccess.Read);
s.Position = 0;
- sum0 = 0;
- while (s.Read (buf, 0, 1) == 1)
+ while (s.Read (buf, 0, 1) == 1) {
sum0 += buf [0];
+ count0 ++;
+ }
s.Position = 0;
buf = new byte [1];
ar = s.BeginRead (buf, 0, 1, ac, buf);
} while (s.EndRead (ar) == 1);
- sum -= buf [0];
Thread.Sleep (100);
s.Close ();
+ count0 ++; // async_callback is invoked for the "finished reading" case too
Console.WriteLine ("CSUM: " + sum + " " + sum0);
- if (sum != sum0)
+ Console.WriteLine ("Count: " + count + " " + count0);
+ if (sum != sum0 || count != count0)
return 1;
return 0;
break;
case STATE_OUT:
if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_OUT) == STATE_OUT) {
- result = mono_lls_find (&lls, hp, i);
+ result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
assert (!result);
mono_hazard_pointer_clear_all (hp, -1);
- result = mono_lls_insert (&lls, hp, &nodes [i].node);
+ result = mono_lls_insert (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
mono_hazard_pointer_clear_all (hp, -1);
assert (nodes [i].state == STATE_BUSY);
break;
case STATE_IN:
if (InterlockedCompareExchange (&nodes [i].state, STATE_BUSY, STATE_IN) == STATE_IN) {
- result = mono_lls_find (&lls, hp, i);
+ result = mono_lls_find (&lls, hp, i, HAZARD_FREE_SAFE_CTX);
assert (result);
assert (mono_hazard_pointer_get_val (hp, 1) == &nodes [i].node);
mono_hazard_pointer_clear_all (hp, -1);
- result = mono_lls_remove (&lls, hp, &nodes [i].node);
+ result = mono_lls_remove (&lls, hp, &nodes [i].node, HAZARD_FREE_SAFE_CTX);
mono_hazard_pointer_clear_all (hp, -1);
++thread_data->num_removes;
mono_threads_init (&thread_callbacks, 0);
- mono_lls_init (&lls, free_node);
+ mono_lls_init (&lls, free_node, HAZARD_FREE_NO_LOCK);
for (i = 0; i < N; ++i) {
nodes [i].node.key = i;
typedef struct {
gpointer p;
MonoHazardousFreeFunc free_func;
- gboolean might_lock;
+ HazardFreeLocking locking;
} DelayedFreeItem;
/* The hazard table */
}
static gboolean
-try_free_delayed_free_item (gboolean lock_free_context)
+try_free_delayed_free_item (HazardFreeContext context)
{
DelayedFreeItem item;
gboolean popped = mono_lock_free_array_queue_pop (&delayed_free_queue, &item);
if (!popped)
return FALSE;
- if ((lock_free_context && item.might_lock) || (is_pointer_hazardous (item.p))) {
+ if ((context == HAZARD_FREE_ASYNC_CTX && item.locking == HAZARD_FREE_MAY_LOCK) ||
+ (is_pointer_hazardous (item.p))) {
mono_lock_free_array_queue_push (&delayed_free_queue, &item);
return FALSE;
}
void
mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func,
- gboolean free_func_might_lock, gboolean lock_free_context)
+ HazardFreeLocking locking, HazardFreeContext context)
{
int i;
- if (lock_free_context)
- g_assert (!free_func_might_lock);
- if (free_func_might_lock)
- g_assert (!lock_free_context);
-
/* First try to free a few entries in the delayed free
table. */
for (i = 0; i < 3; ++i)
- try_free_delayed_free_item (lock_free_context);
+ try_free_delayed_free_item (context);
/* Now see if the pointer we're freeing is hazardous. If it
isn't, free it. Otherwise put it in the delay list. */
- if (is_pointer_hazardous (p)) {
- DelayedFreeItem item = { p, free_func, free_func_might_lock };
+ if ((context == HAZARD_FREE_ASYNC_CTX && locking == HAZARD_FREE_MAY_LOCK) ||
+ is_pointer_hazardous (p)) {
+ DelayedFreeItem item = { p, free_func, locking };
++hazardous_pointer_count;
void
mono_thread_hazardous_try_free_all (void)
{
- while (try_free_delayed_free_item (FALSE))
+ while (try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX))
;
}
{
int i;
for (i = 0; i < 10; ++i)
- try_free_delayed_free_item (FALSE);
+ try_free_delayed_free_item (HAZARD_FREE_SAFE_CTX);
}
void
typedef void (*MonoHazardousFreeFunc) (gpointer p);
+typedef enum {
+ HAZARD_FREE_MAY_LOCK,
+ HAZARD_FREE_NO_LOCK,
+} HazardFreeLocking;
+
+typedef enum {
+ HAZARD_FREE_SAFE_CTX,
+ HAZARD_FREE_ASYNC_CTX,
+} HazardFreeContext;
+
void mono_thread_hazardous_free_or_queue (gpointer p, MonoHazardousFreeFunc free_func,
- gboolean free_func_might_lock, gboolean lock_free_context);
+ HazardFreeLocking locking, HazardFreeContext context);
void mono_thread_hazardous_try_free_all (void);
void mono_thread_hazardous_try_free_some (void);
MonoThreadHazardPointers* mono_hazard_pointer_get (void);
g_assert (desc->in_use);
desc->in_use = FALSE;
free_sb (desc->sb, desc->block_size);
- mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, FALSE, TRUE);
+ mono_thread_hazardous_free_or_queue (desc, desc_enqueue_avail, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
}
#else
MonoLockFreeQueue available_descs;
list_put_partial (Descriptor *desc)
{
g_assert (desc->anchor.data.state != STATE_FULL);
- mono_thread_hazardous_free_or_queue (desc, desc_put_partial, FALSE, TRUE);
+ mono_thread_hazardous_free_or_queue (desc, desc_put_partial, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
}
static void
desc_retire (desc);
} else {
g_assert (desc->heap->sc == sc);
- mono_thread_hazardous_free_or_queue (desc, desc_put_partial, FALSE, TRUE);
+ mono_thread_hazardous_free_or_queue (desc, desc_put_partial, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
if (++num_non_empty >= 2)
return;
}
g_assert (q->has_dummy);
q->has_dummy = 0;
mono_memory_write_barrier ();
- mono_thread_hazardous_free_or_queue (head, free_dummy, FALSE, TRUE);
+ mono_thread_hazardous_free_or_queue (head, free_dummy, HAZARD_FREE_NO_LOCK, HAZARD_FREE_ASYNC_CTX);
if (try_reenqueue_dummy (q))
goto retry;
return NULL;
static void
conc_table_lf_free (conc_table *table)
{
- mono_thread_hazardous_free_or_queue (table, conc_table_free, TRUE, FALSE);
+ mono_thread_hazardous_free_or_queue (table, conc_table_free, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
}
void
mono_loader_set_error_from_mono_error (MonoError *oerror);
+void
+mono_error_move (MonoError *dest, MonoError *src);
+
#endif
mono_error_cleanup (target_error);
return ex;
}
+
+void
+mono_error_move (MonoError *dest, MonoError *src)
+{
+ memcpy (dest, src, sizeof (MonoErrorInternal));
+ mono_error_init (src);
+}
/*
Initialize @list and will use @free_node_func to release memory.
If @free_node_func is null the caller is responsible for releasing node memory.
-@free_node_func must be lock-free. That implies that it cannot use malloc/free.
+If @free_node_func may lock, @free_node_func_locking must be
+HAZARD_FREE_MAY_LOCK; otherwise, HAZARD_FREE_NO_LOCK. It is ignored if
+@free_node_func is null.
*/
void
-mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *))
+mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking)
{
list->head = NULL;
list->free_node_func = free_node_func;
+ list->locking = free_node_func_locking;
}
/*
Search @list for element with key @key.
+@context specifies whether the function is being called from a lock-free (i.e.
+signal handler or world stopped) context. It is only relevant if a node free
+function was given.
The nodes next, cur and prev are returned in @hp.
Returns true if a node with key @key was found.
-This function cannot be called from a signal nor within interrupt context*.
-XXX A variant that works within interrupted is possible if needed.
-
-* interrupt context is when the current thread is reposible for another thread
-been suspended at an arbritary point. This is a limitation of our SMR implementation.
*/
gboolean
-mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key)
+mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context)
{
MonoLinkedListSetNode *cur, *next;
MonoLinkedListSetNode **prev;
mono_memory_write_barrier ();
mono_hazard_pointer_clear (hp, 1);
if (list->free_node_func)
- mono_thread_hazardous_free_or_queue (cur, list->free_node_func, FALSE, TRUE);
+ mono_thread_hazardous_free_or_queue (cur, list->free_node_func, list->locking, context);
} else
goto try_again;
}
/*
Insert @value into @list.
+@context specifies whether the function is being called from a lock-free (i.e.
+signal handler or world stopped) context. It is only relevant if a node free
+function was given.
The nodes value, cur and prev are returned in @hp.
Return true if @value was inserted by this call. If it returns FALSE, it's the caller
resposibility to release memory.
-This function cannot be called from a signal nor with the world stopped.
*/
gboolean
-mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
+mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
{
MonoLinkedListSetNode *cur, **prev;
/*We must do a store barrier before inserting
mono_memory_barrier ();
while (1) {
- if (mono_lls_find (list, hp, value->key))
+ if (mono_lls_find (list, hp, value->key, context))
return FALSE;
cur = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 1);
prev = (MonoLinkedListSetNode **) mono_hazard_pointer_get_val (hp, 2);
}
/*
-Search @list for element with key @key.
+Search @list for element with key @key and remove it.
+@context specifies whether the function is being called from a lock-free (i.e.
+signal handler or world stopped) context. It is only relevant if a node free
+function was given.
The nodes next, cur and prev are returned in @hp
Returns true if @value was removed by this call.
-This function cannot be called from a signal nor with the world stopped.
*/
gboolean
-mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value)
+mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context)
{
MonoLinkedListSetNode *cur, **prev, *next;
while (1) {
- if (!mono_lls_find (list, hp, value->key))
+ if (!mono_lls_find (list, hp, value->key, context))
return FALSE;
next = (MonoLinkedListSetNode *) mono_hazard_pointer_get_val (hp, 0);
mono_memory_write_barrier ();
mono_hazard_pointer_clear (hp, 1);
if (list->free_node_func)
- mono_thread_hazardous_free_or_queue (value, list->free_node_func, FALSE, TRUE);
+ mono_thread_hazardous_free_or_queue (value, list->free_node_func, list->locking, context);
} else
- mono_lls_find (list, hp, value->key);
+ mono_lls_find (list, hp, value->key, context);
return TRUE;
}
}
typedef struct {
MonoLinkedListSetNode *head;
void (*free_node_func)(void *);
+ HazardFreeLocking locking;
} MonoLinkedListSet;
*/
void
-mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *));
+mono_lls_init (MonoLinkedListSet *list, void (*free_node_func)(void *), HazardFreeLocking free_node_func_locking);
gboolean
-mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key);
+mono_lls_find (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, uintptr_t key, HazardFreeContext context);
gboolean
-mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value);
+mono_lls_insert (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context);
gboolean
-mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value);
+mono_lls_remove (MonoLinkedListSet *list, MonoThreadHazardPointers *hp, MonoLinkedListSetNode *value, HazardFreeContext context);
gpointer
get_hazardous_pointer_with_mask (gpointer volatile *pp, MonoThreadHazardPointers *hp, int hazard_index);
-/*
-Requires the world to be stoped
-*/
-#define MONO_LLS_FOREACH(list, element, type) {\
- MonoLinkedListSetNode *__cur; \
- for (__cur = (list)->head; __cur; __cur = mono_lls_pointer_unmask (__cur->next)) \
- if (!mono_lls_pointer_get_mark (__cur->next)) { \
- (element) = (type)__cur;
-
-
-#define MONO_LLS_FOREACH_FILTERED(list, element, filter_func, type) {\
- MonoLinkedListSetNode *__cur; \
- for (__cur = (list)->head; __cur; __cur = (MonoLinkedListSetNode *)mono_lls_pointer_unmask (__cur->next)) \
- if (!mono_lls_pointer_get_mark (__cur->next)) { \
- (element) = (type)__cur; \
- if (!filter_func (element)) continue;
-
-#define MONO_LLS_END_FOREACH }}
-
-static inline MonoLinkedListSetNode*
-mono_lls_info_step (MonoLinkedListSetNode *val, MonoThreadHazardPointers *hp)
+static inline gboolean
+mono_lls_filter_accept_all (gpointer elem)
{
- val = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (val);
- mono_hazard_pointer_set (hp, 1, val);
- return val;
+ return TRUE;
}
/*
-Provides snapshot iteration
-*/
-#define MONO_LLS_FOREACH_SAFE(list, element, type) {\
- MonoThreadHazardPointers *__hp = mono_hazard_pointer_get (); \
- MonoLinkedListSetNode *__cur, *__next; \
- for (__cur = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (get_hazardous_pointer ((gpointer volatile*)&(list)->head, __hp, 1)); \
- __cur; \
- __cur = (MonoLinkedListSetNode *) mono_lls_info_step (__next, __hp)) { \
- __next = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer volatile*)&__cur->next, __hp, 0); \
- if (!mono_lls_pointer_get_mark (__next)) { \
- (element) = (type)__cur;
-
-#define MONO_LLS_FOREACH_FILTERED_SAFE(list, element, filter_func, type) {\
- MonoThreadHazardPointers *__hp = mono_hazard_pointer_get (); \
- MonoLinkedListSetNode *__cur, *__next; \
- for (__cur = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (get_hazardous_pointer ((gpointer volatile*)&(list)->head, __hp, 1)); \
- __cur; \
- __cur = (MonoLinkedListSetNode *) mono_lls_info_step (__next, __hp)) { \
- __next = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer volatile*)&__cur->next, __hp, 0); \
- if (!mono_lls_pointer_get_mark (__next)) { \
- (element) = (type)__cur; \
- if (!filter_func (element)) continue;
-
-
-#define MONO_LLS_END_FOREACH_SAFE \
+ * These macros assume that no other threads are actively modifying the list.
+ */
+
+#define MONO_LLS_FOREACH_FILTERED(list, type, elem, filter) \
+ do { \
+ MonoLinkedListSet *list__ = (list); \
+ for (MonoLinkedListSetNode *cur__ = list__->head; cur__; cur__ = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (cur__->next)) { \
+ if (!mono_lls_pointer_get_mark (cur__->next)) { \
+ type *elem = (type *) cur__; \
+ if (filter (elem)) {
+
+#define MONO_LLS_FOREACH_END \
+ } \
+ } \
} \
- } \
- mono_hazard_pointer_clear (__hp, 0); \
- mono_hazard_pointer_clear (__hp, 1); \
-}
+ } while (0);
+
+#define MONO_LLS_FOREACH(list, type, elem) \
+ MONO_LLS_FOREACH_FILTERED ((list), type, elem, mono_lls_filter_accept_all)
+
+/*
+ * These macros can be used while other threads are potentially modifying the
+ * list, but they only provide a snapshot of the list as a result.
+ *
+ * NOTE: Do NOT break out of the loop through any other means than a break
+ * statement, as other ways of breaking the loop will skip past important
+ * cleanup work.
+ */
+
+#define MONO_LLS_FOREACH_FILTERED_SAFE(list, type, elem, filter) \
+ do { \
+ /* NOTE: Keep this macro's code in sync with the mono_lls_find () logic. */ \
+ MonoLinkedListSet *list__ = (list); \
+ MonoThreadHazardPointers *hp__ = mono_hazard_pointer_get (); \
+ gboolean progress__ = FALSE; \
+ uintptr_t hkey__; \
+ gboolean restart__; \
+ do { \
+ restart__ = FALSE; \
+ MonoLinkedListSetNode **prev__ = &list__->head; \
+ mono_hazard_pointer_set (hp__, 2, prev__); \
+ MonoLinkedListSetNode *cur__ = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer *) prev__, hp__, 1); \
+ while (1) { \
+ if (!cur__) { \
+ break; \
+ } \
+ MonoLinkedListSetNode *next__ = (MonoLinkedListSetNode *) get_hazardous_pointer_with_mask ((gpointer *) &cur__->next, hp__, 0); \
+ uintptr_t ckey__ = cur__->key; \
+ mono_memory_read_barrier (); \
+ if (*prev__ != cur__) { \
+ restart__ = TRUE; \
+ break; \
+ } \
+ if (!mono_lls_pointer_get_mark (next__)) { \
+ if (!progress__ || ckey__ > hkey__) { \
+ progress__ = TRUE; \
+ hkey__ = ckey__; \
+ type *elem = (type *) cur__; \
+ if (filter (elem)) { \
+ gboolean broke__ = TRUE; \
+ gboolean done__ = FALSE; \
+ do { \
+ if (done__) { \
+ broke__ = FALSE; \
+ break; \
+ } \
+ done__ = TRUE;
+
+#define MONO_LLS_FOREACH_SAFE_END \
+ broke__ = FALSE; \
+ break; \
+ } while (1); \
+ if (broke__) { \
+ break; \
+ } \
+ } \
+ } \
+ prev__ = &cur__->next; \
+ mono_hazard_pointer_set (hp__, 2, cur__); \
+ } else { \
+ next__ = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (next__); \
+ if (InterlockedCompareExchangePointer ((volatile gpointer *) prev__, next__, cur__) == cur__) { \
+ mono_memory_write_barrier (); \
+ mono_hazard_pointer_clear (hp__, 1); \
+ if (list__->free_node_func) { \
+ mono_thread_hazardous_free_or_queue (cur__, list__->free_node_func, list__->locking, HAZARD_FREE_ASYNC_CTX); \
+ } \
+ } else { \
+ restart__ = TRUE; \
+ break; \
+ } \
+ } \
+ cur__ = (MonoLinkedListSetNode *) mono_lls_pointer_unmask (next__); \
+ mono_hazard_pointer_set (hp__, 1, cur__); \
+ } \
+ } while (restart__); \
+ mono_hazard_pointer_clear (hp__, 0); \
+ mono_hazard_pointer_clear (hp__, 1); \
+ mono_hazard_pointer_clear (hp__, 2); \
+ } while (0);
+
+#define MONO_LLS_FOREACH_SAFE(list, type, elem) \
+ MONO_LLS_FOREACH_FILTERED_SAFE ((list), type, elem, mono_lls_filter_accept_all)
#endif /* __MONO_SPLIT_ORDERED_LIST_H__ */
static void
dump_threads (void)
{
- MonoThreadInfo *info;
MonoThreadInfo *cur = mono_thread_info_current ();
MOSTLY_ASYNC_SAFE_PRINTF ("STATE CUE CARD: (? means a positive number, usually 1 or 2, * means any number)\n");
#else
MOSTLY_ASYNC_SAFE_PRINTF ("--thread %p id %p [%p] state %x %s\n", info, (void *) mono_thread_info_get_tid (info), (void*)(size_t)info->native_handle, info->thread_state, info == cur ? "GC INITIATOR" : "" );
#endif
-
- } END_FOREACH_THREAD_SAFE
+ } FOREACH_THREAD_SAFE_END
}
gboolean
{
MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
- if (!mono_lls_find (&thread_list, hp, (uintptr_t)id)) {
+ if (!mono_lls_find (&thread_list, hp, (uintptr_t)id, HAZARD_FREE_ASYNC_CTX)) {
mono_hazard_pointer_clear_all (hp, -1);
return NULL;
}
{
MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
- if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info)) {
+ if (!mono_lls_insert (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX)) {
mono_hazard_pointer_clear_all (hp, -1);
return FALSE;
}
gboolean res;
THREADS_DEBUG ("removing info %p\n", info);
- res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info);
+ res = mono_lls_remove (&thread_list, hp, (MonoLinkedListSetNode*)info, HAZARD_FREE_SAFE_CTX);
mono_hazard_pointer_clear_all (hp, -1);
return res;
}
g_byte_array_free (info->stackdata, /*free_segment=*/TRUE);
/*now it's safe to free the thread info.*/
- mono_thread_hazardous_free_or_queue (info, free_thread_info, TRUE, FALSE);
+ mono_thread_hazardous_free_or_queue (info, free_thread_info, HAZARD_FREE_MAY_LOCK, HAZARD_FREE_SAFE_CTX);
mono_thread_small_id_free (small_id);
}
mono_coop_sem_init (&global_suspend_semaphore, 1);
mono_os_sem_init (&suspend_semaphore, 0);
- mono_lls_init (&thread_list, NULL);
+ mono_lls_init (&thread_list, NULL, HAZARD_FREE_NO_LOCK);
mono_thread_smr_init ();
mono_threads_init_platform ();
mono_threads_init_coop ();
static inline guint32
sleep_interruptable (guint32 ms, gboolean *alerted)
{
- guint32 start, now, end;
+ gint64 now, end;
g_assert (INFINITE == G_MAXUINT32);
g_assert (alerted);
*alerted = FALSE;
- start = mono_msec_ticks ();
-
- if (start < G_MAXUINT32 - ms) {
- end = start + ms;
- } else {
- /* start + ms would overflow guint32 */
- end = G_MAXUINT32;
- }
+ if (ms != INFINITE)
+ end = mono_100ns_ticks () + (ms * 1000 * 10);
mono_lazy_initialize (&sleep_init, sleep_initialize);
mono_coop_mutex_lock (&sleep_mutex);
- for (now = mono_msec_ticks (); ms == INFINITE || now - start < ms; now = mono_msec_ticks ()) {
+ for (;;) {
+ if (ms != INFINITE) {
+ now = mono_100ns_ticks ();
+ if (now > end)
+ break;
+ }
+
mono_thread_info_install_interrupt (sleep_interrupt, NULL, alerted);
if (*alerted) {
mono_coop_mutex_unlock (&sleep_mutex);
return WAIT_IO_COMPLETION;
}
- if (ms < INFINITE)
- mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, end - now);
+ if (ms != INFINITE)
+ mono_coop_cond_timedwait (&sleep_cond, &sleep_mutex, (end - now) / 10 / 1000);
else
mono_coop_cond_wait (&sleep_cond, &sleep_mutex);
/*
Requires the world to be stoped
*/
-#define FOREACH_THREAD(thread) MONO_LLS_FOREACH_FILTERED (mono_thread_info_list_head (), thread, mono_threads_filter_tools_threads, THREAD_INFO_TYPE*)
-#define END_FOREACH_THREAD MONO_LLS_END_FOREACH
+#define FOREACH_THREAD(thread) \
+ MONO_LLS_FOREACH_FILTERED (mono_thread_info_list_head (), THREAD_INFO_TYPE, thread, mono_threads_filter_tools_threads)
+
+#define FOREACH_THREAD_END \
+ MONO_LLS_FOREACH_END
/*
Snapshot iteration.
*/
-#define FOREACH_THREAD_SAFE(thread) MONO_LLS_FOREACH_FILTERED_SAFE (mono_thread_info_list_head (), thread, mono_threads_filter_tools_threads, THREAD_INFO_TYPE*)
-#define END_FOREACH_THREAD_SAFE MONO_LLS_END_FOREACH_SAFE
+#define FOREACH_THREAD_SAFE(thread) \
+ MONO_LLS_FOREACH_FILTERED_SAFE (mono_thread_info_list_head (), THREAD_INFO_TYPE, thread, mono_threads_filter_tools_threads)
+
+#define FOREACH_THREAD_SAFE_END \
+ MONO_LLS_FOREACH_SAFE_END
static inline MonoNativeThreadId
mono_thread_info_get_tid (THREAD_INFO_TYPE *info)
mono_jit_set_aot_only
mono_jit_set_trace_options
mono_jit_thread_attach
+mono_jit_thread_detach
mono_ldstr
mono_ldtoken
mono_load_remote_field
mono_metadata_parse_param
mono_metadata_parse_signature
mono_metadata_parse_type
-mono_metadata_parse_type_full
mono_metadata_parse_typedef_or_ref
mono_metadata_properties_from_typedef
mono_metadata_signature_alloc
mono_method_get_flags
mono_method_get_generic_container
mono_method_get_header
+mono_method_get_header_checked
mono_method_get_index
mono_method_get_last_managed
mono_method_get_marshal_info
mono_jit_set_aot_only
mono_jit_set_trace_options
mono_jit_thread_attach
+mono_jit_thread_detach
mono_ldstr
mono_ldtoken
mono_load_remote_field
mono_metadata_parse_param
mono_metadata_parse_signature
mono_metadata_parse_type
-mono_metadata_parse_type_full
mono_metadata_parse_typedef_or_ref
mono_metadata_properties_from_typedef
mono_metadata_signature_alloc
mono_method_get_flags
mono_method_get_generic_container
mono_method_get_header
+mono_method_get_header_checked
mono_method_get_index
mono_method_get_last_managed
mono_method_get_marshal_info