* ILParser.jay: Implement label form structured exception handling.
[mono.git] / mcs / ilasm / parser / ILParser.jay
index 0406947ce38f2b21b2d924025b951dfdfaaab96e..9c1965356841348ffba9174a23a9693f44e748d2 100644 (file)
@@ -5,6 +5,7 @@
 \r
 using PEAPI;\r
 using System;\r
+using System.IO;\r
 using System.Collections;\r
 using System.Globalization;\r
 \r
@@ -330,8 +331,8 @@ namespace Mono.ILASM {
 %token K_NOMETADATA\r
 %token K_ALGORITHM\r
 %token K_FULLORIGIN\r
-%token K_NAN\r
-%token K_INF\r
+// %token K_NAN\r
+// %token K_INF\r
 %token K_PUBLICKEY\r
 %token K_ENABLEJITTRACKING\r
 %token K_DISABLEJITOPTIMIZER\r
@@ -606,9 +607,14 @@ type                       : K_CLASS class_ref
                           {\r
                                 $$ = $3;\r
                           }\r
-                       | K_VALUETYPE class_ref\r
+                       | K_VALUETYPE OPEN_BRACKET comp_name CLOSE_BRACKET slashed_name\r
                           {\r
-                                $$ = $2;\r
+                                ClassRef klass = codegen.ExternTable.GetValueClass ((string) $3, (string)$5);\r
+                                $$ = new ExternTypeRef (klass, (string) $5);\r
+                          }\r
+                        | K_VALUETYPE slashed_name\r
+                          {\r
+                                $$ = new TypeRef ((string) $2, null);\r
                           }\r
                        | type OPEN_BRACKET CLOSE_BRACKET\r
                           {\r
@@ -1512,18 +1518,28 @@ local                   : type
                           {\r
                                 $$ = new Local (-1, (string) $2, (ITypeRef) $1);\r
                           }\r
-                        | OPEN_BRACKET int32 CLOSE_BRACKET type\r
+                        | slot_num type\r
                           {\r
-                                $$ = new Local ((int) $2, (ITypeRef) $4);\r
+                                $$ = new Local ((int) $1, (ITypeRef) $2);\r
                           }\r
-                        | OPEN_BRACKET int32 CLOSE_BRACKET type id\r
+                        | slot_num type id\r
                           {\r
-                                $$ = new Local ((int) $2, (string) $5, (ITypeRef) $4);\r
+                                $$ = new Local ((int) $1, (string) $5, (ITypeRef) $2);\r
+                          }\r
+                        ;\r
+\r
+slot_num                : OPEN_BRACKET int32 CLOSE_BRACKET\r
+                          {\r
+                                $$ = $2;\r
                           }\r
                         ;\r
 \r
 type_spec              : class_ref\r
                        | OPEN_BRACKET comp_name CLOSE_BRACKET\r
+                          {\r
+                                // This is a reference to a global method in another\r
+                                // assembly. This is not supported in the MS version of ilasm\r
+                          }\r
                        | OPEN_BRACKET D_MODULE comp_name CLOSE_BRACKET\r
                        | type\r
                        ;\r
@@ -1532,30 +1548,85 @@ scope_block             : OPEN_BRACE method_decls CLOSE_BRACE
                        ;\r
 \r
 seh_block              : try_block seh_clauses\r
+                          {\r
+                                Console.WriteLine ($1);\r
+                                Console.WriteLine ($2);\r
+                                TryBlock try_block = (TryBlock) $1;\r
+                                try_block.SetMethod (codegen.CurrentMethodDef);\r
+\r
+                                ArrayList clause_list = (ArrayList) $2;\r
+                                foreach (object clause in clause_list) {\r
+                                        Console.WriteLine ("clause:  " + clause);\r
+                                        try_block.AddSehClause ((ISehClause) clause);\r
+                                }\r
+\r
+                                codegen.CurrentMethodDef.AddInstr (try_block);\r
+                          }\r
                        ;\r
 \r
 try_block              : D_TRY scope_block\r
                        | D_TRY id K_TO id\r
+                          {\r
+                                $$ = new TryBlock ((string) $2, (string) $4);\r
+                          }\r
                        | D_TRY int32 K_TO int32\r
                        ;\r
 \r
 seh_clauses            : seh_clause\r
+                          {\r
+                                ArrayList clause_list = new ArrayList ();\r
+                                clause_list.Add ($1);\r
+                                $$ = clause_list;\r
+                          }\r
                        | seh_clauses seh_clause\r
+                          {\r
+                                ArrayList clause_list = (ArrayList) $1;\r
+                                clause_list.Add ($2);\r
+                          }\r
                        ;\r
 \r
 seh_clause             : K_CATCH class_ref handler_block\r
+                          {\r
+                                Console.WriteLine ($2);\r
+                                Console.WriteLine ($3);\r
+                                ITypeRef type = (ITypeRef) $2;\r
+                                CatchBlock cb = new CatchBlock (type.AsClassRef (codegen));\r
+                                cb.SetHandlerBlock ((HandlerBlock) $3);\r
+                                $$ = cb;\r
+                          }\r
                        | K_FINALLY handler_block\r
+                          {\r
+                                FinallyBlock fb = new FinallyBlock ();\r
+                                fb.SetHandlerBlock ((HandlerBlock) $2);\r
+                                $$ = fb;\r
+                          }\r
                        | K_FAULT handler_block\r
+                          {\r
+                                FaultBlock fb = new FaultBlock ();\r
+                                fb.SetHandlerBlock ((HandlerBlock) $2);\r
+                                $$ = fb;\r
+                          }\r
                        | filter_clause handler_block\r
+                          {\r
+                                FilterBlock fb = (FilterBlock) $1;\r
+                                fb.SetHandlerBlock ((HandlerBlock) $2);\r
+                          }\r
                        ;\r
 \r
 filter_clause          : K_FILTER scope_block\r
                        | K_FILTER id\r
+                          {\r
+                                FilterBlock fb = new FilterBlock ((string) $2);\r
+                                $$ = fb;\r
+                          }\r
                        | K_FILTER int32\r
                        ;\r
 \r
 handler_block          : scope_block\r
                        | K_HANDLER id K_TO id\r
+                          {\r
+                                $$ = new HandlerBlock ((string) $2, (string) $4);\r
+                          }\r
                        | K_HANDLER int32 K_TO int32\r
                        ;\r
 \r
@@ -1599,8 +1670,14 @@ instr                    : INSTR_NONE
                           }\r
                        | INSTR_I8 int64\r
                           {\r
-                                codegen.CurrentMethodDef.AddInstr (new\r
-                                        IntInstr ((IntOp) $1, (int) $2));\r
+                                if ($1 is MiscInstr) {\r
+                                        switch ((MiscInstr) $1) {\r
+                                        case MiscInstr.ldc_i8:\r
+                                        codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1,\r
+                                                (long) $2));\r
+                                        break;\r
+                                        }\r
+                                }\r
                           }\r
                        | INSTR_R float64\r
                           {\r
@@ -1613,9 +1690,12 @@ instr                    : INSTR_NONE
                           }\r
                        | INSTR_R int64\r
                           {\r
+                                long l = (long) $2;\r
+                                \r
                                 switch ((MiscInstr) $1) {\r
+                                        case MiscInstr.ldc_r4:\r
                                         case MiscInstr.ldc_r8:\r
-                                        codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, (double) $2));\r
+                                        codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, (double) l));\r
                                         break;\r
                                 }\r
                           }\r
