In metadata:
authorRobert Jordan <robertj@gmx.net>
Tue, 6 May 2008 19:45:47 +0000 (19:45 -0000)
committerRobert Jordan <robertj@gmx.net>
Tue, 6 May 2008 19:45:47 +0000 (19:45 -0000)
2008-05-05  Robert Jordan  <robertj@gmx.net>

* marshal.c (mono_marshal_get_thunk_invoke_wrapper):
support for value types. See #386415.

* object.c: comments.

In tests:
2008-05-05  Robert Jordan  <robertj@gmx.net>

* libtest.c, thunks.cs: reworked to match the new struct
handling.

svn path=/trunk/mono/; revision=102655

mono/metadata/ChangeLog
mono/metadata/marshal.c
mono/metadata/object.c
mono/tests/ChangeLog
mono/tests/libtest.c
mono/tests/thunks.cs

index 18bbddb27d4b9b68cd4910cd5d6427970cb51945..d835794a95f415e91d03aab225d07adfa4c1ad80 100644 (file)
@@ -1,3 +1,10 @@
+2008-05-05  Robert Jordan  <robertj@gmx.net>
+
+       * marshal.c (mono_marshal_get_thunk_invoke_wrapper):
+       support for value types. See #386415.
+
+       * object.c: comments.
+
 2008-05-05  Martin Baulig  <martin@ximian.com>
 
        * debug-mono-symfile.h
index 671ac376622dd22e139b6dff29a57b125e6961ab..cf0bbfd9b771af346dc9cf8e4893331365f02b8c 100644 (file)
@@ -12047,11 +12047,9 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        csig->call_convention = MONO_CALL_DEFAULT;
 
        if (sig->hasthis) {
-               /* "this" of value types is actually a ptr */
-               csig->params [0] = klass->valuetype
-                       ? &mono_ptr_class_get (&klass->byval_arg)->byval_arg
-                       : &klass->byval_arg;
-               /* shift params */
+               /* add "this" */
+               csig->params [0] = &klass->byval_arg;
+               /* move params up by one */
                for (i = 0; i < sig->param_count; i++)
                        csig->params [i + 1] = sig->params [i];
        }
@@ -12062,6 +12060,10 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        csig->params [param_count - 1]->byref = 1;
        csig->params [param_count - 1]->attrs = PARAM_ATTRIBUTE_OUT;
 
+       /* convert struct return to object */
+       if (MONO_TYPE_ISSTRUCT (sig->ret))
+               csig->ret = &mono_defaults.object_class->byval_arg;
+
        /* local 0 (temp for exception object) */
        mono_mb_add_local (mb, &mono_defaults.object_class->byval_arg);
 
@@ -12081,9 +12083,29 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        clause->try_offset = mono_mb_get_label (mb);
 
        /* push method's args */
-       for (i = 0; i < param_count - 1; i++)
+       for (i = 0; i < param_count - 1; i++) {
+               MonoType *type;
+               MonoClass *klass;
+
                mono_mb_emit_ldarg (mb, i);
 
+               /* get the byval type of the param */
+               klass = mono_class_from_mono_type (csig->params [i]);
+               type = &klass->byval_arg;
+
+               /* unbox struct args */
+               if (MONO_TYPE_ISSTRUCT (type)) {
+                       mono_mb_emit_op (mb, CEE_UNBOX, klass);
+
+                       /* byref args & and the "this" arg must remain a ptr.
+                          Otherwise make a copy of the value type */
+                       if (!(csig->params [i]->byref || (i == 0 && sig->hasthis)))
+                               mono_mb_emit_op (mb, CEE_LDOBJ, klass);
+
+                       csig->params [i] = &mono_defaults.object_class->byval_arg;
+               }
+       }
+
        /* call */
        if (method->flags & METHOD_ATTRIBUTE_VIRTUAL)
                mono_mb_emit_op (mb, CEE_CALLVIRT, method);
@@ -12115,9 +12137,14 @@ mono_marshal_get_thunk_invoke_wrapper (MonoMethod *method)
        mono_mb_patch_branch (mb, pos_leave);
        /* end-try */
 
