static LLVMValueRef genfun_newbe(compile_t* c, gentype_t* g, const char *name, ast_t* typeargs) { ast_t* fun = get_fun(g, name, typeargs); LLVMValueRef func = get_prototype(c, g, name, typeargs, fun); if(func == NULL) { ast_free_unattached(fun); return NULL; } codegen_startfun(c, func, ast_debug(fun)); name_params(c, g->ast, ast_childidx(fun, 3), func); genfun_dwarf(c, g, name, typeargs, fun); if(!gen_field_init(c, g)) { ast_free_unattached(fun); return NULL; } ast_t* body = ast_childidx(fun, 6); LLVMValueRef value = gen_expr(c, body); if(value == NULL) { ast_free_unattached(fun); return NULL; } LLVMBuildRetVoid(c->builder); codegen_finishfun(c); // Generate the sender. LLVMValueRef sender = get_sender(c, g, name, typeargs); codegen_startfun(c, sender, false); LLVMValueRef this_ptr = LLVMGetParam(sender, 0); // Send the arguments in a message to 'this'. uint32_t index = genfun_vtable_index(c, g, name, typeargs); LLVMTypeRef msg_type_ptr = send_message(c, fun, this_ptr, sender, index); genfun_dwarf_return(c, body); // Return 'this'. LLVMBuildRet(c->builder, this_ptr); codegen_finishfun(c); // Add the dispatch case. add_dispatch_case(c, g, fun, index, func, msg_type_ptr); ast_free_unattached(fun); return func; }
static bool genfun_newbe(compile_t* c, reachable_type_t* t, reachable_method_t* m) { assert(m->func != NULL); assert(m->func_handler != NULL); AST_GET_CHILDREN(m->r_fun, cap, id, typeparams, params, result, can_error, body); // Generate the handler. codegen_startfun(c, m->func_handler, m->di_file, m->di_method); name_params(c, t, m, params, m->func_handler); LLVMValueRef value = gen_expr(c, body); if(value == NULL) return false; LLVMBuildRetVoid(c->builder); codegen_finishfun(c); // Generate the sender. codegen_startfun(c, m->func, NULL, NULL); LLVMValueRef this_ptr = LLVMGetParam(m->func, 0); // Send the arguments in a message to 'this'. LLVMTypeRef msg_type_ptr = send_message(c, params, this_ptr, m->func, m->vtable_index); // Return 'this'. codegen_debugloc(c, ast_childlast(body)); LLVMBuildRet(c->builder, this_ptr); codegen_debugloc(c, NULL); codegen_finishfun(c); // Add the dispatch case. add_dispatch_case(c, t, params, m->vtable_index, m->func_handler, msg_type_ptr); return true; }