void gendesc_init(compile_t* c, reach_type_t* t) { if(t->desc_type == NULL) return; // Initialise the global descriptor. uint32_t event_notify_index = reach_vtable_index(t, c->str__event_notify); uint32_t size = (uint32_t)LLVMABISizeOfType(c->target_data, t->structure); uint32_t trait_count = 0; LLVMValueRef trait_list = make_trait_list(c, t, &trait_count); LLVMValueRef args[DESC_LENGTH]; args[DESC_ID] = LLVMConstInt(c->i32, t->type_id, false); args[DESC_SIZE] = LLVMConstInt(c->i32, size, false); args[DESC_TRAIT_COUNT] = LLVMConstInt(c->i32, trait_count, false); args[DESC_FIELD_COUNT] = make_field_count(c, t); args[DESC_FIELD_OFFSET] = make_field_offset(c, t); args[DESC_TRACE] = make_function_ptr(t->trace_fn, c->trace_fn); args[DESC_SERIALISE] = make_function_ptr(t->serialise_fn, c->trace_fn); args[DESC_DESERIALISE] = make_function_ptr(t->deserialise_fn, c->trace_fn); args[DESC_DISPATCH] = make_function_ptr(t->dispatch_fn, c->dispatch_fn); args[DESC_FINALISE] = make_function_ptr(t->final_fn, c->final_fn); args[DESC_EVENT_NOTIFY] = LLVMConstInt(c->i32, event_notify_index, false); args[DESC_TRAITS] = trait_list; args[DESC_FIELDS] = make_field_list(c, t); args[DESC_VTABLE] = make_vtable(c, t); LLVMValueRef desc = LLVMConstNamedStruct(t->desc_type, args, DESC_LENGTH); LLVMSetInitializer(t->desc, desc); LLVMSetGlobalConstant(t->desc, true); }
void gendesc_init(compile_t* c, gentype_t* g) { // Initialise the global descriptor. uint32_t size = (uint32_t)LLVMABISizeOfType(c->target_data, g->structure); // Generate a separate type ID for every type. LLVMValueRef args[DESC_LENGTH]; args[DESC_ID] = make_type_id(c, g->type_name); args[DESC_SIZE] = LLVMConstInt(c->i32, size, false); args[DESC_TRAIT_COUNT] = make_trait_count(c, g); args[DESC_FIELD_COUNT] = make_field_count(c, g); args[DESC_TRACE] = make_function_ptr(c, genname_trace(g->type_name), c->trace_fn); args[DESC_SERIALISE] = make_function_ptr(c, genname_serialise(g->type_name), c->trace_fn); args[DESC_DESERIALISE] = make_function_ptr(c, genname_deserialise(g->type_name), c->trace_fn); args[DESC_DISPATCH] = make_function_ptr(c, genname_dispatch(g->type_name), c->dispatch_fn); args[DESC_FINALISE] = make_function_ptr(c, genname_finalise(g->type_name), c->final_fn); args[DESC_EVENT_NOTIFY] = LLVMConstInt(c->i32, genfun_vtable_index(c, g, stringtab("_event_notify"), NULL), false); args[DESC_TRAITS] = make_trait_list(c, g); args[DESC_FIELDS] = make_field_list(c, g); args[DESC_VTABLE] = make_vtable(c, g); LLVMValueRef desc = LLVMConstNamedStruct(g->desc_type, args, DESC_LENGTH); LLVMSetInitializer(g->desc, desc); LLVMSetGlobalConstant(g->desc, true); }
static LLVMValueRef make_vtable(compile_t* c, gentype_t* g) { uint32_t vtable_size = genfun_vtable_size(c, g); if(vtable_size == 0) return LLVMConstArray(c->void_ptr, NULL, 0); size_t buf_size = vtable_size * sizeof(LLVMValueRef); LLVMValueRef* vtable = (LLVMValueRef*)pool_alloc_size(buf_size); memset(vtable, 0, buf_size); reachable_type_t* t = reach_type(c->reachable, g->type_name); size_t i = HASHMAP_BEGIN; reachable_method_name_t* n; while((n = reachable_method_names_next(&t->methods, &i)) != NULL) { size_t j = HASHMAP_BEGIN; reachable_method_t* m; while((m = reachable_methods_next(&n->r_methods, &j)) != NULL) { const char* fullname = genname_fun(t->name, n->name, m->typeargs); token_id t = ast_id(m->r_fun); switch(t) { case TK_NEW: case TK_BE: if(g->underlying == TK_ACTOR) fullname = genname_be(fullname); break; default: {} } uint32_t index = m->vtable_index; assert(index != (uint32_t)-1); assert(vtable[index] == NULL); if(g->primitive != NULL) vtable[index] = make_unbox_function(c, g, fullname, t); else vtable[index] = make_function_ptr(c, fullname, c->void_ptr); } } for(uint32_t i = 0; i < vtable_size; i++) { if(vtable[i] == NULL) vtable[i] = LLVMConstNull(c->void_ptr); } LLVMValueRef r = LLVMConstArray(c->void_ptr, vtable, vtable_size); pool_free_size(buf_size, vtable); return r; }
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_function_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; }