|
@@ -1,260 +1,21 @@
|
|
|
gb_internal TB_FunctionPrototype *cg_procedure_type_as_prototype(cgModule *m, Type *type) {
|
|
|
- // TODO(bill): cache the procedure type generation
|
|
|
- GB_ASSERT(build_context.metrics.os == TargetOs_windows);
|
|
|
-
|
|
|
- GB_ASSERT(type != nullptr);
|
|
|
- type = base_type(type);
|
|
|
- GB_ASSERT(type->kind == Type_Proc);
|
|
|
- TypeProc *pt = &type->Proc;
|
|
|
-
|
|
|
- auto params = array_make<TB_PrototypeParam>(heap_allocator(), 0, pt->param_count);
|
|
|
- if (pt->params) for (Entity *e : pt->params->Tuple.variables) {
|
|
|
- TB_PrototypeParam param = {};
|
|
|
-
|
|
|
- Type *t = core_type(e->type);
|
|
|
- i64 sz = type_size_of(t);
|
|
|
- switch (t->kind) {
|
|
|
- case Type_Basic:
|
|
|
- switch (t->Basic.kind) {
|
|
|
- case Basic_bool:
|
|
|
- case Basic_b8:
|
|
|
- case Basic_b16:
|
|
|
- case Basic_b32:
|
|
|
- case Basic_b64:
|
|
|
- case Basic_i8:
|
|
|
- case Basic_u8:
|
|
|
- case Basic_i16:
|
|
|
- case Basic_u16:
|
|
|
- case Basic_i32:
|
|
|
- case Basic_u32:
|
|
|
- case Basic_i64:
|
|
|
- case Basic_u64:
|
|
|
- case Basic_i128:
|
|
|
- case Basic_u128:
|
|
|
- case Basic_rune:
|
|
|
- case Basic_int:
|
|
|
- case Basic_uint:
|
|
|
- case Basic_uintptr:
|
|
|
- param.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
|
|
|
- break;
|
|
|
-
|
|
|
- case Basic_f16: param.dt = TB_TYPE_F16; break;
|
|
|
- case Basic_f32: param.dt = TB_TYPE_F32; break;
|
|
|
- case Basic_f64: param.dt = TB_TYPE_F64; break;
|
|
|
-
|
|
|
- case Basic_complex32:
|
|
|
- case Basic_complex64:
|
|
|
- case Basic_complex128:
|
|
|
- case Basic_quaternion64:
|
|
|
- case Basic_quaternion128:
|
|
|
- case Basic_quaternion256:
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
-
|
|
|
+ GB_ASSERT(is_type_proc(type));
|
|
|
+ mutex_lock(&m->proc_proto_mutex);
|
|
|
+ defer (mutex_unlock(&m->proc_proto_mutex));
|
|
|
|
|
|
- case Basic_rawptr:
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
- case Basic_string: // ^u8 + int
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
- case Basic_cstring: // ^u8
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
- case Basic_any: // rawptr + ^Type_Info
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
-
|
|
|
- case Basic_typeid:
|
|
|
- param.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
|
|
|
- break;
|
|
|
-
|
|
|
- // Endian Specific Types
|
|
|
- case Basic_i16le:
|
|
|
- case Basic_u16le:
|
|
|
- case Basic_i32le:
|
|
|
- case Basic_u32le:
|
|
|
- case Basic_i64le:
|
|
|
- case Basic_u64le:
|
|
|
- case Basic_i128le:
|
|
|
- case Basic_u128le:
|
|
|
- case Basic_i16be:
|
|
|
- case Basic_u16be:
|
|
|
- case Basic_i32be:
|
|
|
- case Basic_u32be:
|
|
|
- case Basic_i64be:
|
|
|
- case Basic_u64be:
|
|
|
- case Basic_i128be:
|
|
|
- case Basic_u128be:
|
|
|
- param.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
|
|
|
- break;
|
|
|
-
|
|
|
- case Basic_f16le: param.dt = TB_TYPE_F16; break;
|
|
|
- case Basic_f32le: param.dt = TB_TYPE_F32; break;
|
|
|
- case Basic_f64le: param.dt = TB_TYPE_F64; break;
|
|
|
-
|
|
|
- case Basic_f16be: param.dt = TB_TYPE_F16; break;
|
|
|
- case Basic_f32be: param.dt = TB_TYPE_F32; break;
|
|
|
- case Basic_f64be: param.dt = TB_TYPE_F64; break;
|
|
|
- }
|
|
|
-
|
|
|
- case Type_Pointer:
|
|
|
- case Type_MultiPointer:
|
|
|
- case Type_Proc:
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- switch (sz) {
|
|
|
- case 1: param.dt = TB_TYPE_I8; break;
|
|
|
- case 2: param.dt = TB_TYPE_I16; break;
|
|
|
- case 4: param.dt = TB_TYPE_I32; break;
|
|
|
- case 8: param.dt = TB_TYPE_I64; break;
|
|
|
- default:
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (param.dt.raw != 0) {
|
|
|
- if (is_blank_ident(e->token)) {
|
|
|
- param.name = alloc_cstring(temporary_allocator(), e->token.string);
|
|
|
- }
|
|
|
- param.debug_type = cg_debug_type(m, e->type);
|
|
|
- array_add(¶ms, param);
|
|
|
- }
|
|
|
+ if (type->kind == Type_Named) {
|
|
|
+ type = base_type(type);
|
|
|
}
|
|
|
-
|
|
|
- auto results = array_make<TB_PrototypeParam>(heap_allocator(), 0, 1);
|
|
|
-
|
|
|
- Type *result_type = reduce_tuple_to_single_type(pt->results);
|
|
|
-
|
|
|
- if (result_type) {
|
|
|
- bool return_is_tuple = result_type->kind == Type_Tuple && is_calling_convention_odin(pt->calling_convention);
|
|
|
-
|
|
|
- if (return_is_tuple) {
|
|
|
- for (isize i = 0; i < result_type->Tuple.variables.count-1; i++) {
|
|
|
- Entity *e = result_type->Tuple.variables[i];
|
|
|
- TB_PrototypeParam param = {};
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- param.debug_type = cg_debug_type(m, alloc_type_pointer(e->type));
|
|
|
- array_add(¶ms, param);
|
|
|
- }
|
|
|
-
|
|
|
- result_type = result_type->Tuple.variables[result_type->Tuple.variables.count-1]->type;
|
|
|
- }
|
|
|
-
|
|
|
- Type *rt = core_type(result_type);
|
|
|
- i64 sz = type_size_of(rt);
|
|
|
-
|
|
|
- TB_PrototypeParam result = {};
|
|
|
-
|
|
|
- switch (rt->kind) {
|
|
|
- case Type_Basic:
|
|
|
- switch (rt->Basic.kind) {
|
|
|
- case Basic_bool:
|
|
|
- case Basic_b8:
|
|
|
- case Basic_b16:
|
|
|
- case Basic_b32:
|
|
|
- case Basic_b64:
|
|
|
- case Basic_i8:
|
|
|
- case Basic_u8:
|
|
|
- case Basic_i16:
|
|
|
- case Basic_u16:
|
|
|
- case Basic_i32:
|
|
|
- case Basic_u32:
|
|
|
- case Basic_i64:
|
|
|
- case Basic_u64:
|
|
|
- case Basic_i128:
|
|
|
- case Basic_u128:
|
|
|
- case Basic_rune:
|
|
|
- case Basic_int:
|
|
|
- case Basic_uint:
|
|
|
- case Basic_uintptr:
|
|
|
- result.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
|
|
|
- break;
|
|
|
-
|
|
|
- case Basic_f16: result.dt = TB_TYPE_I16; break;
|
|
|
- case Basic_f32: result.dt = TB_TYPE_F32; break;
|
|
|
- case Basic_f64: result.dt = TB_TYPE_F64; break;
|
|
|
-
|
|
|
- case Basic_rawptr:
|
|
|
- result.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
- case Basic_cstring: // ^u8
|
|
|
- result.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
-
|
|
|
- case Basic_typeid:
|
|
|
- result.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
|
|
|
- break;
|
|
|
-
|
|
|
- // Endian Specific Types
|
|
|
- case Basic_i16le:
|
|
|
- case Basic_u16le:
|
|
|
- case Basic_i32le:
|
|
|
- case Basic_u32le:
|
|
|
- case Basic_i64le:
|
|
|
- case Basic_u64le:
|
|
|
- case Basic_i128le:
|
|
|
- case Basic_u128le:
|
|
|
- case Basic_i16be:
|
|
|
- case Basic_u16be:
|
|
|
- case Basic_i32be:
|
|
|
- case Basic_u32be:
|
|
|
- case Basic_i64be:
|
|
|
- case Basic_u64be:
|
|
|
- case Basic_i128be:
|
|
|
- case Basic_u128be:
|
|
|
- result.dt = TB_TYPE_INTN(cast(u16)gb_min(64, 8*sz));
|
|
|
- break;
|
|
|
-
|
|
|
- case Basic_f16le: result.dt = TB_TYPE_I16; break;
|
|
|
- case Basic_f32le: result.dt = TB_TYPE_F32; break;
|
|
|
- case Basic_f64le: result.dt = TB_TYPE_F64; break;
|
|
|
-
|
|
|
- case Basic_f16be: result.dt = TB_TYPE_I16; break;
|
|
|
- case Basic_f32be: result.dt = TB_TYPE_F32; break;
|
|
|
- case Basic_f64be: result.dt = TB_TYPE_F64; break;
|
|
|
- }
|
|
|
-
|
|
|
- case Type_Pointer:
|
|
|
- case Type_MultiPointer:
|
|
|
- case Type_Proc:
|
|
|
- result.dt = TB_TYPE_PTR;
|
|
|
- break;
|
|
|
-
|
|
|
- default:
|
|
|
- switch (sz) {
|
|
|
- case 1: result.dt = TB_TYPE_I8; break;
|
|
|
- case 2: result.dt = TB_TYPE_I16; break;
|
|
|
- case 4: result.dt = TB_TYPE_I32; break;
|
|
|
- case 8: result.dt = TB_TYPE_I64; break;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (result.dt.raw != 0) {
|
|
|
- result.debug_type = cg_debug_type(m, result_type);
|
|
|
- array_add(&results, result);
|
|
|
- } else {
|
|
|
- result.debug_type = cg_debug_type(m, alloc_type_pointer(result_type));
|
|
|
- result.dt = TB_TYPE_PTR;
|
|
|
-
|
|
|
- array_resize(¶ms, params.count+1);
|
|
|
- array_copy(¶ms, params, 1);
|
|
|
- params[0] = result;
|
|
|
- }
|
|
|
+ TB_FunctionPrototype **found = map_get(&m->proc_proto_map, type);
|
|
|
+ if (found) {
|
|
|
+ return *found;
|
|
|
}
|
|
|
|
|
|
- if (pt->calling_convention == ProcCC_Odin) {
|
|
|
- TB_PrototypeParam param = {};
|
|
|
- param.dt = TB_TYPE_PTR;
|
|
|
- param.debug_type = cg_debug_type(m, t_context_ptr);
|
|
|
- param.name = "__.context_ptr";
|
|
|
- array_add(¶ms, param);
|
|
|
- }
|
|
|
+ TB_DebugType *dbg = cg_debug_type_for_proc(m, type);
|
|
|
+ TB_FunctionPrototype *proto = tb_prototype_from_dbg(m->mod, dbg);
|
|
|
|
|
|
- return tb_prototype_create(m->mod, TB_CDECL, params.count, params.data, results.count, results.data, pt->c_vararg);
|
|
|
+ map_set(&m->proc_proto_map, type, proto);
|
|
|
+ return proto;
|
|
|
}
|
|
|
|
|
|
gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool ignore_body=false) {
|
|
@@ -327,9 +88,6 @@ gb_internal cgProcedure *cg_procedure_create(cgModule *m, Entity *entity, bool i
|
|
|
TB_Arena *arena = tb_default_arena();
|
|
|
p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE);
|
|
|
|
|
|
- // p->proto = cg_procedure_type_as_prototype(m, p->type);
|
|
|
- // tb_function_set_prototype(p->func, p->proto, arena);
|
|
|
-
|
|
|
size_t out_param_count = 0;
|
|
|
p->debug_type = cg_debug_type_for_proc(m, p->type);
|
|
|
TB_Node **params = tb_function_set_prototype_from_dbg(p->func, p->debug_type, arena, &out_param_count);
|
|
@@ -382,8 +140,6 @@ gb_internal cgProcedure *cg_procedure_create_dummy(cgModule *m, String const &li
|
|
|
TB_Arena *arena = tb_default_arena();
|
|
|
p->func = tb_function_create(m->mod, link_name.len, cast(char const *)link_name.text, linkage, TB_COMDAT_NONE);
|
|
|
|
|
|
- // p->proto = cg_procedure_type_as_prototype(m, p->type);
|
|
|
- // tb_function_set_prototype(p->func, p->proto, arena);
|
|
|
size_t out_param_count = 0;
|
|
|
p->debug_type = cg_debug_type_for_proc(m, p->type);
|
|
|
TB_Node **params = tb_function_set_prototype_from_dbg(p->func, p->debug_type, arena, &out_param_count);
|
|
@@ -425,16 +181,13 @@ gb_internal void cg_procedure_begin(cgProcedure *p) {
|
|
|
}
|
|
|
|
|
|
TB_Node *param = p->param_nodes[param_index++];
|
|
|
- TB_Node *ptr = tb_inst_local(p->func, cast(TB_CharUnits)type_size_of(e->type), cast(TB_CharUnits)type_align_of(e->type));
|
|
|
- TB_DataType dt = cg_data_type(e->type);
|
|
|
- tb_inst_store(p->func, dt, ptr, param, cast(TB_CharUnits)type_align_of(e->type), false);
|
|
|
- cgValue local = cg_value(ptr, alloc_type_pointer(e->type));
|
|
|
+ cgValue local = cg_value(param, alloc_type_pointer(e->type));
|
|
|
|
|
|
if (e != nullptr && e->token.string.len > 0 && e->token.string != "_") {
|
|
|
// NOTE(bill): for debugging purposes only
|
|
|
String name = e->token.string;
|
|
|
TB_DebugType *debug_type = cg_debug_type(p->module, e->type);
|
|
|
- tb_node_append_attrib(ptr, tb_function_attrib_variable(p->func, name.len, cast(char const *)name.text, debug_type));
|
|
|
+ tb_node_append_attrib(param, tb_function_attrib_variable(p->func, name.len, cast(char const *)name.text, debug_type));
|
|
|
|
|
|
}
|
|
|
cgAddr addr = cg_addr(local);
|