LLVMValueRef gen_string(compile_t* c, ast_t* ast) { ast_t* type = ast_type(ast); const char* name = ast_name(ast); size_t len = ast_name_len(ast); LLVMValueRef args[4]; args[0] = LLVMConstInt(c->i32, 0, false); args[1] = LLVMConstInt(c->i32, 0, false); LLVMValueRef str = LLVMConstStringInContext(c->context, name, (int)len, false); LLVMValueRef g_str = LLVMAddGlobal(c->module, LLVMTypeOf(str), ""); LLVMSetLinkage(g_str, LLVMPrivateLinkage); LLVMSetInitializer(g_str, str); LLVMSetGlobalConstant(g_str, true); LLVMValueRef str_ptr = LLVMConstInBoundsGEP(g_str, args, 2); reach_type_t* t = reach_type(c->reach, type); args[0] = t->desc; args[1] = LLVMConstInt(c->intptr, len, false); args[2] = LLVMConstInt(c->intptr, len + 1, false); args[3] = str_ptr; LLVMValueRef inst = LLVMConstNamedStruct(t->structure, args, 4); LLVMValueRef g_inst = LLVMAddGlobal(c->module, t->structure, ""); LLVMSetInitializer(g_inst, inst); LLVMSetGlobalConstant(g_inst, true); LLVMSetLinkage(g_inst, LLVMPrivateLinkage); return g_inst; }
static void make_global_instance(compile_t* c, gentype_t* g) { // Not a primitive type. if(g->underlying != TK_PRIMITIVE) return; // No instance for base types. if(g->primitive != NULL) return; // Check for an existing instance. const char* inst_name = genname_instance(g->type_name); g->instance = LLVMGetNamedGlobal(c->module, inst_name); if(g->instance != NULL) return; // Create a unique global instance. LLVMValueRef args[1]; args[0] = g->desc; LLVMValueRef value = LLVMConstNamedStruct(g->structure, args, 1); g->instance = LLVMAddGlobal(c->module, g->structure, inst_name); LLVMSetInitializer(g->instance, value); LLVMSetGlobalConstant(g->instance, true); LLVMSetLinkage(g->instance, LLVMInternalLinkage); }
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 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, t->abi_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_INSTANCE] = make_desc_ptr(t->instance, c->object_ptr); args[DESC_TRACE] = make_desc_ptr(t->trace_fn, c->trace_fn); args[DESC_SERIALISE_TRACE] = make_desc_ptr(t->serialise_trace_fn, c->trace_fn); args[DESC_SERIALISE] = make_desc_ptr(t->serialise_fn, c->serialise_fn); args[DESC_DESERIALISE] = make_desc_ptr(t->deserialise_fn, c->trace_fn); args[DESC_DISPATCH] = make_desc_ptr(t->dispatch_fn, c->dispatch_fn); args[DESC_FINALISE] = make_desc_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); }
LLVMValueRef ett_default_value(EagleComplexType *type) { switch(type->type) { case ETInt1: case ETInt8: case ETUInt8: case ETInt16: case ETUInt16: case ETInt32: case ETUInt32: case ETInt64: case ETUInt64: case ETEnum: return LLVMConstInt(ett_llvm_type(type), 0, 0); case ETFloat: case ETDouble: return LLVMConstReal(ett_llvm_type(type), 0.0); case ETPointer: return LLVMConstPointerNull(ett_llvm_type(type)); case ETStruct: { Arraylist *types; ty_struct_get_members(type, NULL, &types); LLVMValueRef vals[types->count]; for(int i = 0; i < types->count; i++) vals[i] = ett_default_value(types->items[i]); return LLVMConstNamedStruct(ett_llvm_type(type), vals, types->count); } case ETArray: { EagleArrayType *at = (EagleArrayType *)type; LLVMValueRef val = ett_default_value(at->of); LLVMValueRef vals[at->ct]; for(int i = 0; i < at->ct; i++) vals[i] = val; return LLVMConstArray(ett_llvm_type(at->of), vals, at->ct); } default: return NULL; } }
LLVMValueRef gen_string(compile_t* c, ast_t* ast) { const char* name = ast_name(ast); genned_string_t k; k.string = name; size_t index = HASHMAP_UNKNOWN; genned_string_t* string = genned_strings_get(&c->strings, &k, &index); if(string != NULL) return string->global; ast_t* type = ast_type(ast); pony_assert(is_literal(type, "String")); reach_type_t* t = reach_type(c->reach, type); compile_type_t* c_t = (compile_type_t*)t->c_type; size_t len = ast_name_len(ast); LLVMValueRef args[4]; args[0] = c_t->desc; args[1] = LLVMConstInt(c->intptr, len, false); args[2] = LLVMConstInt(c->intptr, len + 1, false); args[3] = codegen_string(c, name, len); LLVMValueRef inst = LLVMConstNamedStruct(c_t->structure, args, 4); LLVMValueRef g_inst = LLVMAddGlobal(c->module, c_t->structure, ""); LLVMSetInitializer(g_inst, inst); LLVMSetGlobalConstant(g_inst, true); LLVMSetLinkage(g_inst, LLVMPrivateLinkage); LLVMSetUnnamedAddr(g_inst, true); string = POOL_ALLOC(genned_string_t); string->string = name; string->global = g_inst; genned_strings_putindex(&c->strings, string, index); return g_inst; }
static void make_global_instance(compile_t* c, reach_type_t* t) { // Not a primitive type. if(t->underlying != TK_PRIMITIVE) return; // No instance for machine word types. if(t->primitive != NULL) return; // Create a unique global instance. const char* inst_name = genname_instance(t->name); LLVMValueRef args[1]; args[0] = t->desc; LLVMValueRef value = LLVMConstNamedStruct(t->structure, args, 1); t->instance = LLVMAddGlobal(c->module, t->structure, inst_name); LLVMSetInitializer(t->instance, value); LLVMSetGlobalConstant(t->instance, true); LLVMSetLinkage(t->instance, LLVMPrivateLinkage); }
LLVMValueRef gen_string(compile_t* c, ast_t* ast) { ast_t* type = ast_type(ast); const char* name = ast_name(ast); size_t len = strlen(name); LLVMValueRef args[4]; args[0] = LLVMConstInt(c->i32, 0, false); args[1] = LLVMConstInt(c->i32, 0, false); LLVMValueRef str = LLVMConstStringInContext(c->context, name, (int)len, false); LLVMValueRef g_str = LLVMAddGlobal(c->module, LLVMTypeOf(str), "$strval"); LLVMSetLinkage(g_str, LLVMInternalLinkage); LLVMSetInitializer(g_str, str); LLVMSetGlobalConstant(g_str, true); LLVMValueRef str_ptr = LLVMConstInBoundsGEP(g_str, args, 2); gentype_t g; if(!gentype(c, type, &g)) return NULL; args[0] = g.desc; args[1] = LLVMConstInt(c->i64, len, false); args[2] = LLVMConstInt(c->i64, 0, false); args[3] = str_ptr; LLVMValueRef inst = LLVMConstNamedStruct(g.structure, args, 4); LLVMValueRef g_inst = LLVMAddGlobal(c->module, g.structure, "$string"); LLVMSetInitializer(g_inst, inst); LLVMSetGlobalConstant(g_inst, true); LLVMSetLinkage(g_inst, LLVMInternalLinkage); return g_inst; }