-       if (!MONO_TYPE_IS_VOID (sig->ret))
+       if (!MONO_TYPE_IS_VOID (sig->ret)) {
                mono_mb_emit_ldloc (mb, 1);
 
+               /* box the return value */
+               if (MONO_TYPE_ISSTRUCT (sig->ret))
+                       mono_mb_emit_op (mb, CEE_BOX, mono_class_from_mono_type (sig->ret));
+       }
+
        mono_mb_emit_byte (mb, CEE_RET);
 
        res = mono_mb_create_and_cache (cache, method, mb, csig, param_count + 16);
index f095d5dbe0c66c2fb8e40de9df1b206f002d8d07..48b6b2cc6a0493f71030ebab7ad370c5ad52ee50 100644 (file)
@@ -2101,18 +2101,18 @@ mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **
  * The thunk's C signature closely matches the managed signature:
  *
  * C#: public bool Equals (object obj);
- * C:  typedef MonoBoolean (*Equals)(MonoObject *this,
- *             MonoObject *obj, MonoException **ex);
+ * C:  typedef MonoBoolean (*Equals)(MonoObject*,
+ *             MonoObject*, MonoException**);
  *
- * The "this" parameter must not be used with static methods:
+ * The 1st ("this") parameter must not be used with static methods:
  *
  * C#: public static bool ReferenceEquals (object a, object b);
- * C:  typedef MonoBoolean (*ReferenceEquals)(MonoObject *a, MonoObject *b,
- *             MonoException **ex);
+ * C:  typedef MonoBoolean (*ReferenceEquals)(MonoObject*, MonoObject*,
+ *             MonoException**);
  *
  * The last argument must be a non-null pointer of a MonoException* pointer.
  * It has "out" semantics. After invoking the thunk, *ex will be NULL if no
- * exception has been thrown in managed code. Otherwise, it will point
+ * exception has been thrown in managed code. Otherwise it will point
  * to the MonoException* caught by the thunk. In this case, the result of
  * the thunk is undefined:
  *
