* with newer runtimes, and vice versa.
*/
internal const int MAJOR_VERSION = 2;
- internal const int MINOR_VERSION = 23;
+ internal const int MINOR_VERSION = 24;
enum WPSuspendPolicy {
NONE = 0,
GET_INFO = 6,
GET_BODY = 7,
RESOLVE_TOKEN = 8,
- GET_CATTRS = 9
+ GET_CATTRS = 9,
+ MAKE_GENERIC_METHOD = 10
}
enum CmdType {
return ReadCattrs (r);
}
+ internal long Method_MakeGenericMethod (long id, long[] args) {
+ PacketReader r = SendReceive (CommandSet.METHOD, (int)CmdMethod.MAKE_GENERIC_METHOD, new PacketWriter ().WriteId (id).WriteInt (args.Length).WriteIds (args));
+ return r.ReadId ();
+ }
+
/*
* THREAD
*/
using System;
using System.Collections.Generic;
+using System.Linq;
using System.Text;
using System.Reflection;
using C = Mono.Cecil;
return type_args;
}
+ // Since protocol version 2.24
+ public MethodMirror MakeGenericMethod (TypeMirror[] args) {
+ if (args == null)
+ throw new ArgumentNullException ("args");
+ foreach (var a in args)
+ if (a == null)
+ throw new ArgumentNullException ("args");
+
+ if (!IsGenericMethodDefinition)
+ throw new InvalidOperationException ("not a generic method definition");
+
+ if (GetGenericArguments ().Length != args.Length)
+ throw new ArgumentException ("Incorrect length");
+
+ vm.CheckProtocolVersion (2, 24);
+ long id = -1;
+ try {
+ id = vm.conn.Method_MakeGenericMethod (Id, args.Select (t => t.Id).ToArray ());
+ } catch (CommandException) {
+ throw new InvalidOperationException ();
+ }
+ return vm.GetMethod (id);
+ }
+
public IList<int> ILOffsets {
get {
if (debug_info == null)
set_gc_suspend_field ();
gc_suspend_1 ();
}
+
+ [MethodImplAttribute (MethodImplOptions.NoInlining)]
+ public static void generic_method<T> () where T : class {
+ }
}
class TypeLoadClass {
var o2 = entry_point.DeclaringType.GetValue (entry_point.DeclaringType.GetField ("gc_suspend_field")) as ObjectMirror;
Assert.IsNull (o2);
}
+
+ [Test]
+ public void MakeGenericMethod () {
+ Event e = run_until ("bp1");
+
+ var intm = vm.RootDomain.GetCorrespondingType (typeof (int));
+ var stringm = vm.RootDomain.GetCorrespondingType (typeof (string));
+ var gm = entry_point.DeclaringType.GetMethod ("generic_method");
+ var res = gm.MakeGenericMethod (new TypeMirror [] { stringm });
+ var args = res.GetGenericArguments ();
+ Assert.AreEqual (1, args.Length);
+ Assert.AreEqual (stringm, args [0]);
+
+ // Error checking
+ AssertThrows<ArgumentNullException> (delegate {
+ gm.MakeGenericMethod (null);
+ });
+ AssertThrows<ArgumentNullException> (delegate {
+ gm.MakeGenericMethod (new TypeMirror [] { null });
+ });
+ AssertThrows<ArgumentException> (delegate {
+ gm.MakeGenericMethod (new TypeMirror [] { stringm, stringm });
+ });
+ AssertThrows<InvalidOperationException> (delegate {
+ gm.MakeGenericMethod (new TypeMirror [] { intm });
+ });
+ AssertThrows<InvalidOperationException> (delegate {
+ entry_point.DeclaringType.GetMethod ("Main").MakeGenericMethod (new TypeMirror [] { intm });
+ });
+ }
}
}
AssertException<ArgumentNullException> (delegate () { ((IEnumerable<string>) null).Contains ("2", (IEqualityComparer<string>) EqualityComparer<string>.Default); });
}
+ static void IsFalse(bool b, int[] data) {
+ if (b) {
+ Console.WriteLine (data.Contains (0));
+ object o = null;
+ o.ToString ();
+ Assert.IsFalse (true);
+ }
+ //Console.WriteLine ("HIT!");
+ }
+
[Test]
public void ContainsTest ()
{
int [] data = { 5, 2, 3, 1, 6 };
-
+ ICollection<int> icoll = data;
// Contains<TSource> (TSource)
Assert.IsTrue (data.Contains (2));
- Assert.IsFalse (data.Contains (0));
+ for (int i = 0; i < 50; ++i)
+ Console.WriteLine (icoll.Contains (0));//Console.WriteLine (data.Contains (0));
+ IsFalse (data.Contains (0), data);
// Contains<TSource> (TSource, IEqualityComparer<TSource>)
Assert.IsTrue (data.Contains (2, EqualityComparer<int>.Default));
T value;
GetGenericValueImpl (i, out value);
if (item == null){
- if (value == null)
+ if (value == null) {
return true;
+ }
continue;
}
-
- if (item.Equals (value))
+
+ if (item.Equals (value)) {
return true;
+ }
}
return false;
#include <mono/metadata/assembly.h>
#include <mono/metadata/runtime.h>
#include <mono/metadata/threadpool.h>
+#include <mono/metadata/verify-internals.h>
#include <mono/utils/mono-semaphore.h>
#include <mono/utils/mono-error-internals.h>
#include <mono/utils/mono-stack-unwinding.h>
#define HEADER_LENGTH 11
#define MAJOR_VERSION 2
-#define MINOR_VERSION 23
+#define MINOR_VERSION 24
typedef enum {
CMD_SET_VM = 1,
CMD_METHOD_GET_BODY = 7,
CMD_METHOD_RESOLVE_TOKEN = 8,
CMD_METHOD_GET_CATTRS = 9,
+ CMD_METHOD_MAKE_GENERIC_METHOD = 10
} CmdMethod;
typedef enum {
buffer_add_cattrs (buf, domain, method->klass->image, attr_klass, cinfo);
break;
}
+ case CMD_METHOD_MAKE_GENERIC_METHOD: {
+ MonoType **type_argv;
+ int i, type_argc;
+ MonoDomain *d;
+ MonoClass *klass;
+ MonoGenericInst *ginst;
+ MonoGenericContext tmp_context;
+ MonoMethod *inflated;
+
+ type_argc = decode_int (p, &p, end);
+ type_argv = g_new0 (MonoType*, type_argc);
+ for (i = 0; i < type_argc; ++i) {
+ klass = decode_typeid (p, &p, end, &d, &err);
+ if (err) {
+ g_free (type_argv);
+ return err;
+ }
+ if (domain != d) {
+ g_free (type_argv);
+ return ERR_INVALID_ARGUMENT;
+ }
+ type_argv [i] = &klass->byval_arg;
+ }
+ ginst = mono_metadata_get_generic_inst (type_argc, type_argv);
+ g_free (type_argv);
+ tmp_context.class_inst = method->klass->generic_class ? method->klass->generic_class->context.class_inst : NULL;
+ tmp_context.method_inst = ginst;
+
+ inflated = mono_class_inflate_generic_method (method, &tmp_context);
+ if (!mono_verifier_is_method_valid_generic_instantiation (inflated))
+ return ERR_INVALID_ARGUMENT;
+ buffer_add_methodid (buf, domain, inflated);
+ break;
+ }
default:
return ERR_NOT_IMPLEMENTED;
}