* ILParser.jay: Implement label form structured exception handling.
[mono.git] / mcs / ilasm / parser / ILParser.jay
index 84606698289f9eadd6e02e09e6369c127c87aec3..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
@@ -402,7 +404,6 @@ vtfixup_decl                : D_VTFIXUP OPEN_BRACKET int32 CLOSE_BRACKET
                        ;\r
 \r
 vtfixup_attr           : /* EMPTY */\r
-                       | vtfixup_attr int32\r
                        | vtfixup_attr int64\r
                        | vtfixup_attr K_FROMUNMANAGED\r
                        | vtfixup_attr K_CALLMOSTDERIVED\r
@@ -578,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
@@ -603,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
@@ -1176,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
@@ -1403,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
@@ -1433,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
@@ -1450,6 +1484,9 @@ method_decl               : D_EMITBYTE int32
                        | scope_block\r
                        | D_PARAM OPEN_BRACKET int32 CLOSE_BRACKET init_opt\r
                        | id COLON\r
+                          {\r
+                                codegen.CurrentMethodDef.AddLabel ((string) $1);\r
+                          }\r
                        | seh_block\r
                        | instr\r
                        | sec_decl\r
@@ -1459,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
@@ -1469,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
@@ -1501,59 +1635,213 @@ 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
-                           //     Console.WriteLine ((Int64) $2);\r
-                           //     codegen.CurrentMethodDef.AddInstr (new\r
-                           //             IntInstr ((IntOp) $1, (int) $2));\r
+                                codegen.CurrentMethodDef.AddInstr (new\r
+                                        IntInstr ((IntOp) $1, (int) $2));\r
+                          }\r
+                       | INSTR_I id\r
+                          {\r
+                                int slot = codegen.CurrentMethodDef.GetNamedLocalSlot ((string) $2);\r
+                                codegen.CurrentMethodDef.AddInstr (new\r
+                                        IntInstr ((IntOp) $1, slot));\r
                           }\r
-                       | INSTR_I id /* Allow variable names */\r
                        | INSTR_I8 int64\r
                           {\r
-                                Console.WriteLine ($1);\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
+                                switch ((MiscInstr) $1) {\r
+                                case MiscInstr.ldc_r4:\r
+                                case MiscInstr.ldc_r8:\r
+                                         codegen.CurrentMethodDef.AddInstr (new LdcInstr ((MiscInstr) $1, (double) $2));\r
+                                         break;\r
+                                }\r
+                          }\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) l));\r
+                                        break;\r
+                                }\r
+                          }\r
                        | INSTR_R OPEN_PARENS bytes CLOSE_PARENS\r
                        | INSTR_BRTARGET int32\r
+                          {\r
+                                // Need to add this to PEAPI        \r
+                          }\r
                        | INSTR_BRTARGET id\r
+                          {\r
+                                codegen.CurrentMethodDef.AddInstr (new BranchInstr ((BranchOp) $1,\r
+                                        codegen.CurrentMethodDef, (string) $2));\r
+                          }\r
                        | INSTR_METHOD method_ref\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 ((string) $1 == "ldstr")\r
+                                if ((MiscInstr) $1 == MiscInstr.ldstr)\r
                                         codegen.CurrentMethodDef.AddInstr (new LdstrInstr ((string) $2));\r
                           }\r
                        | 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
+                                        codegen.CurrentMethodDef));\r
+                          }\r
                        ;\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
                        | id\r
+                          {\r
+                                ArrayList label_list = new ArrayList ();\r
+                                label_list.Add ($1);\r
+                                $$ = label_list;\r
+                          }\r
                        | int32\r
+                          {\r
+                                ArrayList label_list = new ArrayList ();\r
+                                label_list.Add ($1);\r
+                                $$ = label_list;\r
+                          }\r
                        | labels COMMA id\r
+                          {\r
+                                ArrayList label_list = (ArrayList) $1;\r
+                                label_list.Add ($3);\r
+                          }\r
                        | labels COMMA int32\r
+                          {\r
+                                ArrayList label_list = (ArrayList) $1;\r
+                                label_list.Add ($3);\r
+                          }\r
                        ;\r
 \r
 owner_type             : type_spec\r
                        | 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
@@ -1777,25 +2065,49 @@ manifestres_decl        : D_FILE comp_name K_AT int32
                        | customattr_decl\r
                        ;\r
 \r
-dotted_name            : id\r
-                       | dotted_name DOT id    { $$ = String.Format ("{0}.{1}", $1, $3); }\r
-                       ;\r
-\r
 comp_qstring           : QSTRING\r
                        | comp_qstring PLUS QSTRING     { $$ = String.Format ("{0}{1}", $1, $3); }\r
                        ;\r
 \r
 int32                  : INT32\r
-                       | INT64\r
+                        | INT64\r
+                          {\r
+                                long l = (long) $1;\r
+                                byte[] intb = BitConverter.GetBytes (l);\r
+                                $$ = BitConverter.ToInt32 (intb, 0);\r
+                          }\r
                        ;\r
 \r
-int64                  : INT32\r
-                       | INT64\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
@@ -1836,11 +2148,10 @@ id                      : ID
                        ;\r
 \r
 comp_name              : id\r
-                       | dotted_name\r
-                       ;\r
-\r
-dotted_name            : id\r
-                       | dotted_name DOT id\r
+                       | comp_name DOT id\r
+                          {\r
+                                $$ = (string) $1 + '.' + (string) $3;\r
+                          }\r
                        ;\r
 \r
 \r