@@ -2128,8 +2128,18 @@ mono_runtime_invoke (MonoMethod *method, void *obj, void **params, MonoObject **
  * convention. This means that under Windows, C declarations must
  * contain the __stdcall attribute:
  *
- * C:  typedef MonoBoolean (__stdcall *Equals)(MonoObject *this,
- *             MonoObject *obj, MonoException **ex);
+ * C:  typedef MonoBoolean (__stdcall *Equals)(MonoObject*,
+ *             MonoObject*, MonoException**);
+ *
+ * LIMITATIONS
+ *
+ * Value type arguments and return values are treated as they were objects:
+ *
+ * C#: public static Rectangle Intersect (Rectangle a, Rectangle b);
+ * C:  typedef MonoObject* (*Intersect)(MonoObject*, MonoObject*, MonoException**);
+ *
+ * Arguments must be properly boxed upon trunk's invocation, while return
+ * values must be unboxed.
  */
 gpointer
 mono_method_get_unmanaged_thunk (MonoMethod *method)
index a0d85bc1cc3316947bb6b7e6c2d702b9427605c2..8310d003025a60129475ee5a51d44a7590804520 100644 (file)
@@ -1,3 +1,8 @@
+2008-05-05  Robert Jordan  <robertj@gmx.net>
+
+       * libtest.c, thunks.cs: reworked to match the new struct
+       handling.       
+       
 2008-05-06  Rodrigo Kumpera  <rkumpera@novell.com>
 
        * bug-382986.cs. bug-382986-lib.cs: Regression test for
index 206bf6fab25655b26071e29fde069af3a5100d57..fff46e1cf0fc88985fcca2e4d670b00cc716e599 100644 (file)
@@ -2903,20 +2903,17 @@ mono_test_marshal_ccw_itest (MonoComObject *pUnk)
  * mono_method_get_unmanaged_thunk tests
  */
 
-
-#define NATIVE_ALIGNMENT(type) G_STRUCT_OFFSET(struct { char c; type x; }, x)
-#ifdef __GNUC__
-#define MANAGED_ALIGNMENT __alignof__
+#if defined(__GNUC__) && defined(__i386__) && (defined(__linux__) || defined (__APPLE__))
+#define ALIGN(size) __attribute__ ((aligned(size)))
 #else
-#define MANAGED_ALIGNMENT NATIVE_ALIGNMENT
+#define ALIGN(size)
 #endif
 
-#define SAME_ALIGNMENT(type) (NATIVE_ALIGNMENT(type) == MANAGED_ALIGNMENT(type))
 
 /* thunks.cs:TestStruct */
 typedef struct _TestStruct {
        int A;
-       double B;
+       double B ALIGN(8);  /* align according to  mono's struct layout */
 } TestStruct;
 
 /* Searches for mono symbols in all loaded modules */
@@ -2933,12 +2930,12 @@ lookup_mono_symbol (char *symbol_name)
 /**
  * test_method_thunk:
  *
- * @id: the method number
+ * @test_id: the test number
  * @test_method_handle: MonoMethod* of the C# test method
  * @create_object_method_handle: MonoMethod* of thunks.cs:Test.CreateObject
  */
 STDCALL int 
-test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_method_handle)
+test_method_thunk (int test_id, gpointer test_method_handle, gpointer create_object_method_handle)
 {
        gpointer (*mono_method_get_unmanaged_thunk)(gpointer)
                = lookup_mono_symbol ("mono_method_get_unmanaged_thunk");
@@ -2949,6 +2946,9 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        char* (*mono_string_to_utf8)(gpointer)
                = lookup_mono_symbol ("mono_string_to_utf8");
 
+       gpointer (*mono_object_unbox)(gpointer)
+               = lookup_mono_symbol ("mono_object_unbox");
+
        gpointer test_method, ex = NULL;
        gpointer (STDCALL *CreateObject)(gpointer*);
 
@@ -2965,17 +2965,17 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
                return 3;
 
 
-       switch (id) {
+       switch (test_id) {
 
        case 0: {
-               /* thunks.cs:Test.Foo0 */
+               /* thunks.cs:Test.Test0 */
                void (STDCALL *F)(gpointer*) = test_method;
                F (&ex);
                break;
        }
 
        case 1: {
-               /* thunks.cs:Test.Foo1 */
+               /* thunks.cs:Test.Test1 */
                int (STDCALL *F)(gpointer*) = test_method;
                if (F (&ex) != 42)
                        return 4;
@@ -2983,7 +2983,7 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 2: {
-               /* thunks.cs:Test.Foo2 */
+               /* thunks.cs:Test.Test2 */
                gpointer (STDCALL *F)(gpointer, gpointer*) = test_method;
                gpointer str = mono_string_new_wrapper ("foo");
                if (str != F (str, &ex))
@@ -2992,7 +2992,7 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 3: {
-               /* thunks.cs:Test.Foo3 */
+               /* thunks.cs:Test.Test3 */
                gpointer (STDCALL *F)(gpointer, gpointer, gpointer*);
                gpointer obj;
                gpointer str;
@@ -3007,7 +3007,7 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 4: {
-               /* thunks.cs:Test.Foo4 */
+               /* thunks.cs:Test.Test4 */
                int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
                gpointer obj;
                gpointer str;
@@ -3023,7 +3023,7 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 5: {
-               /* thunks.cs:Test.Foo5 */
+               /* thunks.cs:Test.Test5 */
                int (STDCALL *F)(gpointer, gpointer, int, gpointer*);
                gpointer obj;
                gpointer str;
@@ -3040,11 +3040,11 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 6: {
-               /* thunks.cs:Test.Foo6 */
+               /* thunks.cs:Test.Test6 */
                int (STDCALL *F)(gpointer, guint8, gint16, gint32, gint64, float, double,
                                 gpointer, gpointer*);
                gpointer obj;
-               gpointer str = mono_string_new_wrapper ("Foo6");
+               gpointer str = mono_string_new_wrapper ("Test6");
                int res;
 
                F = test_method;
@@ -3061,7 +3061,7 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 7: {
-               /* thunks.cs:Test.Foo7 */
+               /* thunks.cs:Test.Test7 */
                gint64 (STDCALL *F)(gpointer*) = test_method;
                if (F (&ex) != G_MAXINT64)
                        return 4;
@@ -3069,7 +3069,7 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 8: {
-               /* thunks.cs:Test.Foo8 */
+               /* thunks.cs:Test.Test8 */
                void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
                                 gpointer*, gpointer*);
 
@@ -3093,14 +3093,14 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
                      a4 == 6789600 &&
                      (fabs (a5 - 3.1415) < 0.001) &&
                      (fabs (a6 - 3.1415) < 0.001) &&
-                     strcmp (mono_string_to_utf8 (a7), "Foo8") == 0))
+                     strcmp (mono_string_to_utf8 (a7), "Test8") == 0))
                        return 5;
 
                break;
        }
 
        case 9: {
-               /* thunks.cs:Test.Foo9 */
+               /* thunks.cs:Test.Test9 */
                void (STDCALL *F)(guint8*, gint16*, gint32*, gint64*, float*, double*,
                                 gpointer*, gpointer*);
 
@@ -3122,100 +3122,157 @@ test_method_thunk (int id, gpointer test_method_handle, gpointer create_object_m
        }
 
        case 10: {
-               /* thunks.cs:Test.Foo10 */
-               int (STDCALL *F)(TestStruct, gpointer*);
+               /* thunks.cs:Test.Test10 */
+               void (STDCALL *F)(gpointer*, gpointer*);
 
-               TestStruct a1;
-               int res;
+               gpointer obj1, obj2;
 
-               if (!SAME_ALIGNMENT (double))
-                       break;
-
-               a1.A = 42;
-               a1.B = 3.1415;
+               obj1 = obj2 = CreateObject (&ex);
+               if (ex)
+                       return 4;
 
                F = test_method;
 
-               res = F (a1, &ex);
+               F (&obj1, &ex);
                if (ex)
-                       return 4;
-
-               if (!res)
                        return 5;
 
+               if (obj1 == obj2)
+                       return 6;
+
                break;
        }
 
-       case 11: {
-               /* thunks.cs:Test.Foo11 */
-               void (STDCALL *F)(TestStruct*, gpointer*);
+       case 100: {
+               /* thunks.cs:TestStruct.Test0 */
+               int (STDCALL *F)(gpointer*, gpointer*);
 
-               TestStruct a1;
+               gpointer obj;
+               TestStruct *a1;
+               int res;
 
-               if (!SAME_ALIGNMENT (double))
-                       break;
+               obj = CreateObject (&ex);
+               if (ex)
+                       return 4;
+
+               if (!obj)
+                       return 5;
+
+               a1 = mono_object_unbox (obj);
+               if (!a1)
+                       return 6;
+
+               a1->A = 42;
+               a1->B = 3.1415;
 
                F = test_method;
 
-               F (&a1, &ex);
+               res = F (obj, &ex);
+               if (ex)
+                       return 7;
+
+               if (!res)
+                       return 8;
+
+               /* check whether the call was really by value */
+               if (a1->A != 42 || a1->B != 3.1415)
+                       return 9;
+
+               break;
+       }
+
+       case 101: {
+               /* thunks.cs:TestStruct.Test1 */
+               void (STDCALL *F)(gpointer, gpointer*);
+
+               TestStruct *a1;
+               gpointer obj;
+
+               obj = CreateObject (&ex);
                if (ex)
                        return 4;
 
-               if (!a1.A == 42)
+               if (!obj)
                        return 5;
 
-               if (!fabs (a1.B - 3.1415) < 0.001)
+               a1 = mono_object_unbox (obj);
+               if (!a1)
                        return 6;
 
+               F = test_method;
+
+               F (obj, &ex);
+               if (ex)
+                       return 7;
+
+               if (a1->A != 42)
+                       return 8;
+
+               if (!fabs (a1->B - 3.1415) < 0.001)
+                       return 9;
+
                break;
        }
 
-       case 12: {
-               /* thunks.cs:Test.Foo12 */
-               TestStruct (STDCALL *F)(gpointer*);
+       case 102: {
+               /* thunks.cs:TestStruct.Test2 */
+               gpointer (STDCALL *F)(gpointer*);
 
-               TestStruct a1;
-
-               if (!SAME_ALIGNMENT (double))
-                       break;
+               TestStruct *a1;
+               gpointer obj;
 
                F = test_method;
 
-               a1 = F (&ex);
+               obj = F (&ex);
                if (ex)
                        return 4;
 
-               if (!a1.A == 42)
+               if (!obj)
                        return 5;
 
-               if (!fabs (a1.B - 3.1415) < 0.001)
+               a1 = mono_object_unbox (obj);
+
+               if (a1->A != 42)
+                       return 5;
+
+               if (!fabs (a1->B - 3.1415) < 0.001)
                        return 6;
 
                break;
        }
 
-       case 13: {
-               /* thunks.cs:TestStruct.Foo13 */
-               void (STDCALL *F)(TestStruct*, gpointer*);
+       case 103: {
+               /* thunks.cs:TestStruct.Test3 */
+               void (STDCALL *F)(gpointer, gpointer*);
 
-               TestStruct a1;
+               TestStruct *a1;
+               gpointer obj;
 
-               if (!SAME_ALIGNMENT (double))
-                       break;
+               obj = CreateObject (&ex);
+               if (ex)
+                       return 4;
+
+               if (!obj)
+                       return 5;
+               
+               a1 = mono_object_unbox (obj);
+
+               if (!a1)
+                       return 6;
 
-               a1.A = 42;
-               a1.B = 3.1415;
+               a1->A = 42;
+               a1->B = 3.1415;
 
                F = test_method;
 
-               F (&a1, &ex);
+               F (obj, &ex);
                if (ex)
                        return 4;
 
-               if (a1.A != 1)
+               if (a1->A != 1)
                        return 5;
 
-               if (a1.B != 17)
+               if (a1->B != 17)
                        return 6;
 
                break;
index 5ee054dadd92cd11c5f4d098b1ecbd4f09db0329..cd59ad8bb721e1ed335680575b09866a38d44fcc 100644 (file)
@@ -1,79 +1,76 @@
 using System;
+using System.Reflection;
 using System.Runtime.InteropServices;
 
 public class Test
 {
        [DllImport ("libtest")]
-       public static extern int test_method_thunk (int id, IntPtr testMethodHandle,
+               public static extern int test_method_thunk (int test_id, IntPtr testMethodHandle,
                IntPtr createObjectHandle);
 
-       static int test_method_thunk (int id, Type type)
+       static void RunTests(int series, Type type)
        {
-               string name = String.Format ("Foo{0}", id);
-               return test_method_thunk (
-                       id,
-                       type.GetMethod (name).MethodHandle.Value,
-                       type.GetMethod ("CreateObject").MethodHandle.Value);
+               const string Prefix = "Test";
+               MethodInfo createObjectMethod = type.GetMethod ("CreateObject");
+               
+               foreach (MethodInfo mi in type.GetMethods ()) {
+                       string name = mi.Name;
+                       if (!name.StartsWith (Prefix))
+                               continue;
+
+                       int id = Convert.ToInt32 (name.Substring (Prefix.Length));
+
+                       int res = test_method_thunk (series + id, mi.MethodHandle.Value, createObjectMethod.MethodHandle.Value);
+
+                       if (res != 0) {
+                               Console.WriteLine ("{0} returned {1}", mi, res);
+                               Environment.Exit ((id << 3) + res);
+                       }
+               }
        }
 
        public static int Main ()
        {
-               const int MaxClassTests = 13;
-               const int MaxStructTests = 1;
-               
-               // tests of class "Test"
-               for (int i = 0; i < MaxClassTests; i++) {
-                       int res = test_method_thunk (i, typeof (Test));
-                       if (res != 0)
-                               return i*10 + res;
-               }
-
-               // tests of struct "TestStruct"
-               for (int i = 0; i < MaxStructTests; i++) {
-                       int res = test_method_thunk (MaxClassTests + i, typeof (TestStruct));
-                       if (res != 0)
-                               return i*10 + res;
-               }
-               
+               RunTests (0, typeof (Test));
+               RunTests (100, typeof (TestStruct));
                return 0;
        }
 
        public static object CreateObject ()
        {
-               Test t = new Test ();
-               return t;
+               return new Test ();
        }
 
-       public static void Foo0 ()
+       public static void Test0 ()
        {
        }
 
-       public static int Foo1 ()
+       public static int Test1 ()
        {
                return 42;
        }
 
-       public static string Foo2 (string s)
+       public static string Test2 (string s)
        {
                return s;
        }
 
-       public string Foo3 (string a)
+       public string Test3 (string a)
        {
                return a;
        }
 
-       public int Foo4 (string a, int i)
+       public int Test4 (string a, int i)
        {
                return i;
        }
 
-       public int Foo5 (string a, int i)
+       public int Test5 (string a, int i)
        {
                throw new NotImplementedException ();
        }
 
-       public bool Foo6 (byte a1, short a2, int a3, long a4, float a5, double a6, string a7)
+       public bool Test6 (byte a1, short a2, int a3, long a4, float a5, double a6, string a7)
        {
                return  a1 == 254 &&
                        a2 == 32700 &&
@@ -81,15 +78,15 @@ public class Test
                        a4 == 6789600 &&
                        (Math.Abs (a5 - 3.1415) < 0.001) &&
                        (Math.Abs (a6 - 3.1415) < 0.001) &&
-                       a7 == "Foo6";
+                       a7 == "Test6";
        }
 
-       public static long Foo7 ()
+       public static long Test7 ()
        {
                return Int64.MaxValue;
        }
 
-       public static void Foo8 (ref byte a1, ref short a2, ref int a3, ref long a4, ref float a5, ref double a6, ref string a7)
+       public static void Test8 (ref byte a1, ref short a2, ref int a3, ref long a4, ref float a5, ref double a6, ref string a7)
        {
                a1 = 254;
                a2 = 32700;
@@ -97,46 +94,57 @@ public class Test
                a4 = 6789600;
                a5 = 3.1415f;
                a6 = 3.1415;
-               a7 = "Foo8";
+               a7 = "Test8";
        }
 
-       public static void Foo9 (ref byte a1, ref short a2, ref int a3, ref long a4, ref float a5, ref double a6, ref string a7)
+       public static void Test9 (ref byte a1, ref short a2, ref int a3, ref long a4, ref float a5, ref double a6, ref string a7)
        {
                throw new NotImplementedException ();
        }
 
-       public static bool Foo10 (TestStruct s)
+       public static void Test10 (ref Test obj)
+       {
+               obj = new Test ();
+       }
+}
+
+
+public struct TestStruct
+{
+       public int A;
+       public double B;
+
+       public static object CreateObject ()
+       {
+               return new TestStruct ();
+       }
+
+       public static bool Test0 (TestStruct s)
        {
-               return s.A == 42 && Math.Abs (s.B - 3.1415) < 0.001;
+               bool res =  s.A == 42 && Math.Abs (s.B - 3.1415) < 0.001;
+
+               /* these changes must not be visible in unmanaged code */
+               s.A = 12;
+               s.B = 13;
+
+               return res;
        }
 
-       public static void Foo11 (ref TestStruct s)
+       public static void Test1 (ref TestStruct s)
        {
                s.A = 42;
                s.B = 3.1415;
        }
 
-       public static TestStruct Foo12 ()
+       public static TestStruct Test2 ()
        {
                TestStruct s = new TestStruct ();
                s.A = 42;
                s.B = 3.1415;
                return s;
        }
-}
-
-
-public struct TestStruct
-{
-       public int A;
-       public double B;
-
-       public static TestStruct CreateObject ()
-       {
-               return new TestStruct ();
-       }
 
-       public void Foo13 ()
+       public void Test3 ()
        {
                A = 1;
                B = 17;