@@ -1636,8 +1716,9 @@ instr                     : INSTR_NONE
                           }\r
                        | INSTR_FIELD type type_spec DOUBLE_COLON id\r
                           {\r
-                                IClassRef owner = (IClassRef) $3;\r
-                                IFieldRef fieldref = owner.GetFieldRef ((ITypeRef) $2, (string) $5);\r
+                                ITypeRef owner = (ITypeRef) $3;\r
+                                IFieldRef fieldref = owner.AsClassRef (codegen).GetFieldRef (\r
+                                        (ITypeRef) $2, (string) $5);\r
 \r
                                 codegen.CurrentMethodDef.AddInstr (new FieldInstr ((FieldOp) $1, fieldref));\r
                           }\r
@@ -1660,7 +1741,26 @@ instr                    : INSTR_NONE
                        | INSTR_STRING K_BYTEARRAY ASSIGN OPEN_PARENS bytes CLOSE_PARENS\r
                        | INSTR_STRING K_BYTEARRAY OPEN_PARENS bytes CLOSE_PARENS               // ****** ADDED\r
                        | INSTR_SIG call_conv type OPEN_PARENS sig_args CLOSE_PARENS\r
+                          {\r
+                                ArrayList arg_list = (ArrayList) $5;\r
+                                ITypeRef[] arg_array = null;\r
+\r
+                                if (arg_list != null)\r
+                                        arg_array = (ITypeRef[]) arg_list.ToArray (typeof (ITypeRef));\r
+\r
+                                codegen.CurrentMethodDef.AddInstr (new CalliInstr ((CallConv) $1,\r
+                                        (ITypeRef) $3, arg_array));\r
+                          }     \r
                        | INSTR_TOK owner_type\r
