void reach_dump(reach_t* r) { printf("REACH\n"); size_t i = HASHMAP_BEGIN; reach_type_t* t; while((t = reach_types_next(&r->types, &i)) != NULL) { printf(" %d: %s, %s\n", t->type_id, t->name, t->mangle); size_t j = HASHMAP_BEGIN; reach_method_name_t* n; printf(" size: " __zu "\n", t->abi_size); printf(" vtable: %d\n", t->vtable_size); while((n = reach_method_names_next(&t->methods, &j)) != NULL) { size_t k = HASHMAP_BEGIN; reach_method_t* m; while((m = reach_mangled_next(&n->r_mangled, &k)) != NULL) printf(" %d: %s\n", m->vtable_index, m->mangled_name); } j = HASHMAP_BEGIN; reach_type_t* t2; while((t2 = reach_type_cache_next(&t->subtypes, &j)) != NULL) { printf(" %s\n", t2->name); } } }
static void set_method_external_interface(reach_type_t* t, const char* name, uint32_t vtable_index) { size_t i = HASHMAP_BEGIN; reach_type_t* sub; while((sub = reach_type_cache_next(&t->subtypes, &i)) != NULL) { reach_method_name_t* n = reach_method_name(sub, name); if(n == NULL) continue; size_t j = HASHMAP_BEGIN; reach_method_t* m; while((m = reach_mangled_next(&n->r_mangled, &j)) != NULL) { if(m->vtable_index == vtable_index) { compile_method_t* c_m = (compile_method_t*)m->c_method; LLVMSetFunctionCallConv(c_m->func, LLVMCCallConv); LLVMSetLinkage(c_m->func, LLVMExternalLinkage); break; } } } }
static void print_methods(compile_t* c, reach_type_t* t, printbuf_t* buf) { size_t i = HASHMAP_BEGIN; reach_method_name_t* n; while((n = reach_method_names_next(&t->methods, &i)) != NULL) { size_t j = HASHMAP_BEGIN; reach_method_t* m; while((m = reach_mangled_next(&n->r_mangled, &j)) != NULL) print_method(c, buf, t, m); } }
static void add_methods_to_type(reach_t* r, reach_type_t* from, reach_type_t* to, pass_opt_t* opt) { size_t i = HASHMAP_BEGIN; reach_method_name_t* n; while((n = reach_method_names_next(&from->methods, &i)) != NULL) { size_t j = HASHMAP_BEGIN; reach_method_t* m; while((m = reach_mangled_next(&n->r_mangled, &j)) != NULL) add_rmethod_to_subtype(r, to, n, m, opt); } }
static LLVMValueRef make_vtable(compile_t* c, reach_type_t* t) { if(t->vtable_size == 0) return LLVMConstArray(c->void_ptr, NULL, 0); size_t buf_size = t->vtable_size * sizeof(LLVMValueRef); LLVMValueRef* vtable = (LLVMValueRef*)ponyint_pool_alloc_size(buf_size); memset(vtable, 0, buf_size); size_t i = HASHMAP_BEGIN; reach_method_name_t* n; while((n = reach_method_names_next(&t->methods, &i)) != NULL) { size_t j = HASHMAP_BEGIN; reach_method_t* m; while((m = reach_mangled_next(&n->r_mangled, &j)) != NULL) { uint32_t index = m->vtable_index; assert(index != (uint32_t)-1); assert(vtable[index] == NULL); if(t->primitive != NULL) vtable[index] = make_unbox_function(c, t, m); else vtable[index] = make_desc_ptr(m->func, c->void_ptr); } } for(uint32_t i = 0; i < t->vtable_size; i++) { if(vtable[i] == NULL) vtable[i] = LLVMConstNull(c->void_ptr); } LLVMValueRef r = LLVMConstArray(c->void_ptr, vtable, t->vtable_size); ponyint_pool_free_size(buf_size, vtable); return r; }