aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandreao <andreao@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-23 10:08:14 +0000
committerandreao <andreao@138bc75d-0d04-0410-961f-82ee72b054a4>2008-04-23 10:08:14 +0000
commit2e1501064a9b9bfc8703d76a4c08174f1c54f953 (patch)
tree8a942a473bd0e8eff88621098a4700ca311dc8df
parent2bfea2f6792ecaa9bfb65dd705e606959087c3b0 (diff)
generate POINTER_PLUS_EXPR correctly
emit labels only when necessary for clean CFG remove emission of temporaries for expressions of the stack, gimplify shall do it better handling of operations in the parser cleanup of unused code most of the work from Piotr Lesnicki git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/branches/st/cli@134589 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cil/cil-builtins.c4
-rw-r--r--gcc/cil/parser.c1027
-rw-r--r--gcc/cil/stack.c52
-rw-r--r--gcc/cil/stack.h14
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;