* ILParser.jay: Implement label form structured exception handling.
[mono.git] / mcs / ilasm / parser / ILParser.jay
index 25efab48b12550e90723fd60483d009444b6fed2..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
@@ -93,7 +94,8 @@ namespace Mono.ILASM {
 %token INSTR_TOK\r
 %token INSTR_SWITCH\r
 %token INSTR_PHI\r
-\r
+%token INSTR_LOCAL\r
+%token INSTR_PARAM\r
 \r
 \r
 \r
@@ -329,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
@@ -577,9 +579,12 @@ class_decl         : method_all
                        | customattr_decl\r
                        | D_SIZE int32\r
                           {\r
-                                \r
+                                codegen.CurrentTypeDef.SetSize ((int) $2);\r
                           }\r
                        | D_PACK int32\r
+                          {\r
+                                codegen.CurrentTypeDef.SetPack ((int) $2);\r
+                          }\r
                        | D_OVERRIDE type_spec DOUBLE_COLON method_name\r
                          K_WITH call_conv type type_spec DOUBLE_COLON method_name\r
                          OPEN_PARENS sig_args CLOSE_PARENS\r
@@ -602,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
@@ -1175,16 +1185,11 @@ data_decl               : data_head data_body
 \r
 data_head              : D_DATA tls id ASSIGN\r
                           {\r
-                                \r
-                                $$ = new DataDef ((string) $3, (bool)\r
-                          $2);\r
-                               \r
+                                $$ = new DataDef ((string) $3, (bool) $2);    \r
                           } \r
                        | D_DATA tls\r
                           {\r
-                                \r
                                 $$ = new DataDef (String.Empty, (bool) $2);\r
-                                \r
                           }\r
                        ;\r
 \r
@@ -1402,7 +1407,7 @@ impl_attr         : /* EMPTY */                   { $$ = new ImplAttr (); }
                        | impl_attr K_NOINLINING        { $$ = (ImplAttr) $1 | ImplAttr.NoInLining; }\r
                        ;\r
 \r
-sig_args               :               { $$ = new ArrayList (); }\r
+sig_args               : /* EMPTY */\r
                        | sig_arg_list\r
                        ;\r
 \r
@@ -1432,15 +1437,45 @@ sig_arg                 : param_attr type
                        | param_attr type K_MARSHAL OPEN_PARENS native_type CLOSE_PARENS id\r
                        ;\r
 \r
+type_list               : /* EMPTY */\r
+                        | type\r
+                          {\r
+                                ArrayList type_list = new ArrayList ();\r
+                                type_list.Add ($1);\r
+                                $$ = type_list;\r
+                          }\r
+                        | type_list COMMA type\r
+                          {\r
+                                ArrayList type_list = (ArrayList) $1;\r
+                                type_list.Add ($3);\r
+                          }\r
+                        ;\r
+\r
 method_decls           : /* EMPTY */\r
                        | method_decls method_decl\r
                        ;\r
 \r
 method_decl            : D_EMITBYTE int32\r
                        | D_MAXSTACK int32\r
-                       | D_LOCALS OPEN_PARENS sig_args CLOSE_PARENS\r
-                       | D_LOCALS K_INIT OPEN_PARENS sig_args CLOSE_PARENS\r
+                       | D_LOCALS OPEN_PARENS local_list CLOSE_PARENS\r
+                          {\r
+                                if ($3 != null) {\r
+                                        codegen.CurrentMethodDef.AddLocals (\r
+                                                (ArrayList) $3);\r
+                                }\r
+                          }\r
+                       | D_LOCALS K_INIT OPEN_PARENS local_list CLOSE_PARENS\r
+                          {\r
+                                if ($4 != null) {\r
+                                        codegen.CurrentMethodDef.AddLocals (\r
+                                                (ArrayList) $4);\r
+                                        codegen.CurrentMethodDef.InitLocals ();\r
+                                }\r
+                          }\r
                        | D_ENTRYPOINT\r
+                          {\r
+                                codegen.CurrentMethodDef.EntryPoint ();\r
+                          }\r
                        | D_ZEROINIT\r
                        | D_EXPORT OPEN_BRACKET int32 CLOSE_BRACKET\r
                        | D_EXPORT OPEN_BRACKET int32 CLOSE_BRACKET K_AS id\r
@@ -1461,8 +1496,50 @@ method_decl              : D_EMITBYTE int32
                        | data_decl\r
                        ;\r
 \r
+local_list              : /* EMPTY */\r
+                        | local\r
+                          {\r
+                                ArrayList local_list = new ArrayList ();\r
+                                local_list.Add ($1);\r
+                                $$ = local_list;\r
+                          }\r
+                        | local_list COMMA local\r
+                          {\r
+                                ArrayList local_list = (ArrayList) $1;\r
+                                local_list.Add ($3);\r
+                          }\r
+                        ;\r
+\r
+local                   : type\r
+                          {\r
+                                $$ = new Local (-1, (ITypeRef) $1);\r
+                          }\r
+                        | type id\r
+                          {\r
+                                $$ = new Local (-1, (string) $2, (ITypeRef) $1);\r
+                          }\r
+                        | slot_num type\r
+                          {\r
+                                $$ = new Local ((int) $1, (ITypeRef) $2);\r
+                          }\r
+                        | slot_num type id\r
+                          {\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
@@ -1471,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
@@ -1503,17 +1635,49 @@ instr                   : INSTR_NONE
                                 codegen.CurrentMethodDef.AddInstr (\r
                                         new SimpInstr ((Op) $1));\r
                           }\r
-                       | INSTR_VAR int32\r
+                       | INSTR_LOCAL int32\r
+                          {\r
+                                codegen.CurrentMethodDef.AddInstr (\r
+                                        new IntInstr ((IntOp) $1, (int) $2));        \r
+                          }\r
+                        | INSTR_LOCAL id\r
+                          {\r
+                                int slot = codegen.CurrentMethodDef.GetNamedLocalSlot ((string) $2);\r
+                                codegen.CurrentMethodDef.AddInstr (\r
+                                        new IntInstr ((IntOp) $1, slot));\r
+                          }\r
+                        | INSTR_PARAM int32\r
+                          {\r
+                                codegen.CurrentMethodDef.AddInstr (\r
+                                        new IntInstr ((IntOp) $1, (int) $2));\r
+                          }\r
+                        | INSTR_PARAM id\r
+                          {\r
+                                int pos = codegen.CurrentMethodDef.GetNamedParamPos ((string) $2);\r
+                                codegen.CurrentMethodDef.AddInstr (\r
+                                        new IntInstr ((IntOp) $1, pos));\r
+                          }\r
                        | INSTR_I int32\r
                           {\r
                                 codegen.CurrentMethodDef.AddInstr (new\r
                                         IntInstr ((IntOp) $1, (int) $2));\r
                           }\r
-                       | INSTR_I id /* Allow variable names */\r
-                       | INSTR_I8 int64\r
+                       | INSTR_I id\r
                           {\r
+                                int slot = codegen.CurrentMethodDef.GetNamedLocalSlot ((string) $2);\r
                                 codegen.CurrentMethodDef.AddInstr (new\r
-                                        IntInstr ((IntOp) $1, (int) $2));\r
+                                        IntInstr ((IntOp) $1, slot));\r
+                          }\r
+                       | INSTR_I8 int64\r
+                          {\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
@@ -1526,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
@@ -1544,11 +1711,28 @@ instr                   : INSTR_NONE
                           }\r
                        | INSTR_METHOD method_ref\r
                           {\r
-                                \r
+                                codegen.CurrentMethodDef.AddInstr (new MethodInstr ((MethodOp) $1,\r
+                                        (IMethodRef) $2));\r
                           }\r
                        | INSTR_FIELD type type_spec DOUBLE_COLON id\r
