static void make_dispatch(compile_t* c, gentype_t* g) { // Do nothing if we're not an actor. if(g->underlying != TK_ACTOR) return; // Create a dispatch function. const char* dispatch_name = genname_dispatch(g->type_name); g->dispatch_fn = codegen_addfun(c, dispatch_name, c->dispatch_type); LLVMSetFunctionCallConv(g->dispatch_fn, LLVMCCallConv); codegen_startfun(c, g->dispatch_fn, false); LLVMBasicBlockRef unreachable = codegen_block(c, "unreachable"); // Read the message ID. LLVMValueRef msg = LLVMGetParam(g->dispatch_fn, 2); LLVMValueRef id_ptr = LLVMBuildStructGEP(c->builder, msg, 1, ""); LLVMValueRef id = LLVMBuildLoad(c->builder, id_ptr, "id"); // Store a reference to the dispatch switch. When we build behaviours, we // will add cases to this switch statement based on message ID. g->dispatch_switch = LLVMBuildSwitch(c->builder, id, unreachable, 0); // Mark the default case as unreachable. LLVMPositionBuilderAtEnd(c->builder, unreachable); LLVMBuildUnreachable(c->builder); codegen_finishfun(c); }
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); }