static ir_node *gcji_get_arrayclass(ir_node *block, ir_node **mem, ir_node *array_class_ref) { ir_graph *irg = get_irn_irg(block); ir_node *addr = new_r_Address(irg, gcj_get_array_class_entity); ir_node *null = new_r_Const(irg, get_mode_null(mode_reference)); ir_node *args[] = { array_class_ref, null }; ir_type *call_type = get_entity_type(gcj_get_array_class_entity); ir_node *call = new_r_Call(block, *mem, addr, ARRAY_SIZE(args), args, call_type); ir_node *new_mem = new_Proj(call, mode_M, pn_Call_M); ir_node *ress = new_Proj(call, mode_T, pn_Call_T_result); ir_node *res = new_Proj(ress, mode_reference, 0); *mem = new_mem; return res; }
void eh_lower_Raise(ir_node *raise, ir_node *proj) { assert (is_Raise(raise) && is_Proj(proj)); ir_node *ex_obj = get_Raise_exo_ptr(raise); ir_node *block = get_nodes_block(raise); ir_graph *irg = get_irn_irg(raise); ir_node *cur_mem = get_Raise_mem(raise); ir_node *c_symc = new_r_SymConst(irg, throw_entity); ir_node *in[1] = { ex_obj }; ir_node *throw = new_r_Call(block, cur_mem, c_symc, 1, in, get_entity_type(throw_entity)); ir_set_throws_exception(throw, 1); exchange(raise, throw); set_Proj_num(proj, pn_Call_X_except); }
ir_node *gcji_lookup_interface(ir_node *objptr, ir_type *iface, ir_entity *method, ir_graph *irg, ir_node *block, ir_node **mem) { ir_node *cur_mem = *mem; // we need the reference to the object's class$ field // first, dereference the vptr in order to get the vtable address. ir_entity *vptr_entity = get_vptr_entity(); ir_type *vptr_type = get_entity_type(vptr_entity); ir_node *vptr_addr = new_r_Member(block, objptr, vptr_entity); ir_node *vptr_load = new_r_Load(block, cur_mem, vptr_addr, mode_reference, vptr_type, cons_none); ir_node *vtable_addr = new_r_Proj(vptr_load, mode_reference, pn_Load_res); cur_mem = new_r_Proj(vptr_load, mode_M, pn_Load_M); // second, dereference vtable_addr (it points to the slot where the address of the class$ field is stored). ir_node *cd_load = new_r_Load(block, cur_mem, vtable_addr, mode_reference, vptr_type, cons_none); ir_node *cd_ref = new_r_Proj(cd_load, mode_reference, pn_Load_res); cur_mem = new_r_Proj(cd_load, mode_M, pn_Load_M); class_t *linked_class = (class_t*) oo_get_type_link(iface); method_t *linked_method = (method_t*) oo_get_entity_link(method); assert(linked_class && linked_method); constant_t *name_const = linked_class->constants[linked_method->name_index]; ir_entity *name_const_ent= gcji_emit_utf8_const(name_const, 1); ir_node *name_ref = new_r_Address(irg, name_const_ent); constant_t *desc_const = linked_class->constants[linked_method->descriptor_index]; ir_entity *desc_const_ent= gcji_emit_utf8_const(desc_const, 1); ir_node *desc_ref = new_r_Address(irg, desc_const_ent); ir_node *callee = new_r_Address(irg, gcj_lookup_interface_entity); ir_node *args[3] = { cd_ref, name_ref, desc_ref }; ir_type *call_type = get_entity_type(gcj_lookup_interface_entity); ir_node *call = new_r_Call(block, cur_mem, callee, 3, args, call_type); cur_mem = new_r_Proj(call, mode_M, pn_Call_M); ir_node *ress = new_r_Proj(call, mode_T, pn_Call_T_result); ir_node *res = new_r_Proj(ress, mode_reference, 0); *mem = cur_mem; return res; }
ir_node *dmemory_default_alloc_array(ir_type *eltype, ir_node *count, ir_graph *irg, ir_node *block, ir_node **mem) { ir_node *cur_mem = *mem; unsigned count_size = get_mode_size_bytes(default_arraylength_mode); unsigned element_size = is_Class_type(eltype) ? get_mode_size_bytes(mode_P) : get_type_size_bytes(eltype); // FIXME: some langs support arrays of structs. /* increase element count so we have enough space for a counter at the front */ unsigned add_size = (element_size + (count_size-1)) / count_size; ir_node *count_u = new_r_Conv(block, count, mode_Iu); ir_node *addv = new_r_Const_long(irg, mode_Iu, add_size); ir_node *add1 = new_r_Add(block, count_u, addv, mode_Iu); ir_node *elsizev = new_r_Const_long(irg, mode_Iu, element_size); ir_node *size = new_r_Mul(block, add1, elsizev, mode_Iu); unsigned addr_delta = add_size * element_size; symconst_symbol calloc_sym; calloc_sym.entity_p = calloc_entity; ir_node *callee = new_r_SymConst(irg, mode_P, calloc_sym, symconst_addr_ent); ir_node *one = new_r_Const_long(irg, mode_Iu, 1); ir_node *in[2] = { one, size }; ir_type *call_type = get_entity_type(calloc_entity); ir_node *call = new_r_Call(block, cur_mem, callee, 2, in, call_type); cur_mem = new_r_Proj(call, mode_M, pn_Call_M); ir_node *ress = new_r_Proj(call, mode_T, pn_Call_T_result); ir_node *res = new_r_Proj(ress, mode_P, 0); /* write length of array */ ir_node *len_value = new_r_Conv(block, count, default_arraylength_mode); ir_node *len_delta = new_r_Const_long(irg, mode_P, (int)addr_delta-4); //FIXME: replace magic num ir_node *len_addr = new_r_Add(block, res, len_delta, mode_P); ir_node *store = new_r_Store(block, cur_mem, len_addr, len_value, cons_none); cur_mem = new_r_Proj(store, mode_M, pn_Store_M); if (addr_delta > 0) { ir_node *delta = new_r_Const_long(irg, mode_P, (int)addr_delta); res = new_r_Add(block, res, delta, mode_P); } *mem = cur_mem; return res; }
static ir_node *gcji_instanceof(ir_node *objptr, ir_type *classtype, ir_graph *irg, ir_node *block, ir_node **mem) { ir_node *jclass = gcji_get_runtime_classinfo_(block, mem, classtype); ir_node *addr = new_r_Address(irg, gcj_instanceof_entity); ir_node *args[] = { objptr, jclass }; ir_type *call_type = get_entity_type(gcj_instanceof_entity); ir_node *call = new_r_Call(block, *mem, addr, ARRAY_SIZE(args), args, call_type); ir_node *new_mem = new_r_Proj(call, mode_M, pn_Call_M); ir_node *ress = new_r_Proj(call, mode_T, pn_Call_T_result); ir_node *call_res = new_r_Proj(ress, mode_int, 0); ir_node *zero = new_r_Const(irg, get_mode_null(mode_int)); ir_node *res = new_r_Cmp(block, call_res, zero, ir_relation_less_greater); *mem = new_mem; return res; }
ir_node *dmemory_default_alloc_object(ir_type *type, ir_graph *irg, ir_node *block, ir_node **mem) { ir_node *cur_mem = *mem; symconst_symbol type_sym; type_sym.type_p = type; ir_node *size = new_r_SymConst(irg, mode_Iu, type_sym, symconst_type_size); symconst_symbol calloc_sym; calloc_sym.entity_p = calloc_entity; ir_node *callee = new_r_SymConst(irg, mode_P, calloc_sym, symconst_addr_ent); ir_node *one = new_r_Const_long(irg, mode_Iu, 1); ir_node *in[2] = { one, size }; ir_type *call_type = get_entity_type(calloc_entity); ir_node *call = new_r_Call(block, cur_mem, callee, 2, in, call_type); cur_mem = new_r_Proj(call, mode_M, pn_Call_M); ir_node *ress = new_r_Proj(call, mode_T, pn_Call_T_result); ir_node *res = new_r_Proj(ress, mode_P, 0); *mem = cur_mem; return res; }