+                          {\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
                        | INSTR_FIELD type id\r
+                          {\r
+                                GlobalFieldRef fieldref = new GlobalFieldRef ((ITypeRef) $2, (string) $3);\r
+\r
+                                codegen.CurrentMethodDef.AddInstr (new FieldInstr ((FieldOp) $1, fieldref));\r
+                          }\r
                        | INSTR_TYPE type_spec\r
+                          {\r
+                                codegen.CurrentMethodDef.AddInstr (new TypeInstr ((TypeOp) $1,\r
+                                        (ITypeRef) $2));\r
+                          }\r
                        | INSTR_STRING comp_qstring\r
                           {\r
                                 if ((MiscInstr) $1 == MiscInstr.ldstr)\r
@@ -1557,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
@@ -1566,9 +1769,33 @@ instr                    : INSTR_NONE
                        ;\r
 \r
 method_ref             : call_conv type type_spec DOUBLE_COLON method_name \r
-                         OPEN_PARENS sig_args CLOSE_PARENS\r
+                         OPEN_PARENS type_list CLOSE_PARENS\r
+                          {\r
+                                ITypeRef owner = (ITypeRef) $3;\r
+                                ArrayList arg_list = (ArrayList) $7;\r
+                                ITypeRef[] param_list;\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
+                                $$ = owner.AsClassRef (codegen).GetMethodRef ((ITypeRef) $2,\r
+                                        (CallConv) $1, (string) $5, param_list);\r
+                          }\r
                        | call_conv type method_name \r
-                         OPEN_PARENS sig_args CLOSE_PARENS\r
+                         OPEN_PARENS type_list CLOSE_PARENS\r
+                          {\r
+                                ArrayList arg_list = (ArrayList) $5;\r
+                                ITypeRef[] param_list;\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
+                                $$ = new GlobalMethodRef ((ITypeRef) $2, (string) $3, param_list);\r
+                          }\r
                        ;\r
 \r
 labels                 : /* EMPTY */\r
@@ -1600,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
@@ -1833,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