ir_entity *gcji_get_rtti_entity(ir_type *type) { if (is_Pointer_type(type)) { ir_type *points_to = get_pointer_points_to_type(type); if (is_Class_type(points_to)) return oo_get_class_rtti_entity(points_to); return NULL; } else if (is_Primitive_type(type)) { if (type == type_boolean) return gcj_boolean_rtti_entity; if (type == type_byte) return gcj_byte_rtti_entity; if (type == type_char) return gcj_char_rtti_entity; if (type == type_short) return gcj_short_rtti_entity; if (type == type_int) return gcj_int_rtti_entity; if (type == type_long) return gcj_long_rtti_entity; if (type == type_float) return gcj_float_rtti_entity; if (type == type_double) return gcj_double_rtti_entity; panic("unexpected type"); } else { return oo_get_class_rtti_entity(type); } }
static ir_entity *emit_type_signature(ir_type *type) { ir_type *curtype = type; unsigned n_pointer_levels = 0; while (is_Pointer_type(curtype)) { n_pointer_levels++; curtype = get_pointer_points_to_type(curtype); } struct obstack obst; obstack_init(&obst); if (n_pointer_levels > 0) { for (unsigned i = 0; i < n_pointer_levels-1; i++) obstack_1grow(&obst, '['); if (is_Primitive_type(curtype)) obstack_1grow(&obst, '['); } if (is_Primitive_type(curtype)) { char c = get_prim_type_char(curtype); obstack_1grow(&obst, c); } else { assert(is_Class_type(curtype)); obstack_1grow(&obst, 'L'); obstack_printf(&obst, "%s", get_compound_name(curtype)); obstack_1grow(&obst, ';'); obstack_1grow(&obst, '\0'); } const char *sig_bytes = obstack_finish(&obst); ir_entity *res = do_emit_utf8_const(sig_bytes, strlen(sig_bytes)); obstack_free(&obst, NULL); return res; }
static ir_type *get_Sel_or_SymConst_type(ir_node *sos) { assert (is_Sel(sos) || is_SymConst_addr_ent(sos)); ir_entity *entity = get_irn_entity_attr(sos); ir_type *type = get_entity_type(entity); if (is_Method_type(type)) { size_t n_ress = get_method_n_ress(type); if (n_ress == 0) return NULL; assert (n_ress == 1); type = get_method_res_type(type, 0); } if (is_Pointer_type(type)) type = get_pointer_points_to_type(type); if (is_Class_type(type)) return type; return NULL; }
static ir_node *gcji_get_runtime_classinfo_(ir_node *block, ir_node **mem, ir_type *type) { ir_entity *rtti_entity = gcji_get_rtti_entity(type); ir_graph *irg = get_irn_irg(block); if (rtti_entity != NULL) return new_r_Address(irg, rtti_entity); /* Arrays are represented as pointer types. We extract the base type, * get its classinfo and let gcj give the array type for that. * * gcj emits the type signature to the class' constant pool. During * class linking, the reference to the utf8const is replaced by the * reference to the appropriate class object. */ assert(is_Pointer_type(type)); unsigned n_pointer_levels = 0; ir_type *eltype = type; while (is_Pointer_type(eltype)) { ++n_pointer_levels; eltype = get_pointer_points_to_type(eltype); } if (!is_Primitive_type(eltype)) --n_pointer_levels; ir_entity *elem_cdf = gcji_get_rtti_entity(eltype); assert(elem_cdf != NULL); ir_node *array_class_ref = new_r_Address(irg, elem_cdf); for (unsigned d = 0; d < n_pointer_levels; d++) { array_class_ref = gcji_get_arrayclass(block, mem, array_class_ref); } return array_class_ref; }