Merge pull request #5210 from alexrp/profiler-runtime-settings
[mono.git] / mono / tests / gen-runtime-invoke.cs
1 /*
2  * Test generator for runtime invoke tests.
3  */
4 using System;
5 using System.IO;
6
7 public class Tests
8 {
9         public static void Main (String[] args) {
10                 /* There are multiple approaches, we generate c# directly */
11
12                 using (var w = new StreamWriter (Console.OpenStandardOutput ())) {
13                         w.WriteLine ("using System;");
14                         w.WriteLine ("using System.Reflection;");
15                         w.WriteLine ();
16
17                         // Struct with 2 int fields
18                         w.WriteLine ("public struct FooStruct { public int i, j; public static bool operator == (FooStruct f1, FooStruct f2) { return f1.i == f2.i && f1.j == f2.j; } public static bool operator != (FooStruct f1, FooStruct f2) { return f1.i != f2.i || f1.j != f2.j; } public override bool Equals (object obj) { return this == (FooStruct)obj; } public override int GetHashCode () { return 0; } }");
19
20                         // Struct with 1 long field
21                         w.WriteLine ("public struct FooStruct2 { public long i; public static bool operator == (FooStruct2 f1, FooStruct2 f2) { return f1.i == f2.i; } public static bool operator != (FooStruct2 f1, FooStruct2 f2) { return f1.i != f2.i; } public override bool Equals (object obj) { return this == (FooStruct2)obj; } public override int GetHashCode () { return 0; } }");
22
23                         // Struct with 2 bool fields
24                         w.WriteLine ("public struct FooStruct3 { public bool i, j; public static bool operator == (FooStruct3 f1, FooStruct3 f2) { return f1.i == f2.i && f1.j == f2.j; } public static bool operator != (FooStruct3 f1, FooStruct3 f2) { return f1.i != f2.i || f1.j != f2.j; } public override bool Equals (object obj) { return this == (FooStruct3)obj; } public override int GetHashCode () { return 0; } }");
25
26                         w.WriteLine ("public class Tests {");
27                         w.WriteLine ("    public static int Main (String[] args) {");
28                         w.WriteLine ("        return TestDriver.RunTests (typeof (Tests), args);");
29                         w.WriteLine ("    }");
30
31                         // int
32                         GenCase (w, "int", "42", new string [] { "int", "uint" }, new string [] { "Int32.MinValue", "UInt32.MaxValue" });
33
34                         // byref int
35                         GenCase (w, "int", "42", new string [] { "ref int" }, new string [] { "Int32.MinValue" });
36
37                         // short
38                         GenCase (w, "short", "42", new string [] { "short", "ushort" }, new string [] { "Int16.MinValue", "UInt16.MaxValue" });
39
40                         // bool
41                         GenCase (w, "bool", "true", new string [] { "bool", "bool", "bool" }, new string [] { "true", "false", "true" });
42
43                         // char
44                         GenCase (w, "char", "'A'", new string [] { "char", "char", "char" }, new string [] { "'A'", "'B'", "'C'" });
45
46                         // long
47                         GenCase (w, "long", "0x12345678AL", new string [] { "long", "long" }, new string [] { "0x123456789L", "0x123456789L" });
48
49                         // long in an odd numbered register
50                         GenCase (w, "long", "0x12345678AL", new string [] { "int", "long", "long" }, new string [] { "1", "0x123456789L", "0x123456789L" });
51
52                         // long in split reg/stack on arm
53                         GenCase (w, "void", "", new string [] { "int", "int", "int", "long" }, new string [] { "1", "2", "3", "0x123456789L" });
54
55                         // vtype in split reg/stack on arm
56                         GenCase (w, "void", "", new string [] { "int", "int", "int", "FooStruct" }, new string [] { "1", "2", "3", "new FooStruct () { i = 1, j = 2 }" });
57
58                         // 8 aligned vtype in split reg/stack on arm
59                         GenCase (w, "void", "", new string [] { "int", "int", "int", "FooStruct2" }, new string [] { "1", "2", "3", "new FooStruct2 () { i = 0x123456789L }" });
60
61                         // vtype entirely on the stack on arm
62                         GenCase (w, "void", "", new string [] { "int", "int", "int", "int", "FooStruct" }, new string [] { "1", "2", "3", "4", "new FooStruct () { i = 1, j = 2 }" });
63
64                         // vtype with size 2 in a register on arm
65                         GenCase (w, "FooStruct3", "new FooStruct3 () { i = true, j = false }", new string [] { "FooStruct3" }, new string [] { "new FooStruct3 () { i = true, j = false }" });
66
67                         // float
68                         GenCase (w, "void", "", new string [] { "float" }, new string [] { "0.123f" });
69
70                         // float on the stack on arm
71                         GenCase (w, "void", "", new string [] { "int", "int", "int", "int", "float" }, new string [] { "1", "2", "3", "4", "0.123f" });
72
73                         // float ret
74                         GenCase (w, "float", "0.123f", new string [] { }, new string [] { });
75
76                         // double
77                         GenCase (w, "void", "", new string [] { "double" }, new string [] { "0.123f" });
78
79                         // double in split reg/stack on arm
80                         GenCase (w, "void", "", new string [] { "int", "int", "int", "double" }, new string [] { "1", "2", "3", "0.123f" });
81
82                         // double ret
83                         GenCase (w, "double", "0.123f", new string [] { }, new string [] { });
84
85                         w.WriteLine ("}");
86                 }
87         }
88
89         static int testid_gen;
90
91         static void WriteList (StreamWriter w, string[] values) {
92                 int i = 0;
93                 foreach (string v in values) {
94                         if (i > 0)
95                                 w.Write (", ");
96                         w.Write (v);
97                         i ++;
98                 }
99         }
100
101         public static void GenCase (StreamWriter w, string retType, string retVal, string[] types, string[] values) {
102                 testid_gen ++;
103
104                 string callee_name = "meth_" + testid_gen;
105
106                 /* The caller */
107                 w.WriteLine ("\tpublic static int test_0_" + testid_gen + " () {");
108                 w.Write ("\t\t");
109                 if (retType != "void")
110                         w.Write (retType + " res = (" + retType + ")");
111                 w.Write ("typeof (Tests).GetMethod (\"" + callee_name + "\").Invoke (null, new object [] { ");
112                 WriteList (w, values);
113                 w.WriteLine ("});");
114                 if (retType != "void")
115                         w.WriteLine ("\t\tif (res !=  " + retVal + ") return 1;");
116                 w.WriteLine ("\t\treturn 0;");
117                 w.WriteLine ("\t}");
118
119                 /* The callee */
120                 w.Write ("\tpublic static " + retType + " meth_" + testid_gen + " (");
121
122                 string[] arg_decl = new string [types.Length];
123                 for (int i = 0; i < types.Length; ++i)
124                         arg_decl [i] = types [i] + " arg" + i;
125
126                 WriteList (w, arg_decl);
127                 w.WriteLine (") {");
128
129                 for (int i = 0; i < values.Length; ++i)
130                         w.WriteLine ("\t\tif (arg" + i + " != " + values [i] + ") throw new Exception ();");
131
132                 if (retType != "void")
133                         w.WriteLine ("\t\treturn " + retVal + ";");
134
135                 w.WriteLine ("\t}");
136         }
137 }