static void primitive_call(compile_t* c, const char* method, LLVMValueRef arg) { size_t count = 1; if(arg != NULL) count++; size_t i = HASHMAP_BEGIN; reachable_type_t* t; while((t = reachable_types_next(c->reachable, &i)) != NULL) { if(ast_id(t->type) == TK_TUPLETYPE) continue; ast_t* def = (ast_t*)ast_data(t->type); if(ast_id(def) != TK_PRIMITIVE) continue; reachable_method_name_t* n = reach_method_name(t, method); if(n == NULL) continue; gentype_t g; if(!gentype(c, t->type, &g)) { assert(0); return; } LLVMValueRef fun = genfun_proto(c, &g, method, NULL); assert(fun != NULL); LLVMValueRef args[2]; args[0] = g.instance; args[1] = arg; codegen_call(c, fun, args, count); } }
static LLVMValueRef dispatch_function(compile_t* c, ast_t* from, gentype_t* g, LLVMValueRef l_value, const char* method_name, ast_t* typeargs) { LLVMValueRef func; if(g->use_type == c->object_ptr) { // Virtual, get the function by selector colour. uint32_t index = genfun_vtable_index(c, g, method_name, typeargs); assert(index != (uint32_t)-1); // Get the function from the vtable. func = gendesc_vtable(c, l_value, index); // Cast to the right function type. LLVMTypeRef f_type = genfun_sig(c, g, method_name, typeargs); if(f_type == NULL) { ast_error(from, "couldn't create a signature for '%s'", method_name); return NULL; } f_type = LLVMPointerType(f_type, 0); func = LLVMBuildBitCast(c->builder, func, f_type, "method"); } else { // Static, get the actual function. func = genfun_proto(c, g, method_name, typeargs); if(func == NULL) { ast_error(from, "couldn't locate '%s'", method_name); return NULL; } } return func; }