static bool check_class_member(const ir_type *tp, const ir_entity *entity) { bool fine = true; if (get_entity_n_overwrites(entity) > get_class_n_supertypes(tp)) { report_error("member %+F of %+F has too many overwrites", entity, tp); fine = false; } return fine; }
void gcji_setup_rtti_entity(class_t *cls, ir_type *type) { ir_entity *rtti_entity = oo_get_class_rtti_entity(type); assert(type_java_lang_class != NULL); set_entity_type(rtti_entity, type_java_lang_class); ir_entity *name_ent = gcji_emit_utf8_const( cls->constants[cls->constants[cls->this_class]->classref.name_index], 1); uint16_t accflags = cls->access_flags; ir_entity *method_table = emit_method_table(type); ir_entity *field_table = emit_field_table(type); ir_graph *ccode = get_const_code_irg(); ir_node *size_in_bytes = new_r_Size(ccode, mode_int, type); int16_t field_count = cls->n_fields; int16_t static_field_count = 0; for (int16_t i = 0; i < field_count; i++) { if ((cls->fields[i]->access_flags & ACCESS_FLAG_STATIC) != 0) ++static_field_count; } ir_entity *superclass_rtti = NULL; if (get_class_n_supertypes(type) > 0) { ir_type *superclass = get_class_supertype(type, 0); /* TODO: search for first non-interface instead of taking the * first one and hoping it is a non-interface */ assert(!oo_get_class_is_interface(superclass)); superclass_rtti = gcji_get_rtti_entity(superclass); } ir_node *vtable_init = get_vtable_ref(type); int16_t interface_count = cls->n_interfaces; ir_entity *interfaces = emit_interface_table(type); // w/o slots 0=rtti. see lower_oo.c int16_t vtable_method_count = oo_get_class_vtable_size(type) - (ddispatch_get_index_of_first_method() - ddispatch_get_vptr_points_to_index()); ir_node *class_vtable = get_vtable_ref(type_java_lang_class); /* initializer for base class java.lang.Object */ ir_initializer_t *base_init = create_initializer_compound(1); set_compound_init_node(base_init, 0, class_vtable); /* initializer for java.lang.Class */ unsigned NUM_FIELDS = 39; ir_initializer_t *init = create_initializer_compound(NUM_FIELDS); size_t f = 0; set_initializer_compound_value(init, f++, base_init); set_compound_init_num(init, f++, mode_P, 407000); set_compound_init_entref(init, f++, name_ent); set_compound_init_num(init, f++, mode_ushort, accflags); set_compound_init_entref(init, f++, superclass_rtti); // _Jv_Constants inlined. not sure if this is needed for compiled code. set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_entref(init, f++, method_table); set_compound_init_num(init, f++, mode_short, cls->n_methods); set_compound_init_num(init, f++, mode_short, vtable_method_count); set_compound_init_entref(init, f++, field_table); set_compound_init_node(init, f++, size_in_bytes); set_compound_init_num(init, f++, mode_short, field_count); set_compound_init_num(init, f++, mode_short, static_field_count); set_compound_init_node(init, f++, vtable_init); // most of the following fields are set at runtime during the class linking. set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_entref(init, f++, interfaces); set_compound_init_null(init, f++); set_compound_init_num(init, f++, mode_short, interface_count); set_compound_init_num(init, f++, mode_byte, 1); // state set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); set_compound_init_null(init, f++); // engine set_compound_init_null(init, f++); assert(f == NUM_FIELDS); set_entity_initializer(rtti_entity, init); set_entity_alignment(rtti_entity, 32); add_pointer_in_jcr_segment(rtti_entity); }