static LLVMValueRef make_trait_list(compile_t* c, reach_type_t* t, uint32_t* final_count) { // The list is an array of integers. uint32_t* tid; size_t tid_size; uint32_t count = trait_count(t, &tid, &tid_size); // If we have no traits, return a null pointer to a list. if(count == 0) return LLVMConstNull(LLVMPointerType(LLVMArrayType(c->i32, 0), 0)); // Create a constant array of trait identifiers. size_t list_size = count * sizeof(LLVMValueRef); LLVMValueRef* list = (LLVMValueRef*)ponyint_pool_alloc_size(list_size); for(uint32_t i = 0; i < count; i++) list[i] = LLVMConstInt(c->i32, tid[i], false); LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count); // Create a global to hold the array. const char* name = genname_traitlist(t->name); LLVMTypeRef list_type = LLVMArrayType(c->i32, count); LLVMValueRef global = LLVMAddGlobal(c->module, list_type, name); LLVMSetGlobalConstant(global, true); LLVMSetLinkage(global, LLVMPrivateLinkage); LLVMSetInitializer(global, trait_array); ponyint_pool_free_size(tid_size, tid); ponyint_pool_free_size(list_size, list); *final_count = count; return global; }
LLVMTypeRef gendesc_type(compile_t* c, gentype_t* g) { const char* desc_name; uint32_t traits = 0; uint32_t fields = 0; uint32_t vtable_size = 0; if(g != NULL) { // TODO: wrong trait count desc_name = g->desc_name; traits = trait_count(c, g, NULL, NULL); if(g->underlying == TK_TUPLETYPE) { fields = g->field_count; } else { vtable_size = genfun_vtable_size(c, g); } } else { desc_name = genname_descriptor(NULL); } LLVMTypeRef type = LLVMGetTypeByName(c->module, desc_name); if(type == NULL) { type = LLVMStructCreateNamed(c->context, desc_name); } else if(!LLVMIsOpaqueStruct(type)) { return type; } LLVMTypeRef params[DESC_LENGTH]; params[DESC_ID] = c->i32; params[DESC_SIZE] = c->i32; params[DESC_TRAIT_COUNT] = c->i32; params[DESC_FIELD_COUNT] = c->i32; params[DESC_FIELD_OFFSET] = c->i32; params[DESC_TRACE] = c->trace_fn; params[DESC_SERIALISE] = c->trace_fn; params[DESC_DESERIALISE] = c->trace_fn; params[DESC_DISPATCH] = c->dispatch_fn; params[DESC_FINALISE] = c->final_fn; params[DESC_EVENT_NOTIFY] = c->i32; params[DESC_TRAITS] = LLVMPointerType(LLVMArrayType(c->i32, traits), 0); params[DESC_FIELDS] = LLVMPointerType( LLVMArrayType(c->field_descriptor, fields), 0); params[DESC_VTABLE] = LLVMArrayType(c->void_ptr, vtable_size); LLVMStructSetBody(type, params, DESC_LENGTH, false); return type; }
void gendesc_type(compile_t* c, reach_type_t* t) { switch(t->underlying) { case TK_TUPLETYPE: case TK_PRIMITIVE: case TK_STRUCT: case TK_CLASS: case TK_ACTOR: break; default: return; } const char* desc_name = genname_descriptor(t->name); uint32_t traits = trait_count(t, NULL, NULL); uint32_t fields = 0; uint32_t vtable_size = 0; if(t->underlying == TK_TUPLETYPE) fields = t->field_count; else vtable_size = t->vtable_size; t->desc_type = LLVMStructCreateNamed(c->context, desc_name); LLVMTypeRef params[DESC_LENGTH]; params[DESC_ID] = c->i32; params[DESC_SIZE] = c->i32; params[DESC_TRAIT_COUNT] = c->i32; params[DESC_FIELD_COUNT] = c->i32; params[DESC_FIELD_OFFSET] = c->i32; params[DESC_INSTANCE] = c->object_ptr; params[DESC_TRACE] = c->trace_fn; params[DESC_SERIALISE_TRACE] = c->trace_fn; params[DESC_SERIALISE] = c->serialise_fn; params[DESC_DESERIALISE] = c->trace_fn; params[DESC_DISPATCH] = c->dispatch_fn; params[DESC_FINALISE] = c->final_fn; params[DESC_EVENT_NOTIFY] = c->i32; params[DESC_TRAITS] = LLVMPointerType(LLVMArrayType(c->i32, traits), 0); params[DESC_FIELDS] = LLVMPointerType( LLVMArrayType(c->field_descriptor, fields), 0); params[DESC_VTABLE] = LLVMArrayType(c->void_ptr, vtable_size); LLVMStructSetBody(t->desc_type, params, DESC_LENGTH, false); t->desc = LLVMAddGlobal(c->module, t->desc_type, desc_name); LLVMSetGlobalConstant(t->desc, true); LLVMSetLinkage(t->desc, LLVMPrivateLinkage); }
static LLVMValueRef make_trait_list(compile_t* c, gentype_t* g) { // The list is an array of integers. uint32_t count = trait_count(c, g); // If we have no traits, return a null pointer to a list. if(count == 0) return LLVMConstNull(LLVMPointerType(LLVMArrayType(c->i32, 0), 0)); // Sort the trait identifiers. size_t tid_size = count * sizeof(uint32_t); uint32_t* tid = (uint32_t*)pool_alloc_size(tid_size); reachable_type_t* t = reach_type(c->reachable, g->type_name); assert(t != NULL); size_t i = HASHMAP_BEGIN; size_t index = 0; reachable_type_t* provide; while((provide = reachable_type_cache_next(&t->subtypes, &i)) != NULL) tid[index++] = provide->type_id; qsort(tid, index, sizeof(uint32_t), cmp_uint32); index = unique_uint32(tid, index); // Create a constant array of trait identifiers. size_t list_size = index * sizeof(LLVMValueRef); LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(list_size); for(i = 0; i < index; i++) list[i] = LLVMConstInt(c->i32, tid[i], false); count = (uint32_t)index; LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count); // Create a global to hold the array. const char* name = genname_traitlist(g->type_name); LLVMTypeRef type = LLVMArrayType(c->i32, count); LLVMValueRef global = LLVMAddGlobal(c->module, type, name); LLVMSetGlobalConstant(global, true); LLVMSetLinkage(global, LLVMInternalLinkage); LLVMSetInitializer(global, trait_array); pool_free_size(tid_size, tid); pool_free_size(list_size, list); return global; }
static LLVMValueRef make_trait_list(compile_t* c, gentype_t* g) { // The list is an array of integers. uint32_t count = trait_count(c, g); LLVMTypeRef type = LLVMArrayType(c->i32, count); // If we have no traits, return a null pointer to a list. if(count == 0) return LLVMConstNull(LLVMPointerType(type, 0)); // Create a constant array of trait identifiers. size_t buf_size = count *sizeof(LLVMValueRef); LLVMValueRef* list = (LLVMValueRef*)pool_alloc_size(buf_size); reachable_type_t* t = reach_type(c->reachable, g->type_name); assert(t != NULL); size_t i = HASHMAP_BEGIN; size_t index = 0; reachable_type_t* provide; while((provide = reachable_type_cache_next(&t->subtypes, &i)) != NULL) list[index++] = make_type_id(c, provide->name); LLVMValueRef trait_array = LLVMConstArray(c->i32, list, count); // Create a global to hold the array. const char* name = genname_traitlist(g->type_name); LLVMValueRef global = LLVMAddGlobal(c->module, type, name); LLVMSetGlobalConstant(global, true); LLVMSetLinkage(global, LLVMInternalLinkage); LLVMSetInitializer(global, trait_array); pool_free_size(buf_size, list); return global; }
static LLVMValueRef make_trait_count(compile_t* c, gentype_t* g) { return LLVMConstInt(c->i32, trait_count(c, g), false); }