+                          {\r
+                                if ((MiscInstr) $1 == MiscInstr.ldtoken) {\r
+                                        if ($2 is IMethodRef)\r
+                                                codegen.CurrentMethodDef.AddInstr (new LdtokenInstr ((IMethodRef) $2));\r
+                                        else\r
+                                                codegen.CurrentMethodDef.AddInstr (new LdtokenInstr ((IMethodRef) $2));\r
+                                                \r
+                                }\r
+                          }\r
                        | INSTR_SWITCH OPEN_PARENS labels CLOSE_PARENS\r
                           {\r
                                 codegen.CurrentMethodDef.AddInstr (new SwitchInstr ((ArrayList) $3,\r
@@ -1671,24 +1771,24 @@ instr                   : INSTR_NONE
 method_ref             : call_conv type type_spec DOUBLE_COLON method_name \r
                          OPEN_PARENS type_list CLOSE_PARENS\r
                           {\r
-                                IClassRef owner = (IClassRef) $3;\r
+                                ITypeRef owner = (ITypeRef) $3;\r
                                 ArrayList arg_list = (ArrayList) $7;\r
                                 ITypeRef[] param_list;\r
-\r
+  \r
                                 if (arg_list != null)\r
                                         param_list = (ITypeRef[]) arg_list.ToArray (typeof (ITypeRef));\r
                                 else\r
                                         param_list = new ITypeRef[0];\r
 \r
-                                \r
-                                $$ = owner.GetMethodRef ((ITypeRef) $2, (string) $5, param_list);\r
+                                $$ = owner.AsClassRef (codegen).GetMethodRef ((ITypeRef) $2,\r
+                                        (CallConv) $1, (string) $5, param_list);\r
                           }\r
                        | call_conv type method_name \r
                          OPEN_PARENS type_list CLOSE_PARENS\r
                           {\r
                                 ArrayList arg_list = (ArrayList) $5;\r
                                 ITypeRef[] param_list;\r
-                        \r
+  \r
                                 if (arg_list != null)\r
                                         param_list = (ITypeRef[]) arg_list.ToArray (typeof (ITypeRef));\r
                                 else\r
@@ -1727,9 +1827,21 @@ owner_type               : type_spec
                        | member_ref\r
                        ;\r
 \r
-member_ref             : K_METHOD member_ref\r
+member_ref             : K_METHOD method_ref\r
+                          {\r
+                                $$ = $1;\r
+                          }\r
                        | K_FIELD type type_spec DOUBLE_COLON id\r
+                          {\r
+                                ITypeRef owner = (ITypeRef) $3;\r
+\r
+                                $$ = owner.AsClassRef (codegen).GetFieldRef (\r
+                                        (ITypeRef) $2, (string) $5);\r
+                          }\r
                        | K_FIELD type id\r
+                          {\r
+                                $$ = new GlobalFieldRef ((ITypeRef) $2, (string) $3);\r
+                          }\r
                        ;\r
 \r
 event_all              : event_head OPEN_BRACE event_decls CLOSE_BRACE\r
@@ -1960,22 +2072,42 @@ comp_qstring            : QSTRING
 int32                  : INT32\r
                         | INT64\r
                           {\r
-                                Int64 int64 = (Int64) $1;\r
-\r
-                                if (int64 > Int32.MaxValue)\r
-                                        $$ = Int32.MaxValue;\r
-                                else if (int64 < Int32.MinValue)\r
-                                        $$ = Int32.MinValue;  \r
+                                long l = (long) $1;\r
+                                byte[] intb = BitConverter.GetBytes (l);\r
+                                $$ = BitConverter.ToInt32 (intb, 0);\r
                           }\r
                        ;\r
 \r
 int64                  : INT64\r
                         | INT32\r
+                          {\r
+                                $$ = Convert.ToInt64 ($1);\r
+                          }\r
                        ;\r
 \r
 float64                        : FLOAT64\r
-                       | K_FLOAT32 OPEN_PARENS int32 CLOSE_PARENS\r
-                       | K_FLOAT64 OPEN_PARENS int64 CLOSE_PARENS\r
+                       | K_FLOAT32 OPEN_PARENS INT32 CLOSE_PARENS\r
+                          {\r
+                                int i = (int) $3;\r
+                                byte[] intb = BitConverter.GetBytes (i);\r
+                                $$ = (double) BitConverter.ToSingle (intb, 0);\r
+                          }\r
+                        | K_FLOAT32 OPEN_PARENS INT64 CLOSE_PARENS\r
+                          {\r
+                                long l = (long) $3;\r
+                                byte[] intb = BitConverter.GetBytes (l);\r
+                                $$ = (double) BitConverter.ToSingle (intb, 0);\r
+                          }\r
+                       | K_FLOAT64 OPEN_PARENS INT64 CLOSE_PARENS\r
+                          {\r
+                                byte[] intb = BitConverter.GetBytes ((long) $3);\r
+                                $$ = BitConverter.ToDouble (intb, 0);\r
+                          }\r
+                        | K_FLOAT64 OPEN_PARENS INT32 CLOSE_PARENS\r
+                          {\r
+                                byte[] intb = BitConverter.GetBytes ((int) $3);\r
+                                $$ = (double) BitConverter.ToSingle (intb, 0);\r
+                          }\r
                        ;\r
 \r
 hexbyte                        : HEXBYTE\r