diff options
-rw-r--r-- | gcc/cil/cil-builtins.c | 4 | ||||
-rw-r--r-- | gcc/cil/parser.c | 1027 | ||||
-rw-r--r-- | gcc/cil/stack.c | 52 | ||||
-rw-r--r-- | gcc/cil/stack.h | 14 |
4 files changed, 752 insertions, 345 deletions
diff --git a/gcc/cil/cil-builtins.c b/gcc/cil/cil-builtins.c index 2e24d7192e1..216587ebbed 100644 --- a/gcc/cil/cil-builtins.c +++ b/gcc/cil/cil-builtins.c @@ -64,6 +64,10 @@ static tree handle_pure_attribute (tree *, tree, tree, int, bool *); const struct attribute_spec cil_common_attribute_table[] = { /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */ + /* CIL Specific Attributes */ + { "OpenSystem.C.InitializerAttribute", 0, 0, false, false, false, NULL }, + + /* Attributes borrowed from C to be able to support builtins */ { "packed", 0, 0, false, false, false, NULL/*handle_packed_attribute*/ }, { "nocommon", 0, 0, true, false, false, NULL/*handle_nocommon_attribute*/ }, { "common", 0, 0, true, false, false, NULL/*handle_common_attribute*/ }, diff --git a/gcc/cil/parser.c b/gcc/cil/parser.c index 45332dee9c5..7704d246b60 100644 --- a/gcc/cil/parser.c +++ b/gcc/cil/parser.c @@ -71,10 +71,6 @@ bool flag_parse_only_reachable = FALSE; /* what to do when trying to compile a method that uses some unsupported feature */ UnsupportedMethodBehavior flag_unsupported_method_behavior = UMB_WARNING; -/* Debug hooks */ -#define TRACE_DECL(x) -#define TRACE_IMPL(x) - /* Auxiliary types and variables for compilation */ // typedef GHashTable CILLabelsMap; /* maps ip to label */ @@ -101,6 +97,12 @@ cil_labels_set_get_label (CILLabelsMap *labels, const unsigned char *ip) return label_decl_tree; } +static tree +cil_labels_get_label (CILLabelsMap *labels, const unsigned char *ip) +{ + return g_hash_table_lookup (labels, ip); +} + static void cil_labels_set_free (CILLabelsMap *labels) { @@ -370,41 +372,18 @@ parser_get_class_mode (MonoClass *klass) } } -static CilStackType -parser_get_binary_numeric_operations_type (CilStackType opA_type, CilStackType opB_type) -{ - if (opA_type == CIL_STACK_TYPE_ERROR || opB_type == CIL_STACK_TYPE_ERROR) - { - return CIL_STACK_TYPE_ERROR; - } - else - { - gcc_assert (opA_type < CIL_STACK_TYPE_ERROR); - gcc_assert (opB_type < CIL_STACK_TYPE_ERROR); - const CilStackType table[6][6] = { - { CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_MANAGED_POINTER, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT64, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_MANAGED_POINTER, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_F, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_MANAGED_POINTER, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_MANAGED_POINTER, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - }; - return table[opA_type][opB_type]; - } -} - static void parser_emit_ldc_i4 (gint32 i) { tree exp = build_int_cst (cil_type_for_size (32, false), i); - cil_stack_push (exp, CIL_STACK_TYPE_INT32); + cil_stack_push (exp, CIL_STYPE_INT32); } static void parser_emit_ldc_i8 (gint64 i) { tree exp = build_int_cst (cil_type_for_size (64, false), i); - cil_stack_push (exp, CIL_STACK_TYPE_INT64); + cil_stack_push (exp, CIL_STYPE_INT64); } static void @@ -414,7 +393,7 @@ parser_emit_ldc_r4 (gint32 f) const long *pf = (void *) &f; real_from_target_fmt (&real_value, pf, &ieee_single_format); tree exp = build_real (double_type_node, real_value); - cil_stack_push (exp, CIL_STACK_TYPE_F); + cil_stack_push (exp, CIL_STYPE_F); } static void @@ -424,31 +403,226 @@ parser_emit_ldc_r8 (gint64 f) const long *pf = (void *) &f; real_from_target_fmt (&real_value, pf, &ieee_double_format); tree exp = build_real (double_type_node, real_value); - cil_stack_push (exp, CIL_STACK_TYPE_F); + cil_stack_push (exp, CIL_STYPE_F); +} + +/********* binary numeric operations ****************/ + +/* + * BIN_OP: + * binop_code, binop_tag, tree_code_int, tree_code_f, handler_for_pointers + * + * handler_for_pointers is of type: tree (*) (tree,tree) + */ + +#define CIL_BINARY_NUMERIC_OPERATIONS \ + BIN_OP(add, ADD, PLUS_EXPR, PLUS_EXPR, parser_add_op_pointer_handler) \ + BIN_OP(sub, SUB, MINUS_EXPR, MINUS_EXPR, parser_sub_op_pointer_handler) \ + BIN_OP(mul, MUL, MULT_EXPR, MULT_EXPR, NULL) \ + BIN_OP(div, DIV, TRUNC_DIV_EXPR, RDIV_EXPR, NULL) \ + BIN_OP(rem, REM, TRUNC_MOD_EXPR, ERROR_MARK, NULL) + + +enum cil_bin_op { +#define BIN_OP(binop_code, binop_tag, tree_code_int, tree_code_f, handler_for_pointers) \ + BINARY_NUMERIC_OPERATION_ ## binop_tag , + CIL_BINARY_NUMERIC_OPERATIONS + BINARY_NUMERIC_OPERATION_NUM_OPS +#undef BIN_OP +}; + + +static CilStackType +parser_get_binary_numeric_operations_type (enum cil_bin_op bin_op, CilStackType opA_type, CilStackType opB_type) +{ + if (opA_type == CIL_STYPE_ERROR || opB_type == CIL_STYPE_ERROR) + { + return CIL_STYPE_ERROR; + } + else + { + gcc_assert (opA_type < CIL_STYPE_ERROR); + gcc_assert (opB_type < CIL_STYPE_ERROR); + const CilStackType table[6][6] = { + { CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_MP, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_INT64, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_MP, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_F, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_MP, CIL_STYPE_ERROR, CIL_STYPE_MP, CIL_STYPE_ERROR, CIL_STYPE_NINT, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + }; + CilStackType ret = table[opA_type][opB_type]; + if (ret == CIL_STYPE_ERROR) + { + switch (bin_op) + { + case BINARY_NUMERIC_OPERATION_SUB: + if ( (opA_type == CIL_STYPE_MP) + && (opB_type == CIL_STYPE_MP)) + ret = CIL_STYPE_NINT; + + /* ... fall through ... */ + + case BINARY_NUMERIC_OPERATION_ADD: + if ( (opA_type == CIL_STYPE_MP) + || (opB_type == CIL_STYPE_MP)) + ret = CIL_STYPE_MP; + break; + default: + break; + } + } + return ret; + } +} + + +static tree +parser_add_op_pointer_handler(tree opA, tree opB) +{ + tree exp = NULL_TREE; + enum tree_code opcode; + int pA = POINTER_TYPE_P (TREE_TYPE(opA)); + int pB = POINTER_TYPE_P (TREE_TYPE(opB)); + + gcc_assert (pA || pB); + if (pA && !pB) + { + opcode = POINTER_PLUS_EXPR; + opB = convert (unsigned_type_node, opB); + exp = build2 (opcode, TREE_TYPE (opA), opA, opB); + } + else if (!pA && pB) + { + opcode = POINTER_PLUS_EXPR; + opB = convert(unsigned_type_node, opA); + exp = build2 (opcode, TREE_TYPE (opB), opB, opA); + } + else + { + gcc_unreachable (); + } + + return exp; +} + + +static tree +parser_sub_op_pointer_handler(tree opA, tree opB) +{ + tree exp = NULL_TREE; + enum tree_code opcode; + int pA = POINTER_TYPE_P (TREE_TYPE(opA)); + int pB = POINTER_TYPE_P (TREE_TYPE(opB)); + + gcc_assert (pA || pB); + if (pA && !pB) + { + opcode = POINTER_PLUS_EXPR; + opB = convert(unsigned_type_node, opB); + opB = build1(NEGATE_EXPR, TREE_TYPE(opB), opB); + exp = build2 (opcode, TREE_TYPE (opA), opA, opB); + } + else if (!pA && pB) + { + opcode = POINTER_PLUS_EXPR; + opB = convert(unsigned_type_node, opA); + opA = build1(NEGATE_EXPR, TREE_TYPE(opA), opA); + exp = build2 (opcode, TREE_TYPE (opB), opB, opA); + } + else + { + gcc_assert (TREE_TYPE (opA) == TREE_TYPE (opB)); + opcode = MINUS_EXPR; + tree elem_t = TREE_TYPE( TREE_TYPE (opA)); /* FIXME arrays ?*/ + opA = convert (integer_type_node, opA); + opB = convert (integer_type_node, opB); + exp = build2 (opcode, TREE_TYPE (opA), opA, opB); + exp = build2 (EXACT_DIV_EXPR, elem_t, exp, TYPE_SIZE_UNIT (integer_type_node)); + } + + return exp; +} + + +static void +parser_emit_binary_numeric_operation(enum cil_bin_op bin_op, + const char* opname, + enum tree_code opcode_i, + enum tree_code opcode_f, + tree (*pointers_handler)(tree,tree)) +{ + CilStackType opB_type; + tree opB = cil_stack_pop (&opB_type); + CilStackType opA_type; + tree opA = cil_stack_pop (&opA_type); + CilStackType result_stack_type = parser_get_binary_numeric_operations_type (bin_op, opA_type, opB_type); + if (result_stack_type == CIL_STYPE_ERROR) + { + error ("Wrong operand types for %s\n", opname); + } + int pA = POINTER_TYPE_P (TREE_TYPE(opA)); + int pB = POINTER_TYPE_P (TREE_TYPE(opB)); + tree exp = NULL_TREE; + switch (result_stack_type) + { + case CIL_STYPE_INT64: + /* ... FALL THROUGH ...*/ + + case CIL_STYPE_INT32: + gcc_assert( !pA && !pB); + exp = build2 (opcode_i, TREE_TYPE (opA), opA, opB); + break; + + case CIL_STYPE_F: + gcc_assert( !pA && !pB); + exp = build2 (opcode_f, TREE_TYPE (opA), opA, opB); + break; + + case CIL_STYPE_NINT: + if (!pA && !pB) + { + exp = build2 (opcode_i, TREE_TYPE (opA), opA, opB); + break; + } + + /* ... FALL THROUGH ...*/ + + case CIL_STYPE_MP: + if (!pA && !pB) + { + gcc_unreachable (); + break; + } + + /* case of pointers */ + if (!pointers_handler) + { + gcc_unreachable(); + } + exp = (*pointers_handler)(opA, opB); + + break; + default: + gcc_unreachable (); + } + cil_stack_push (exp, result_stack_type); } -#define TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION(name,tree_code,tree_code_float) \ + +/* emit the functions here */ +#define BIN_OP(binop_code, binop_tag, tree_code_int, tree_code_f, handler_for_pointers) \ static void \ -parser_emit_##name (void) \ +parser_emit_ ## binop_code (void) \ { \ - CilStackType opB_type; \ - tree opB = cil_stack_pop (&opB_type); \ - CilStackType opA_type; \ - tree opA = cil_stack_pop (&opA_type); \ - CilStackType result_type = parser_get_binary_numeric_operations_type (opA_type, opB_type); \ - if (result_type == CIL_STACK_TYPE_ERROR) \ - { \ - error ("Wrong operand types for "#name); \ - } \ - tree exp = build2 (result_type == CIL_STACK_TYPE_F ? tree_code_float : tree_code, cil_stack_get_tree_type_for_cil_stack_type (result_type), opA, opB); \ - cil_stack_push (exp, result_type); \ + parser_emit_binary_numeric_operation(BINARY_NUMERIC_OPERATION_ ## binop_tag, #binop_code, tree_code_int, tree_code_f, handler_for_pointers); \ } -TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION (add, PLUS_EXPR, PLUS_EXPR) -TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION (sub, MINUS_EXPR, MINUS_EXPR) -TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION (mul, MULT_EXPR, MULT_EXPR) -TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION (div, TRUNC_DIV_EXPR, RDIV_EXPR) -TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION (rem, TRUNC_MOD_EXPR, (gcc_unreachable (), ERROR_MARK /* TODO */)) -#undef TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_OPERATION +CIL_BINARY_NUMERIC_OPERATIONS +#undef BIN_OP + + +#undef CIL_BINARY_NUMERIC_OPERATIONS +/********* END binary numeric operations ****************/ static void parser_emit_min (void) @@ -481,30 +655,46 @@ parser_emit_abs (void) cil_stack_push (exp, op_type); } + +/********* integer operations ****************/ + +#define CIL_INTEGER_OPERATIONS \ + INT_OP(div_un, UNSIGNED, TRUNC_DIV_EXPR) \ + INT_OP(rem_un, UNSIGNED, TRUNC_MOD_EXPR) \ + INT_OP(and, SIGNED, BIT_AND_EXPR) \ + INT_OP(or, SIGNED, BIT_IOR_EXPR) \ + INT_OP(xor, SIGNED, BIT_XOR_EXPR) + + + static CilStackType parser_get_integer_operations_type_tree (CilStackType opA_type, CilStackType opB_type) { - if (opA_type == CIL_STACK_TYPE_ERROR || opB_type == CIL_STACK_TYPE_ERROR) + if (opA_type == CIL_STYPE_ERROR || opB_type == CIL_STYPE_ERROR) { - return CIL_STACK_TYPE_ERROR; + return CIL_STYPE_ERROR; } else { - gcc_assert (opA_type < CIL_STACK_TYPE_ERROR); - gcc_assert (opB_type < CIL_STACK_TYPE_ERROR); - const CilStackType table[6][6] = { - { CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT64, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, + static CilStackType table[6][6] = { + { CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_INT64, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, }; + gcc_assert (opA_type < CIL_STYPE_ERROR); + gcc_assert (opB_type < CIL_STYPE_ERROR); return table[opA_type][opB_type]; } } -#define TEMPLATE_PARSER_EMIT_INTEGER_OPERATION(name,tree_code,unsignedp) \ +/* create 'emit'fonctions */ +#define SIGNED(t) +#define UNSIGNED(t) t = convert (cil_unsigned_or_pointer_type (TREE_TYPE (t)), (t)); + +#define INT_OP(name, CONVERT, OPCODE) \ static void \ parser_emit_##name (void) \ { \ @@ -513,22 +703,35 @@ parser_emit_##name (void) \ CilStackType opA_type; \ tree opA = cil_stack_pop (&opA_type); \ CilStackType result_type = parser_get_integer_operations_type_tree (opA_type, opB_type); \ - if (result_type == CIL_STACK_TYPE_ERROR) \ + if (result_type == CIL_STYPE_ERROR) \ { \ error ("Wrong operand types for "#name); \ } \ - tree result_type_tree = unsignedp ? cil_unsigned_or_pointer_type (cil_stack_get_tree_type_for_cil_stack_type (result_type)) : cil_stack_get_tree_type_for_cil_stack_type (result_type); \ - tree opA_converted = unsignedp ? convert (cil_unsigned_or_pointer_type (TREE_TYPE (opA)), opA) : opA; \ - tree opB_converted = unsignedp ? convert (cil_unsigned_or_pointer_type (TREE_TYPE (opB)), opB) : opB; \ - tree exp = build2 (tree_code, result_type_tree, opA_converted, opB_converted); \ + CONVERT (opA) \ + CONVERT (opB) \ + if (result_type == CIL_STYPE_NINT) \ + { \ + int pA = POINTER_TYPE_P (TREE_TYPE(opA)); \ + int pB = POINTER_TYPE_P (TREE_TYPE(opB)); \ + if (pA) opA = convert (unsigned_type_node, opA); \ + if (pB) opB = convert (unsigned_type_node, opB); \ + } \ + tree exp = build2 (OPCODE, TREE_TYPE (opA), opA, opB); \ cil_stack_push (exp, result_type); \ } -TEMPLATE_PARSER_EMIT_INTEGER_OPERATION(div_un, TRUNC_DIV_EXPR, true) -TEMPLATE_PARSER_EMIT_INTEGER_OPERATION(rem_un, TRUNC_MOD_EXPR, true) -TEMPLATE_PARSER_EMIT_INTEGER_OPERATION(and, BIT_AND_EXPR, false) -TEMPLATE_PARSER_EMIT_INTEGER_OPERATION(or, BIT_IOR_EXPR, false) -TEMPLATE_PARSER_EMIT_INTEGER_OPERATION(xor, BIT_XOR_EXPR, false) -#undef TEMPLATE_PARSER_EMIT_INTEGER_OPERATION + +/* the code is emitted here: */ +CIL_INTEGER_OPERATIONS; + +#undef INT_OP +#undef SIGNED +#undef UNSIGNED +#undef CIL_INTEGER_OPERATIONS + + + +/********* end of integer operations ****************/ + static void parser_emit_neg (void) @@ -602,7 +805,7 @@ parser_emit_ldloca (guint16 local) { tree local_decl = cil_bindings_get_local (local); tree exp_addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (local_decl)), local_decl); - cil_stack_push (cil_bindings_output_statements_and_create_temp (exp_addr), CIL_STACK_TYPE_MANAGED_POINTER); + cil_stack_push (cil_bindings_output_statements_and_create_temp (exp_addr), CIL_STYPE_MP); } static void @@ -617,7 +820,7 @@ parser_emit_ldarga (guint16 arg) { tree arg_decl = cil_bindings_get_arg (arg); tree exp_addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg_decl)), arg_decl); - cil_stack_push (cil_bindings_output_statements_and_create_temp (exp_addr), CIL_STACK_TYPE_MANAGED_POINTER); + cil_stack_push (cil_bindings_output_statements_and_create_temp (exp_addr), CIL_STYPE_MP); } static void @@ -657,9 +860,7 @@ parser_emit_call (MonoMethod *caller, guint32 token) { MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoMethod *called = mono_get_method (image, token, NULL); - TRACE_IMPL ({ char *s = mono_method_full_name (called, true); printf (" %s", s); free (s); }); MonoMethodSignature *signature = mono_method_get_signature_full (called, image, token, NULL); - TRACE_IMPL ({ char *s = mono_signature_get_desc (signature, true); printf (" %s", s); free (s); }); MonoClass *called_klass = mono_method_get_class (called); if ( strcmp ("Crt", mono_class_get_name (called_klass)) == 0 @@ -743,7 +944,6 @@ parser_emit_calli (MonoMethod *caller, guint32 token) { MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoMethodSignature *signature = mono_metadata_parse_signature (image, token); - TRACE_IMPL ({ char *s = mono_signature_get_desc (signature, true); printf (" %s", s); free (s); }); tree ftn_tree = cil_stack_pop (NULL); tree signature_type_tree = parser_signature_tree (signature, NULL); @@ -785,8 +985,6 @@ parser_emit_ldftn (MonoMethod *caller, guint32 token) { MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoMethod *called = mono_get_method (image, token, NULL); - TRACE_IMPL ({ char *s = mono_method_full_name (called, true); printf (" %s", s); free (s); }); - TRACE_IMPL ({ MonoMethodSignature *signature = mono_method_get_signature_full (called, image, token, NULL); char *s = mono_signature_get_desc (signature, true); printf (" %s", s); free (s); }); tree called_addr_tree; if (parser_get_method_mode (called) == GCC_CIL_METHOD_MODE_PINVOKE) { @@ -797,7 +995,7 @@ parser_emit_ldftn (MonoMethod *caller, guint32 token) tree called_tree = parser_get_method_tree (called); called_addr_tree = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (called_tree)), called_tree); } - cil_stack_push (cil_bindings_output_statements_and_create_temp (called_addr_tree), CIL_STACK_TYPE_NATIVE_INT); + cil_stack_push (cil_bindings_output_statements_and_create_temp (called_addr_tree), CIL_STYPE_NINT); } static tree @@ -871,7 +1069,6 @@ parser_emit_ldsfld (MonoMethod *caller, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoClass *klass = NULL; MonoClassField *field = mono_field_from_token (image, token, &klass, NULL); - TRACE_IMPL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf (" %s:%s", s, mono_field_get_name (field)); free (s); }); tree exp = parser_build_static_field_ref_tree (field); if (parser_current_prefix.bolatile) { @@ -886,7 +1083,6 @@ parser_emit_stsfld (MonoMethod *caller, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoClass *klass = NULL; MonoClassField *field = mono_field_from_token (image, token, &klass, NULL); - TRACE_IMPL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf (" %s:%s", s, mono_field_get_name (field)); free (s); }); tree field_ref = parser_build_static_field_ref_tree (field); if (parser_current_prefix.bolatile) { @@ -914,9 +1110,9 @@ parser_emit_ldsflda (MonoMethod *caller, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoClass *klass = NULL; MonoClassField *field = mono_field_from_token (image, token, &klass, NULL); - TRACE_IMPL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf (" %s:%s", s, mono_field_get_name (field)); free (s); }); tree exp_addr = parser_build_static_field_address_tree (field); - cil_stack_push (exp_addr, CIL_STACK_TYPE_MANAGED_POINTER); /* FIXME: the type should be CIL_STACK_TYPE_NATIVE_INT if the object memory is unmanaged */ + /* FIXME: the type should be CIL_STYPE_NINT if the object memory is unmanaged */ + cil_stack_push (exp_addr, CIL_STYPE_MP); } static tree @@ -938,7 +1134,6 @@ parser_emit_stfld (MonoMethod *caller, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoClass *klass = NULL; MonoClassField *field = mono_field_from_token (image, token, &klass, NULL); - TRACE_IMPL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf (" %s:%s", s, mono_field_get_name (field)); free (s); }); tree value_tree = cil_stack_pop (NULL); tree dst_obj_ptr_tree = cil_stack_pop (NULL); tree field_ref = parser_build_field_ref_tree (field, dst_obj_ptr_tree); @@ -960,7 +1155,6 @@ parser_emit_ldfld (MonoMethod *caller, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoClass *klass = NULL; MonoClassField *field = mono_field_from_token (image, token, &klass, NULL); - TRACE_IMPL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf (" %s:%s", s, mono_field_get_name (field)); free (s); }); tree src_obj_ptr_tree = cil_stack_pop (NULL); tree field_ref = parser_build_field_ref_tree (field, src_obj_ptr_tree); if (parser_current_prefix.bolatile) @@ -976,12 +1170,12 @@ parser_emit_ldflda (MonoMethod *caller, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (caller)); MonoClass *klass = NULL; MonoClassField *field = mono_field_from_token (image, token, &klass, NULL); - TRACE_IMPL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf (" %s:%s", s, mono_field_get_name (field)); free (s); }); CilStackType src_obj_ptr_type; tree src_obj_ptr_tree = cil_stack_pop (&src_obj_ptr_type); tree field_ref = parser_build_field_ref_tree (field, src_obj_ptr_tree); tree field_ref_addr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (field_ref)), field_ref); - cil_stack_push (cil_bindings_output_statements_and_create_temp (field_ref_addr), src_obj_ptr_type == CIL_STACK_TYPE_NATIVE_INT ? CIL_STACK_TYPE_NATIVE_INT : CIL_STACK_TYPE_MANAGED_POINTER); + cil_stack_push (cil_bindings_output_statements_and_create_temp (field_ref_addr), + src_obj_ptr_type == CIL_STYPE_NINT ? CIL_STYPE_NINT : CIL_STYPE_MP); } static void @@ -991,7 +1185,6 @@ parser_emit_ldobj (MonoMethod *method, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (method)); MonoClass *klass = mono_class_get (image, token); MonoType *type = mono_class_get_type (klass); - TRACE_IMPL ({ char *s = mono_type_full_name (type); printf (" %s", s); free (s); }); tree type_tree = parser_get_type_tree (type); tree src_tree = cil_stack_pop (NULL); tree converted_src_tree = convert (build_pointer_type (type_tree), src_tree); @@ -1002,7 +1195,7 @@ parser_emit_ldobj (MonoMethod *method, guint32 token) { value_tree = parser_build_volatile_reference_tree (value_tree); } - cil_stack_push (cil_bindings_output_statements_and_create_temp (value_tree), CIL_STACK_TYPE_OBJECT); + cil_stack_push (cil_bindings_output_statements_and_create_temp (value_tree), CIL_STYPE_OBJECT); } else { @@ -1018,7 +1211,6 @@ parser_emit_stobj (MonoMethod *method, guint32 token) MonoImage *image = mono_class_get_image (mono_method_get_class (method)); MonoClass *klass = mono_class_get (image, token); MonoType *type = mono_class_get_type (klass); - TRACE_IMPL ({ char *s = mono_type_full_name (type); printf (" %s", s); free (s); }); tree type_tree = parser_get_type_tree (type); tree value_tree = cil_stack_pop (NULL); tree dest_ptr_tree = cil_stack_pop (NULL); @@ -1050,17 +1242,17 @@ parser_emit_conv_##name (void) \ tree converted_exp = convert (type_tree, exp); \ cil_stack_push (converted_exp, stack_type); \ } -TEMPLATE_PARSER_EMIT_CONV (i, integer_type_node, CIL_STACK_TYPE_NATIVE_INT) -TEMPLATE_PARSER_EMIT_CONV (i1, cil_type_for_size (8, false), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_CONV (u1, cil_type_for_size (8, true), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_CONV (i2, cil_type_for_size (16, false), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_CONV (u2, cil_type_for_size (16, true), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_CONV (i4, cil_type_for_size (32, false), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_CONV (u4, cil_type_for_size (32, true), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_CONV (i8, cil_type_for_size (64, false), CIL_STACK_TYPE_INT64) -TEMPLATE_PARSER_EMIT_CONV (u8, cil_type_for_size (64, true), CIL_STACK_TYPE_INT64) -TEMPLATE_PARSER_EMIT_CONV (r4, float_type_node, CIL_STACK_TYPE_F) -TEMPLATE_PARSER_EMIT_CONV (r8, double_type_node, CIL_STACK_TYPE_F) +TEMPLATE_PARSER_EMIT_CONV (i, integer_type_node, CIL_STYPE_NINT) +TEMPLATE_PARSER_EMIT_CONV (i1, cil_type_for_size (8, false), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_CONV (u1, cil_type_for_size (8, true), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_CONV (i2, cil_type_for_size (16, false), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_CONV (u2, cil_type_for_size (16, true), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_CONV (i4, cil_type_for_size (32, false), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_CONV (u4, cil_type_for_size (32, true), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_CONV (i8, cil_type_for_size (64, false), CIL_STYPE_INT64) +TEMPLATE_PARSER_EMIT_CONV (u8, cil_type_for_size (64, true), CIL_STYPE_INT64) +TEMPLATE_PARSER_EMIT_CONV (r4, float_type_node, CIL_STYPE_F) +TEMPLATE_PARSER_EMIT_CONV (r8, double_type_node, CIL_STYPE_F) #undef TEMPLATE_PARSER_EMIT_CONV static void @@ -1069,7 +1261,7 @@ parser_emit_conv_r_un (void) tree exp = cil_stack_pop (NULL); tree exp_un = convert (cil_unsigned_or_pointer_type (TREE_TYPE (exp)), exp); tree converted_exp = convert (double_type_node, exp_un); - cil_stack_push (converted_exp, CIL_STACK_TYPE_F); + cil_stack_push (converted_exp, CIL_STYPE_F); } #define TEMPLATE_PARSER_EMIT_LDIND(name, elem_type_tree, stack_type) \ @@ -1088,15 +1280,15 @@ parser_emit_ldind_##name (void) \ tree converted_value_tree = convert (stack_type_tree, value_tree); \ cil_stack_push (cil_bindings_output_statements_and_create_temp (converted_value_tree), stack_type); /* TODO: unnecesary? */\ } -TEMPLATE_PARSER_EMIT_LDIND (i, integer_type_node, CIL_STACK_TYPE_NATIVE_INT) -TEMPLATE_PARSER_EMIT_LDIND (i1, cil_type_for_size (8, false), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_LDIND (u1, cil_type_for_size (8, true), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_LDIND (i2, cil_type_for_size (16, false), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_LDIND (u2, cil_type_for_size (16, true), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_LDIND (i4, cil_type_for_size (32, false), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_LDIND (u4, cil_type_for_size (32, true), CIL_STACK_TYPE_INT32) -TEMPLATE_PARSER_EMIT_LDIND (r4, float_type_node, CIL_STACK_TYPE_F) -TEMPLATE_PARSER_EMIT_LDIND (r8, double_type_node, CIL_STACK_TYPE_F) +TEMPLATE_PARSER_EMIT_LDIND (i, integer_type_node, CIL_STYPE_NINT) +TEMPLATE_PARSER_EMIT_LDIND (i1, cil_type_for_size (8, false), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_LDIND (u1, cil_type_for_size (8, true), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_LDIND (i2, cil_type_for_size (16, false), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_LDIND (u2, cil_type_for_size (16, true), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_LDIND (i4, cil_type_for_size (32, false), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_LDIND (u4, cil_type_for_size (32, true), CIL_STYPE_INT32) +TEMPLATE_PARSER_EMIT_LDIND (r4, float_type_node, CIL_STYPE_F) +TEMPLATE_PARSER_EMIT_LDIND (r8, double_type_node, CIL_STYPE_F) #undef TEMPLATE_PARSER_EMIT_LDIND #define TEMPLATE_PARSER_EMIT_STIND(name, value_type_tree) \ @@ -1138,61 +1330,24 @@ parser_emit_dup (void) cil_stack_push (value, type); } -static void -parser_promote_to_same_type (tree *a, CilStackType *a_type, tree *b, CilStackType *b_type) -{ - CilStackType new_type; - - if (*a_type == CIL_STACK_TYPE_F || *b_type == CIL_STACK_TYPE_F) - { - new_type = CIL_STACK_TYPE_F; - } - else if (*a_type == CIL_STACK_TYPE_NATIVE_INT || *b_type == CIL_STACK_TYPE_NATIVE_INT) - { - new_type = CIL_STACK_TYPE_NATIVE_INT; - } - else if (*a_type == CIL_STACK_TYPE_MANAGED_POINTER || *b_type == CIL_STACK_TYPE_MANAGED_POINTER) - { - new_type = CIL_STACK_TYPE_MANAGED_POINTER; - } - else if (*a_type == CIL_STACK_TYPE_INT32 || *b_type == CIL_STACK_TYPE_INT32) - { - new_type = CIL_STACK_TYPE_INT32; - } - else if (*a_type == CIL_STACK_TYPE_INT64 || *b_type == CIL_STACK_TYPE_INT64) - { - new_type = CIL_STACK_TYPE_INT64; - } - else - { - gcc_assert (*a_type == CIL_STACK_TYPE_OBJECT || *a_type == CIL_STACK_TYPE_ERROR); - new_type = *a_type; - } - - *a = convert (cil_stack_get_tree_type_for_cil_stack_type (new_type), *a); - *b = convert (cil_stack_get_tree_type_for_cil_stack_type (new_type), *b); - *a_type = new_type; - *b_type = new_type; -} - static CilStackType parser_get_binary_numeric_comparisons_type (CilStackType opA_type, CilStackType opB_type) { - if (opA_type == CIL_STACK_TYPE_ERROR || opB_type == CIL_STACK_TYPE_ERROR) + if (opA_type == CIL_STYPE_ERROR || opB_type == CIL_STYPE_ERROR) { - return CIL_STACK_TYPE_ERROR; + return CIL_STYPE_ERROR; } else { - gcc_assert (opA_type < CIL_STACK_TYPE_ERROR); - gcc_assert (opB_type < CIL_STACK_TYPE_ERROR); + gcc_assert (opA_type < CIL_STYPE_ERROR); + gcc_assert (opB_type < CIL_STYPE_ERROR); const CilStackType table[6][6] = { - { CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32 }, + { CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_INT32 }, }; return table[opA_type][opB_type]; } @@ -1207,24 +1362,30 @@ parser_emit_##name (void) \ CilStackType opA_type; \ tree opA = cil_stack_pop (&opA_type); \ CilStackType result_type = parser_get_binary_numeric_comparisons_type (opA_type, opB_type); \ - if (result_type == CIL_STACK_TYPE_ERROR) \ + if (result_type == CIL_STYPE_ERROR) \ { \ error ("Wrong operand types for "#name); \ } \ tree result_type_tree = cil_stack_get_tree_type_for_cil_stack_type (result_type); \ - parser_promote_to_same_type (&opA, &opA_type, &opB, &opB_type); /* operands to gcc ompariosons must have the same type (otherwise some optimizations fail) */ \ - if (opA_type == CIL_STACK_TYPE_F) \ + if (TREE_TYPE (opA) != TREE_TYPE (opB)) \ { \ - gcc_assert (opB_type == CIL_STACK_TYPE_F); \ + int iA = (TREE_CODE (TREE_TYPE (opA)) == INTEGER_TYPE); \ + int iB = (TREE_CODE (TREE_TYPE (opB)) == INTEGER_TYPE); \ + if (!iA && iB) opA = convert(TREE_TYPE (opB), opA); \ + opB = convert(TREE_TYPE (opA), opB); \ + } \ + if (opA_type == CIL_STYPE_F) \ + { \ + gcc_assert (opB_type == CIL_STYPE_F); \ tree exp = build2 (tree_code_float, result_type_tree, opA, opB); \ - cil_stack_push (exp, CIL_STACK_TYPE_INT32); \ + cil_stack_push (exp, CIL_STYPE_INT32); \ } \ else \ { \ tree opA_converted = unsignedp ? convert (cil_unsigned_or_pointer_type (TREE_TYPE (opA)), opA) : opA; \ tree opB_converted = unsignedp ? convert (cil_unsigned_or_pointer_type (TREE_TYPE (opB)), opB) : opB; \ tree exp = build2 (tree_code, result_type_tree, opA_converted, opB_converted); \ - cil_stack_push (exp, CIL_STACK_TYPE_INT32); \ + cil_stack_push (exp, CIL_STYPE_INT32); \ } \ } TEMPLATE_PARSER_EMIT_BINARY_NUMERIC_COMPARISON(clt_un, LT_EXPR, UNLT_EXPR, true) @@ -1238,7 +1399,6 @@ static void parser_emit_br (const unsigned char *ip, gint32 offset, CILLabelsMap *labels) { const unsigned char *target_ip = ip + offset; - TRACE_IMPL (printf (" IL%p", target_ip)); tree label_decl_tree = cil_labels_set_get_label (labels, target_ip); tree goto_expr_tree = build1 (GOTO_EXPR, void_type_node, label_decl_tree); cil_bindings_output_statements (goto_expr_tree); @@ -1248,7 +1408,6 @@ static void parser_emit_brfalse (const unsigned char *ip, gint32 offset, CILLabelsMap *labels) { const unsigned char *target_ip = ip + offset; - TRACE_IMPL (printf (" IL%p", target_ip)); tree expr_tree = cil_stack_pop (NULL); tree condition_value_tree = build2 (EQ_EXPR, integer_type_node, expr_tree, convert (TREE_TYPE (expr_tree), integer_zero_node)); tree goto_expr_tree = build1 (GOTO_EXPR, void_type_node, cil_labels_set_get_label (labels, target_ip)); @@ -1260,7 +1419,6 @@ static void parser_emit_brtrue (const unsigned char *ip, gint32 offset, CILLabelsMap *labels) { const unsigned char *target_ip = ip + offset; - TRACE_IMPL (printf (" IL%p", target_ip)); tree expr_tree = cil_stack_pop (NULL); tree condition_value_tree = build2 (NE_EXPR, integer_type_node, expr_tree, convert (TREE_TYPE (expr_tree), integer_zero_node)); tree goto_expr_tree = build1 (GOTO_EXPR, void_type_node, cil_labels_set_get_label (labels, target_ip)); @@ -1295,9 +1453,9 @@ parser_emit_bge (const unsigned char *ip, gint32 offset, CILLabelsMap *labels) cil_stack_peek (0, &opB_type); CilStackType opA_type; cil_stack_peek (1, &opA_type); - if (opA_type == CIL_STACK_TYPE_F) + if (opA_type == CIL_STYPE_F) { - gcc_assert (opB_type == CIL_STACK_TYPE_F); + gcc_assert (opB_type == CIL_STYPE_F); parser_emit_clt_un (); parser_emit_brfalse (ip, offset, labels); } @@ -1315,9 +1473,9 @@ parser_emit_bge_un (const unsigned char *ip, gint32 offset, CILLabelsMap *labels cil_stack_peek (0, &opB_type); CilStackType opA_type; cil_stack_peek (1, &opA_type); - if (opA_type == CIL_STACK_TYPE_F) + if (opA_type == CIL_STYPE_F) { - gcc_assert (opB_type == CIL_STACK_TYPE_F); + gcc_assert (opB_type == CIL_STYPE_F); parser_emit_clt (); parser_emit_brfalse (ip, offset, labels); } @@ -1335,9 +1493,9 @@ parser_emit_ble (const unsigned char *ip, gint32 offset, CILLabelsMap *labels) cil_stack_peek (0, &opB_type); CilStackType opA_type; cil_stack_peek (1, &opA_type); - if (opA_type == CIL_STACK_TYPE_F) + if (opA_type == CIL_STYPE_F) { - gcc_assert (opB_type == CIL_STACK_TYPE_F); + gcc_assert (opB_type == CIL_STYPE_F); parser_emit_cgt_un (); parser_emit_brfalse (ip, offset, labels); } @@ -1355,9 +1513,9 @@ parser_emit_ble_un (const unsigned char *ip, gint32 offset, CILLabelsMap *labels cil_stack_peek (0, &opB_type); CilStackType opA_type; cil_stack_peek (1, &opA_type); - if (opA_type == CIL_STACK_TYPE_F) + if (opA_type == CIL_STYPE_F) { - gcc_assert (opB_type == CIL_STACK_TYPE_F); + gcc_assert (opB_type == CIL_STYPE_F); parser_emit_cgt (); parser_emit_brfalse (ip, offset, labels); } @@ -1457,27 +1615,27 @@ parser_emit_localloc (void) tree size_tree = convert (cil_type_for_size (32, true), cil_stack_pop (NULL)); tree alloca_arglist = tree_cons (NULL_TREE, size_tree, NULL_TREE); tree call_alloca_tree = build_function_call_expr (built_in_decls[BUILT_IN_ALLOCA], alloca_arglist); - cil_stack_push (cil_bindings_output_statements_and_create_temp (call_alloca_tree), CIL_STACK_TYPE_NATIVE_INT); + cil_stack_push (cil_bindings_output_statements_and_create_temp (call_alloca_tree), CIL_STYPE_NINT); } static CilStackType parser_get_shift_operations_type (CilStackType op_type, CilStackType shift_type) { - if (op_type == CIL_STACK_TYPE_ERROR || shift_type == CIL_STACK_TYPE_ERROR) + if (op_type == CIL_STYPE_ERROR || shift_type == CIL_STYPE_ERROR) { - return CIL_STACK_TYPE_ERROR; + return CIL_STYPE_ERROR; } else { - gcc_assert (op_type < CIL_STACK_TYPE_ERROR); - gcc_assert (shift_type < CIL_STACK_TYPE_ERROR); + gcc_assert (op_type < CIL_STYPE_ERROR); + gcc_assert (shift_type < CIL_STYPE_ERROR); const CilStackType table[6][6] = { - { CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT32, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_INT64, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_INT64, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_NATIVE_INT, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, - { CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR, CIL_STACK_TYPE_ERROR }, + { CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_INT32, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_INT64, CIL_STYPE_ERROR, CIL_STYPE_INT64, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_NINT, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, + { CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR, CIL_STYPE_ERROR }, }; return table[op_type][shift_type]; } @@ -1492,7 +1650,7 @@ parser_emit_##name (void) \ CilStackType value_type; \ tree value_tree = cil_stack_pop (&value_type); \ CilStackType result_type = parser_get_shift_operations_type (value_type, shiftamount_type); \ - if (result_type == CIL_STACK_TYPE_ERROR) \ + if (result_type == CIL_STYPE_ERROR) \ { \ error ("Wrong operand types for "#name); \ } \ @@ -1520,6 +1678,90 @@ parser_set_location_from_ip (MonoMethod *m, const unsigned char *ip) #endif } + +static CILLabelsMap * +preparse_method_labels(unsigned const char *code, unsigned const char *code_end, CILLabelsMap *labels) +{ + unsigned const char *ip = code; + while (ip < code_end) + { + MonoOpcodeEnum opcode = mono_opcode_value (&ip, code_end); + ++ip; + + gint64 arg_int64; + gint32 arg_int32; + gint16 arg_int16; + gint8 arg_int8; + guint32 arg_token = 0; +#define read_arg(a) a = *((typeof (a) *) ip); ip += sizeof (a); + switch (mono_opcodes [opcode].argument) + { + case MonoInlineNone: + break; + case MonoInlineType: + case MonoInlineField: + case MonoInlineMethod: + case MonoInlineTok: + case MonoInlineSig: + read_arg (arg_token); + break; + case MonoInlineString: + /* TODO */ + ip += 4; + break; + case MonoInlineVar: + read_arg (arg_int16); + break; + case MonoShortInlineVar: + read_arg (arg_int8); + break; + case MonoInlineBrTarget: + read_arg (arg_int32); + /* set label */ + cil_labels_set_get_label (labels, ip + arg_int32); + break; + case MonoShortInlineBrTarget: + read_arg (arg_int8); + /* set label */ + cil_labels_set_get_label (labels, ip + ((gint32) arg_int8)); + break; + case MonoInlineSwitch: + { + read_arg (arg_int32); + const gint32 sval = arg_int32; + gint32 i; + for (i = 0; i < sval; ++i) + { + read_arg (arg_int32); + /* set the label */ + cil_labels_set_get_label (labels, ip + arg_int32); + } + break; + } + case MonoInlineR: + read_arg (arg_int64); + break; + case MonoShortInlineR: + read_arg (arg_int32); + break; + case MonoInlineI: + read_arg (arg_int32); + break; + case MonoShortInlineI: + read_arg (arg_int8); + break; + case MonoInlineI8: + read_arg (arg_int64); + break; + + default: + g_assert_not_reached (); + } + } + + return labels; +} + static void parse_method_code (MonoMethod *method) { @@ -1527,9 +1769,6 @@ parse_method_code (MonoMethod *method) guint32 code_size; guint32 max_stack; const unsigned char *const code = mono_method_header_get_code (header, &code_size, &max_stack); - TRACE_IMPL (printf ("\t\tCode size: %d\n", code_size)); - TRACE_IMPL (printf ("\t\tMax stack: %d\n", max_stack)); - TRACE_IMPL (printf ("\t\tCode (addresss): %p\n", code)); gcc_assert (current_function_decl); @@ -1537,23 +1776,25 @@ parse_method_code (MonoMethod *method) cil_stack_init (); - CILLabelsMap *labels = cil_labels_set_new (); - parser_current_prefix = cil_opcode_prefix_empty; const unsigned char *ip = code; const unsigned char *const code_end = code + code_size; + + CILLabelsMap *labels = cil_labels_set_new (); + preparse_method_labels (code, code_end, labels); + while (ip < code_end) { parser_set_location_from_ip (method, ip); - /* TODO: emit labels only when actually needed (may not be worth the effort) */ - tree label_decl_tree = cil_labels_set_get_label (labels, ip); - tree label_expr_tree = build1 (LABEL_EXPR, void_type_node, label_decl_tree); - cil_bindings_output_statements (label_expr_tree); - TRACE_IMPL (printf ("\t\t\t%s: ", IDENTIFIER_POINTER (DECL_NAME (label_decl_tree)))); + tree label_decl_tree = cil_labels_get_label (labels, ip); + if (label_decl_tree) + { + tree label_expr_tree = build1 (LABEL_EXPR, void_type_node, label_decl_tree); + cil_bindings_output_statements (label_expr_tree); + } MonoOpcodeEnum opcode = mono_opcode_value (&ip, code_end); - TRACE_IMPL (printf ("%s", mono_opcode_name (opcode))); ++ip; gint64 arg_int64; @@ -1575,12 +1816,10 @@ parse_method_code (MonoMethod *method) break; case MONO_CEE_LDC_I4: read_arg (arg_int32); - TRACE_IMPL (printf (" %d", arg_int32)); parser_emit_ldc_i4 (arg_int32); break; case MONO_CEE_LDC_I4_S: read_arg (arg_int8); - TRACE_IMPL (printf (" %d", arg_int8)); parser_emit_ldc_i4 (arg_int8); break; case MONO_CEE_LDC_I4_M1: @@ -1615,17 +1854,14 @@ parse_method_code (MonoMethod *method) break; case MONO_CEE_LDC_R4: read_arg (arg_int32); - TRACE_IMPL (printf (" %x %f", arg_int32, *((float *) &arg_int32))); parser_emit_ldc_r4 (arg_int32); break; case MONO_CEE_LDC_R8: read_arg (arg_int64); - TRACE_IMPL (printf (" %llx %f", arg_int64, *(double *) &arg_int64)); parser_emit_ldc_r8 (arg_int64); break; case MONO_CEE_LDC_I8: read_arg (arg_int64); - TRACE_IMPL (printf (" %lld", arg_int64)); parser_emit_ldc_i8 (arg_int64); break; case MONO_CEE_ADD: @@ -1666,12 +1902,10 @@ parse_method_code (MonoMethod *method) break; case MONO_CEE_STLOC_S: read_arg (arg_uint8); - TRACE_IMPL (printf (" %d", arg_uint8)); parser_emit_stloc (arg_uint8); break; case MONO_CEE_STLOC: read_arg (arg_uint16); - TRACE_IMPL (printf (" %d", arg_uint16)); parser_emit_stloc (arg_uint16); break; case MONO_CEE_LDLOC_0: @@ -1688,37 +1922,30 @@ parse_method_code (MonoMethod *method) break; case MONO_CEE_LDLOC_S: read_arg (arg_uint8); - TRACE_IMPL (printf (" %d", arg_uint8)); parser_emit_ldloc (arg_uint8); break; case MONO_CEE_LDLOC: read_arg (arg_uint16); - TRACE_IMPL (printf (" %d", arg_uint16)); parser_emit_ldloc (arg_uint16); break; case MONO_CEE_LDLOCA_S: read_arg (arg_uint8); - TRACE_IMPL (printf (" %d", arg_uint8)); parser_emit_ldloca (arg_uint8); break; case MONO_CEE_LDLOCA: read_arg (arg_uint16); - TRACE_IMPL (printf (" %d", arg_uint16)); parser_emit_ldloca (arg_uint16); break; case MONO_CEE_LDFTN: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_ldftn (method, arg_token); break; case MONO_CEE_CALL: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_call (method, arg_token); break; case MONO_CEE_CALLI: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_calli (method, arg_token); break; case MONO_CEE_STARG: @@ -1759,42 +1986,34 @@ parse_method_code (MonoMethod *method) break; case MONO_CEE_LDSFLD: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_ldsfld (method, arg_token); break; case MONO_CEE_LDSFLDA: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_ldsflda (method, arg_token); break; case MONO_CEE_STSFLD: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_stsfld (method, arg_token); break; case MONO_CEE_STFLD: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_stfld (method, arg_token); break; case MONO_CEE_LDFLD: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_ldfld (method, arg_token); break; case MONO_CEE_LDFLDA: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_ldflda (method, arg_token); break; case MONO_CEE_LDOBJ: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_ldobj (method, arg_token); break; case MONO_CEE_STOBJ: read_arg (arg_token); - TRACE_IMPL (printf (" %d", arg_token)); parser_emit_stobj (method, arg_token); break; case MONO_CEE_CONV_I: @@ -2049,11 +2268,9 @@ parse_method_code (MonoMethod *method) } break; default: - TRACE_IMPL (printf ("\n")); gcc_unreachable (); } #undef read_arg - TRACE_IMPL (printf ("\n")); /* reset the prefix unless current opcode is a prefix itself */ switch (opcode) { @@ -2090,7 +2307,7 @@ parser_get_refertenced_types_in_signature (MonoMethodSignature *signature) feature and building lists for called methods and referenced types. Returns true if the method can be compiled. */ static bool -parser_preparse_method (MonoMethod *method, GSList **called_methods, GSList **referenced_types) +parser_preparse_method (MonoMethod *method, GSList **called_methods, GSList **referenced_types, MonoOpcodeEnum *reason) { MonoMethodSignature *signature = mono_method_signature (method); if (mono_signature_is_instance (signature)) @@ -2355,16 +2572,19 @@ parser_preparse_method (MonoMethod *method, GSList **called_methods, GSList **re } break; default: - TRACE_IMPL - ({ - fprintf (stderr, "Unhandled opcode: %s\n", mono_opcode_name (opcode)); - fprintf (stderr, "Method: %s\n", mono_method_full_name (method, true)); - fprintf (stderr, "%s", mono_disasm_code (NULL, method, code, code_end)); - }); +#if 0 + fprintf (stderr, "Unhandled opcode: %s\n", mono_opcode_name (opcode)); + fprintf (stderr, "Method: %s\n", mono_method_full_name (method, true)); + fprintf (stderr, "%s", mono_disasm_code (NULL, method, code, code_end)); +#endif g_slist_free (*called_methods); *called_methods = NULL; g_slist_free (*referenced_types); *referenced_types = NULL; + if (reason) + { + *reason = opcode; + } return false; } } @@ -2457,7 +2677,6 @@ static void parse_method_decl (MonoMethod *method) { gcc_assert (g_hash_table_lookup (parsed_methods_decl, method) == NULL); - TRACE_DECL ({ char *s = mono_method_full_name (method, true); printf ("\tMethod: %s\n", s); free (s); }); const GCCCilMethodMode method_mode = parser_get_method_mode (method); MonoMethodSignature *signature = mono_method_signature (method); @@ -2487,7 +2706,6 @@ parse_method_decl (MonoMethod *method) } if (method_decl != NULL_TREE) { - TRACE_IMPL ({printf ("Libstd:%s not found in builtins\n", fun_name);}); gcc_assert (!g_hash_table_lookup (parsed_methods_decl, method)); gcc_assert (!g_hash_table_lookup (parsed_methods_impl, method)); g_hash_table_insert (parsed_methods_decl, method, method_decl); @@ -2495,7 +2713,6 @@ parse_method_decl (MonoMethod *method) } else { - TRACE_IMPL ({printf ("Libstd:%s FOUNDED in builtins\n", fun_name);}); identifier = get_identifier (fun_name); } } @@ -2547,11 +2764,220 @@ parse_method_decl (MonoMethod *method) cil_bindings_push_decl (method_decl); } +/* tree node from the blob value */ +static tree +get_from_blob(guchar* ptr, MonoType *monotype, guchar** rptr) +{ + tree node; + int typetype = mono_type_get_type (monotype); + + gint val_int; + guint val_uint; + gint64 val_int64; + guint64 val_uint64; + gint32 val_int32; + guint32 val_uint32; + gint16 val_int16; + guint16 val_uint16; + gint8 val_int8; + guint8 val_uint8; + float val_float; + double val_double; + REAL_VALUE_TYPE real_value; + long *pf; + size_t len; +#define read_val(val) val = *((typeof(val) *) ptr) /* FIXME big endian */ + switch(typetype) + { + case MONO_TYPE_U1: + read_val(val_uint8); + node = build_int_cst(cil_type_for_size(8, true), (HOST_WIDE_INT) val_uint8); + ptr += sizeof(val_uint8); + break; + case MONO_TYPE_I1: + read_val(val_int8); + node = build_int_cst(cil_type_for_size(8, false), (HOST_WIDE_INT) val_int8); + ptr += sizeof(val_int8); + break; + case MONO_TYPE_U2: + read_val(val_uint16); + node = build_int_cst(cil_type_for_size(16, true), (HOST_WIDE_INT) val_uint16); + ptr += sizeof(val_uint16); + break; + case MONO_TYPE_I2: + read_val(val_int16); + node = build_int_cst(cil_type_for_size(16, false), (HOST_WIDE_INT) val_int16); + ptr += sizeof(val_int16); + break; + case MONO_TYPE_U4: + read_val(val_uint32); + node = build_int_cst(cil_type_for_size(32, true), (HOST_WIDE_INT) val_uint32); + ptr += sizeof(val_uint32); + break; + case MONO_TYPE_I4: + read_val(val_int32); + node = build_int_cst(cil_type_for_size(32, false), (HOST_WIDE_INT) val_int32); + ptr += sizeof(val_int32); + break; + case MONO_TYPE_U8: + read_val(val_uint64); + node = build_int_cst(cil_type_for_size(64, true), (HOST_WIDE_INT) val_uint64); + ptr += sizeof(val_int64); + break; + case MONO_TYPE_I8: + read_val(val_int64); + node = build_int_cst(cil_type_for_size(64, false), (HOST_WIDE_INT) val_int64); + ptr += sizeof(val_int64); + break; + + case MONO_TYPE_CHAR: + read_val(val_int16); /* utf-8, FIXME convert to char ? */ + node = build_int_cst(cil_type_for_size(16, true), (HOST_WIDE_INT) val_int16); + ptr += sizeof(val_int16); + break; + case MONO_TYPE_U: + read_val(val_uint); + node = build_int_cst(unsigned_type_node, (HOST_WIDE_INT) val_uint); + ptr += sizeof(val_uint); + break; + case MONO_TYPE_I: + read_val(val_int); + node = build_int_cst(integer_type_node, (HOST_WIDE_INT) val_int); + ptr += sizeof(val_int); + break; + + + case MONO_TYPE_R4: + read_val(val_float); + pf = (void *) &val_float; + real_from_target_fmt(&real_value, pf, &ieee_single_format); + node = build_real (double_type_node, real_value); + ptr += sizeof(val_float); + break; + case MONO_TYPE_R8: + read_val(val_double); + pf = (void *) &val_double; + real_from_target_fmt(&real_value, pf, &ieee_double_format); + node = build_real (double_type_node, real_value); + ptr += sizeof(val_double); + break; + + + case MONO_TYPE_STRING: + read_val(val_uint8); + ptr += sizeof(val_uint8); + len = (int) val_uint8; + char *val_str = g_strnfill(len+1, '\0'); + memcpy(val_str, ptr, len); + node = build_string(len, val_str); + free(val_str); + ptr += len; + break; + + case MONO_TYPE_SZARRAY: + read_val(val_uint32); + ptr += sizeof(val_uint32); + len = (typeof(len)) val_uint32; + MonoType *elt_type = mono_class_get_type(monotype->data.klass); + tree elts = NULL_TREE; + guint i; + for(i = 0; i<len; i++) + { + elts = tree_cons(NULL_TREE, get_from_blob(ptr, elt_type, rptr), elts); + ptr = *rptr; + } +/* tree index = build_index_type (build_int_cst(sizetype, len-1)); */ +/* tree array = build_array_type (TREE_TYPE(TREE_VALUE(elts)), index); */ + node = build_vector(TREE_TYPE(TREE_VALUE(elts)), nreverse(elts)); + break; + + default: + fprintf (stderr, "Unhandled type type: 0x%x %s\n", typetype, mono_type_get_name (monotype)); + gcc_unreachable(); + } + + *rptr = ptr; + return node; + +} + +static tree +convert_cil_attributes(MonoCustomAttrInfo *custom_attr) +{ + tree attributes = NULL_TREE; + if (custom_attr) + { + int i; + for (i = 0; i < custom_attr->num_attrs; ++i) + { + /* get purpose */ + GString * purpose = g_string_new(""); + const MonoCustomAttrEntry *attr = &custom_attr->attrs[i]; + MonoClass *klass = mono_method_get_class (attr->ctor); + const char *klass_ns = mono_class_get_namespace (klass); + const char *klass_name = mono_class_get_name (klass); + if( strcmp("",klass_ns) != 0) + { + g_string_append(purpose, klass_ns); + g_string_append(purpose,"."); + } + g_string_append(purpose, klass_name); + + if (!strcmp (klass_ns, "gcc4net.C_Attributes")) + { + attributes = tree_cons(get_identifier(purpose->str), NULL_TREE , attributes); + } + else if (!strcmp (klass_ns, "OpenSystem.C")) + { + /* TODO: should check the class assembly and method arguments? */ + attributes = tree_cons(get_identifier(purpose->str), NULL_TREE , attributes); + } +#if 0 + else if (!strcmp (klass_ns, "gcc4net.JitCompilationHints")) + { + /* get value */ + MonoMethodSignature *sig = mono_method_signature(attr->ctor); + tree value = NULL_TREE; + if( mono_signature_get_param_count(sig) > 0) + { + MonoType *t; + gpointer iter = NULL; + guchar *data = (guchar*) attr->data; + guchar *rdata = NULL; + short prolog = *((short *) data); + data += 2; + if (prolog != 1) + { + fprintf(stderr,"error parsing attribute blob\n"); + break; + } + while((t = mono_signature_get_params(sig, &iter)) != NULL) + { + char *tname = mono_type_get_name(t); + tree blobval = get_from_blob(data, t, &rdata); + value = tree_cons(get_identifier(tname), blobval, value); + data = rdata; + } + short num_named_params = *((short *) data); + data += 2; + while(num_named_params > 0) + { + /* TODO: named paramed */ + num_named_params--; + } + } + attributes = tree_cons(get_identifier(purpose->str), nreverse(value) , attributes); + } +#endif + g_string_free(purpose,FALSE); + } + } + return attributes; +} + static void parse_method_impl (MonoMethod *method) { - TRACE_IMPL ({ char *s = mono_method_full_name (method, true); printf ("\tImplMethod: %s\n", s); free (s); }); - tree method_decl = parser_get_method_tree (method); gcc_assert (!g_hash_table_lookup (parsed_methods_impl, method)); g_hash_table_insert (parsed_methods_impl, method, method_decl); @@ -2621,6 +3047,15 @@ parse_method_impl (MonoMethod *method) DECL_IGNORED_P (result_decl) = 1; DECL_RESULT (method_decl) = result_decl; + /* attributes */ + MonoCustomAttrInfo *attributes = mono_custom_attrs_from_method(method); + if (attributes) + { + tree attrs = convert_cil_attributes(attributes); + decl_attributes(&method_decl, attrs, 0 /*FIXME*/); + mono_custom_attrs_free (attributes); + } + /* declare locals */ guint32 num_locals; gboolean init_locals; @@ -2648,7 +3083,6 @@ parse_method_impl (MonoMethod *method) } } cil_bindings_push_decl_local (i, local_decl); - TRACE_IMPL ({ char *local_type_name = mono_type_get_name (locals[i]); printf ("\t\tLocal %s: %s\n", localname, local_type_name); free (local_type_name); }); ++argnum; } @@ -2675,7 +3109,6 @@ parse_method_impl (MonoMethod *method) } else { - TRACE_IMPL (printf ("\t\tNo header\n");); /* native method or something */ gcc_unreachable (); } @@ -2702,9 +3135,7 @@ parse_instance_field (MonoClassField *field) { gcc_assert ((mono_field_get_flags (field) & MONO_FIELD_ATTR_STATIC) == 0); gcc_assert ((mono_field_get_flags (field) & MONO_FIELD_ATTR_LITERAL) == 0); - TRACE_DECL (printf ("\tInstance Field: %s\n", mono_field_get_name (field))); MonoType *type = mono_field_get_type (field); - TRACE_DECL ({char *field_type_name = mono_type_get_name (type); printf ("\t\tType: %s\n", field_type_name); free (field_type_name);}); MonoClass *klass = mono_field_get_parent (field); tree field_type_tree = NULL; @@ -2742,7 +3173,6 @@ parse_instance_field (MonoClassField *field) int idx = mono_metadata_token_index (mono_class_get_field_token (field)) - 1; guint32 offset; mono_metadata_field_info (mono_class_get_image (klass), idx, &offset, NULL, NULL); - TRACE_DECL (printf ("\t\tOffset: %d\n", offset)); tree offset_tree = bitsize_int (offset * BITS_PER_UNIT); /* We need to pass in the alignment the DECL is known to have. @@ -2849,7 +3279,6 @@ finish_record_type (MonoClass *klass) gboolean explicit_size = mono_metadata_packing_from_typedef (mono_class_get_image (klass), mono_class_get_type_token (klass), &packing_size, &real_size); if (explicit_size) { - TRACE_DECL (printf ("\tChanging size of type, real_size %d\n", real_size)); /* Note, using sizeof is actually incorrect */ int extra_for_headers = mono_class_is_valuetype (klass) ? 0 : 2 * sizeof (void *); tree requested_size_bytes = build_int_cst (integer_type_node, real_size + extra_for_headers); @@ -2886,8 +3315,6 @@ parse_class_instance_fields (MonoClass *klass) gcc_assert (TYPE_SIZE ((tree) g_hash_table_lookup (parsed_classes_records, parent)) != NULL_TREE); } - TRACE_DECL (printf ("Parsing instance fields of %s:\n", mono_class_get_name (klass))); - tree class_record_tree = make_node (RECORD_TYPE); g_hash_table_insert (parsed_classes_records, klass, class_record_tree); @@ -2964,36 +3391,11 @@ parse_class_instance_fields (MonoClass *klass) } static void -parse_static_field (MonoClassField *field) -{ - gcc_assert (mono_field_get_flags (field) & MONO_FIELD_ATTR_STATIC); - gboolean isliteral = mono_field_get_flags (field) & MONO_FIELD_ATTR_LITERAL; - TRACE_DECL (printf ("\tStatic %sField: %s\n", isliteral ? "Literal " : "", mono_field_get_name (field))); - MonoType *type = mono_field_get_type (field); - TRACE_DECL ({char *field_type_name = mono_type_get_name (type); printf ("\t\tType: %s\n", field_type_name); free (field_type_name);}); - parser_parse_type (type); - - if (!isliteral) - { - tree field_name_tree = get_identifier (mono_field_get_name (field)); - tree field_type_tree = parser_get_type_tree (type); - tree field_tree = build_decl (FIELD_DECL, field_name_tree, field_type_tree); - - tree klass_tree = parser_get_class_static_record_tree (mono_field_get_parent (field)); - DECL_CONTEXT (field_tree) = klass_tree; - DECL_FCONTEXT (field_tree) = klass_tree; - TYPE_FIELDS (klass_tree) = chainon (TYPE_FIELDS (klass_tree), field_tree); - } -} - -static void parse_class_static_fields (MonoClass *klass) { gcc_assert (g_hash_table_lookup (parsed_classes_static_records, klass) == NULL); gcc_assert (g_hash_table_lookup (parsed_classes_static_storages, klass) == NULL); - TRACE_DECL (printf ("Parsing static fields of %s:\n", mono_class_get_name (klass))); - GCCCilClassMode class_mode = parser_get_class_mode (klass); tree class_static_record = make_node (RECORD_TYPE); @@ -3004,15 +3406,26 @@ parse_class_static_fields (MonoClass *klass) gpointer iter = NULL; while ((field = mono_class_get_fields (klass, &iter)) != NULL) { - gcc_assert (mono_field_get_parent (field) == klass); - if (mono_field_get_flags (field) & MONO_FIELD_ATTR_STATIC) + guint32 field_flags = mono_field_get_flags (field); + if (field_flags & MONO_FIELD_ATTR_STATIC) { - parse_static_field (field); - if ((mono_field_get_flags (field) & MONO_FIELD_ATTR_LITERAL) == 0) + MonoType *type = mono_field_get_type (field); + parser_parse_type (type); + + if (!(field_flags & MONO_FIELD_ATTR_LITERAL)) { + tree field_name_tree = get_identifier (mono_field_get_name (field)); + tree field_type_tree = parser_get_type_tree (type); + tree field_tree = build_decl (FIELD_DECL, field_name_tree, field_type_tree); + + DECL_CONTEXT (field_tree) = class_static_record; + DECL_FCONTEXT (field_tree) = class_static_record; + TYPE_FIELDS (class_static_record) = chainon (TYPE_FIELDS (class_static_record), field_tree); + emit_static_storage = true; } - if (class_mode == GCC_CIL_CLASS_MODE_COMPILE && (mono_field_get_flags (field) & MONO_FIELD_ATTR_HAS_RVA)) + + if (class_mode == GCC_CIL_CLASS_MODE_COMPILE && (field_flags & MONO_FIELD_ATTR_HAS_RVA)) { static_fields_to_init = g_slist_prepend (static_fields_to_init, field); } @@ -3048,10 +3461,15 @@ parse_class_decl (MonoClass *klass) parser_parse_type (enum_basetype); } - TRACE_DECL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf ("Class decl: %s\n", s); free (s); }); - TRACE_DECL ({ MonoClass *nesting = mono_class_get_nesting_type (klass); if (nesting) printf ("\tNesting: %s:%s\n", mono_class_get_namespace (nesting), mono_class_get_name (nesting)); }); - TRACE_DECL ({ MonoClass *parent = mono_class_get_parent (klass); if (parent) printf ("\tParent: %s:%s\n", mono_class_get_namespace (parent), mono_class_get_name (parent)); }); - TRACE_DECL (printf ("\tValuetype: %s\n", mono_class_is_valuetype (klass) ? "true" : "false")); +#if 0 + /* attributes */ + MonoCustomAttrInfo *attributes = mono_custom_attrs_from_class(klass); + if (attributes) + { + tree attrs = convert_cil_attributes(attributes); + mono_custom_attrs_free (attributes); + } +#endif parse_class_instance_fields (klass); gcc_assert (g_hash_table_lookup (parsed_classes_records, klass) != NULL); @@ -3068,15 +3486,13 @@ parse_class_decl (MonoClass *klass) parse_class_decl (parent); } +#if 0 /* TODO: probably not really needed at all */ MonoClass *nesting = mono_class_get_nesting_type (klass); if (nesting) { -#if 0 /* TODO: probably not really needed at all */ parse_class_decl (nesting); -#endif } - - TRACE_DECL ({ char *s = mono_type_full_name (mono_class_get_type (klass)); printf ("End of Class decl: %s\n", s); free (s); }); +#endif } static void @@ -3159,20 +3575,10 @@ parser_get_is_initialization_method (MonoMethod *method) MonoCustomAttrInfo *attributes = mono_custom_attrs_from_method (method); if (attributes) { - int i; - for (i = 0; i < attributes->num_attrs; ++i) - { - const MonoCustomAttrEntry *attr = &attributes->attrs[i]; - MonoClass *klass = mono_method_get_class (attr->ctor); - if (!strcmp ("InitializerAttribute", mono_class_get_name (klass)) - && !strcmp ("OpenSystem.C", mono_class_get_namespace (klass))) - { - /* TODO: should check the class assembly and method arguments? */ - mono_custom_attrs_free (attributes); - return true; - } - } + tree attrs = convert_cil_attributes(attributes); mono_custom_attrs_free (attributes); + + return lookup_attribute ("OpenSystem.C.InitializerAttribute", attrs) != NULL; } return false; } @@ -3200,17 +3606,17 @@ parser_get_pinvoke_method_info (MonoMethod *method, const char **libname, const { MonoImage *image = mono_class_get_image (mono_method_get_class (method)); - g_assert (mono_method_get_flags (method, NULL) & MONO_METHOD_ATTR_PINVOKE_IMPL); + g_assert (mono_method_get_flags (method, NULL) & MONO_METHOD_ATTR_PINVOKE_IMPL); - guint32 token = mono_method_get_token (method); - int idx = mono_metadata_token_index (token); - int implmap_idx = mono_metadata_implmap_from_method (image, idx - 1); - guint32 im_cols[MONO_IMPLMAP_SIZE]; - mono_metadata_decode_row (mono_image_get_table_info (image, MONO_TABLE_IMPLMAP), implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE); - if (piflags) *piflags = im_cols[MONO_IMPLMAP_FLAGS]; - if (functionname) *functionname = mono_metadata_string_heap (image, im_cols[MONO_IMPLMAP_NAME]); - guint32 scope_token = mono_metadata_decode_row_col (mono_image_get_table_info (image, MONO_TABLE_MODULEREF), im_cols[MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME); - if (libname) *libname = mono_metadata_string_heap (image, scope_token); + guint32 token = mono_method_get_token (method); + int idx = mono_metadata_token_index (token); + int implmap_idx = mono_metadata_implmap_from_method (image, idx - 1); + guint32 im_cols[MONO_IMPLMAP_SIZE]; + mono_metadata_decode_row (mono_image_get_table_info (image, MONO_TABLE_IMPLMAP), implmap_idx - 1, im_cols, MONO_IMPLMAP_SIZE); + if (piflags) *piflags = im_cols[MONO_IMPLMAP_FLAGS]; + if (functionname) *functionname = mono_metadata_string_heap (image, im_cols[MONO_IMPLMAP_NAME]); + guint32 scope_token = mono_metadata_decode_row_col (mono_image_get_table_info (image, MONO_TABLE_MODULEREF), im_cols[MONO_IMPLMAP_SCOPE] - 1, MONO_MODULEREF_NAME); + if (libname) *libname = mono_metadata_string_heap (image, scope_token); } static tree @@ -3263,8 +3669,6 @@ parser_emit_pinvoke_initialization (void) const char *functionname; guint16 piflags; parser_get_pinvoke_method_info (m, &libname, &functionname, &piflags); - TRACE_IMPL ( printf ("Pinvoke method: %s, %s, %s, %x\n", mono_method_get_name (m), libname, functionname, (unsigned int) piflags) ); - tree libname_str_tree = parser_build_string_literal (libname); tree functionname_str_tree = parser_build_string_literal (functionname); tree arglist = tree_cons (NULL_TREE, functionname_str_tree, NULL_TREE); @@ -3499,14 +3903,12 @@ parser_parse_file (const char *filename) #endif gcc_assert (img); images_that_we_are_compiling = g_slist_prepend (images_that_we_are_compiling, img); - TRACE_DECL (printf ("Image name: %s\n", mono_image_get_name (img))); guint32 entry_point_token = mono_image_get_entry_point (img); MonoMethod *entry_point = NULL; if (entry_point_token) { entry_point = mono_get_method (img, entry_point_token, NULL); - TRACE_DECL ({ char *s = mono_method_full_name (entry_point, true); printf ("Entry point: %s\n", s); free (s); }); MonoClass *entry_class = mono_method_get_class (entry_point); parse_class_decl (entry_class); methods_to_parse_impl = g_slist_prepend (methods_to_parse_impl, entry_point); @@ -3525,10 +3927,11 @@ parser_parse_file (const char *filename) methods_to_parse_impl = g_slist_remove (methods_to_parse_impl, m); if (g_hash_table_lookup (parsed_methods_impl, m) == NULL) { + MonoOpcodeEnum reason; GSList *called_methods = NULL; GSList *referenced_types = NULL; parse_class_decl (mono_method_get_class (m)); - bool can_be_compiled = parser_preparse_method (m, &called_methods, &referenced_types); + bool can_be_compiled = parser_preparse_method (m, &called_methods, &referenced_types, &reason); if (can_be_compiled) { GSList *li; @@ -3554,10 +3957,10 @@ parser_parse_file (const char *filename) switch (flag_unsupported_method_behavior) { case UMB_WARNING: - warning (0, "Cannot compile method %s because it uses some unsupported feature.", method_name); + warning (0, "method '%s' not compiled, unsupported feature '%s'.", method_name, mono_opcode_name (reason)); break; case UMB_ERROR: - error ("Cannot compile method %s because it uses some unsupported feature.", method_name); + error ("method '%s' not compiled, unsupported feature '%s'.", method_name, mono_opcode_name (reason)); break; default: gcc_unreachable (); diff --git a/gcc/cil/stack.c b/gcc/cil/stack.c index d317b0ccd2e..8af2747d9dc 100644 --- a/gcc/cil/stack.c +++ b/gcc/cil/stack.c @@ -52,11 +52,11 @@ cil_stack_init (void) static tree cil_stack_normalize_type (tree t, CilStackType type) { - if (type == CIL_STACK_TYPE_OBJECT) + if (type == CIL_STYPE_OBJECT) { return t; /* TODO: no better idea for now */ } - else if (type == CIL_STACK_TYPE_F && SCALAR_FLOAT_TYPE_P (TREE_TYPE (t))) + else if (type == CIL_STYPE_F && SCALAR_FLOAT_TYPE_P (TREE_TYPE (t))) { return t; /* Avoid useless conversions between float and double */ } @@ -88,38 +88,38 @@ cil_stack_get_cil_stack_type_for_tree_type (tree t) { if (t == error_mark_node) { - return CIL_STACK_TYPE_ERROR; + return CIL_STYPE_ERROR; } - if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STACK_TYPE_INT32))) + if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STYPE_INT32))) { - return CIL_STACK_TYPE_INT32; + return CIL_STYPE_INT32; } - else if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STACK_TYPE_INT64))) + else if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STYPE_INT64))) { - return CIL_STACK_TYPE_INT64; + return CIL_STYPE_INT64; } - else if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STACK_TYPE_NATIVE_INT))) + else if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STYPE_NINT))) { - return CIL_STACK_TYPE_NATIVE_INT; + return CIL_STYPE_NINT; } - else if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STACK_TYPE_F))) + else if (cil_stack_type_tree_equal (t, cil_stack_get_tree_type_for_cil_stack_type (CIL_STYPE_F))) { - return CIL_STACK_TYPE_F; + return CIL_STYPE_F; } else if (POINTER_TYPE_P (t)) { - /* TODO: This could be a CIL_STACK_TYPE_OBJECT or a CIL_STACK_TYPE_MANAGED_POINTER also, I assume here that it is an unmanaged pointer */ - return CIL_STACK_TYPE_NATIVE_INT; + /* TODO: This could be a CIL_STYPE_OBJECT or a CIL_STYPE_MP also, I assume here that it is an unmanaged pointer */ + return CIL_STYPE_NINT; } else if (INTEGRAL_TYPE_P (t)) { - if (TYPE_PRECISION (t) <= TYPE_PRECISION (cil_stack_get_tree_type_for_cil_stack_type (CIL_STACK_TYPE_INT32))) + if (TYPE_PRECISION (t) <= TYPE_PRECISION (cil_stack_get_tree_type_for_cil_stack_type (CIL_STYPE_INT32))) { - return CIL_STACK_TYPE_INT32; + return CIL_STYPE_INT32; } - else if (TYPE_PRECISION (t) <= TYPE_PRECISION (cil_stack_get_tree_type_for_cil_stack_type (CIL_STACK_TYPE_INT64))) + else if (TYPE_PRECISION (t) <= TYPE_PRECISION (cil_stack_get_tree_type_for_cil_stack_type (CIL_STYPE_INT64))) { - return CIL_STACK_TYPE_INT64; + return CIL_STYPE_INT64; } else { @@ -128,12 +128,12 @@ cil_stack_get_cil_stack_type_for_tree_type (tree t) } else if (SCALAR_FLOAT_TYPE_P (t)) { - return CIL_STACK_TYPE_F; + return CIL_STYPE_F; } else if (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE) { /* should be a valuetype */ - return CIL_STACK_TYPE_OBJECT; + return CIL_STYPE_OBJECT; } else { @@ -202,19 +202,19 @@ cil_stack_get_tree_type_for_cil_stack_type (CilStackType ct) { switch (ct) { - case CIL_STACK_TYPE_INT32: + case CIL_STYPE_INT32: return cil_type_for_size (32, false); - case CIL_STACK_TYPE_INT64: + case CIL_STYPE_INT64: return cil_type_for_size (64, false); - case CIL_STACK_TYPE_NATIVE_INT: + case CIL_STYPE_NINT: return integer_type_node; - case CIL_STACK_TYPE_F: + case CIL_STYPE_F: return double_type_node; - case CIL_STACK_TYPE_MANAGED_POINTER: + case CIL_STYPE_MP: return build_pointer_type (void_type_node); - case CIL_STACK_TYPE_OBJECT: + case CIL_STYPE_OBJECT: gcc_unreachable (); /* TODO */ - case CIL_STACK_TYPE_ERROR: + case CIL_STYPE_ERROR: return error_mark_node; default: gcc_unreachable (); diff --git a/gcc/cil/stack.h b/gcc/cil/stack.h index 9f8e70a563d..6c10f7f32d5 100644 --- a/gcc/cil/stack.h +++ b/gcc/cil/stack.h @@ -37,13 +37,13 @@ typedef enum { - CIL_STACK_TYPE_INT32, - CIL_STACK_TYPE_INT64, - CIL_STACK_TYPE_NATIVE_INT, - CIL_STACK_TYPE_F, - CIL_STACK_TYPE_MANAGED_POINTER, - CIL_STACK_TYPE_OBJECT, - CIL_STACK_TYPE_ERROR + CIL_STYPE_INT32, /* CIL_STACK_TYPE_INT32 */ + CIL_STYPE_INT64, /* CIL_STACK_TYPE_INT64 */ + CIL_STYPE_NINT, /* CIL_STACK_TYPE_NATIVE_INT */ + CIL_STYPE_F, /* CIL_STACK_TYPE_FLOAT */ + CIL_STYPE_MP, /* CIL_STACK_TYPE_MANAGED_POINTER */ + CIL_STYPE_OBJECT, /* CIL_STACK_TYPE_OBJECT */ + CIL_STYPE_ERROR /* CIL_STACK_TYPE_ERROR */ } CilStackType; |