Change runtime.Type_Info_Enum_Value to be i64 internally rather than a union

This commit is contained in:
gingerBill
2020-06-03 21:10:07 +01:00
parent 626b4740b1
commit d80049bfd2
4 changed files with 93 additions and 106 deletions
+68 -76
View File
@@ -158,10 +158,10 @@ fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info) {
sbprint :: proc(buf: ^strings.Builder, args: ..any) -> string { sbprint :: proc(buf: ^strings.Builder, args: ..any) -> string {
fi: Info; fi: Info;
prev_string := false;
fi.buf = buf; fi.buf = buf;
prev_string := false;
for arg, i in args { for arg, i in args {
is_string := arg != nil && reflect.is_string(type_info_of(arg.id)); is_string := arg != nil && reflect.is_string(type_info_of(arg.id));
if i > 0 && !is_string && !prev_string { if i > 0 && !is_string && !prev_string {
@@ -937,23 +937,68 @@ enum_value_to_string :: proc(val: any) -> (string, bool) {
#partial switch e in type_info.variant { #partial switch e in type_info.variant {
case: return "", false; case: return "", false;
case runtime.Type_Info_Enum: case runtime.Type_Info_Enum:
get_str :: proc(data: rawptr, e: runtime.Type_Info_Enum) -> (string, bool) { Enum_Value :: runtime.Type_Info_Enum_Value;
ev: Enum_Value;
ok := true;
bv := v;
bv.id = runtime.typeid_core(e.base.id);
switch i in bv {
case i8: ev = Enum_Value(i);
case i16: ev = Enum_Value(i);
case i32: ev = Enum_Value(i);
case i64: ev = Enum_Value(i);
case i128: ev = Enum_Value(i);
case int: ev = Enum_Value(i);
case u8: ev = Enum_Value(i);
case u16: ev = Enum_Value(i);
case u32: ev = Enum_Value(i);
case u64: ev = Enum_Value(i);
case u128: ev = Enum_Value(i);
case uint: ev = Enum_Value(i);
case uintptr: ev = Enum_Value(i);
case i16le: ev = Enum_Value(i);
case i32le: ev = Enum_Value(i);
case i64le: ev = Enum_Value(i);
case i128le: ev = Enum_Value(i);
case u16le: ev = Enum_Value(i);
case u32le: ev = Enum_Value(i);
case u64le: ev = Enum_Value(i);
case u128le: ev = Enum_Value(i);
case i16be: ev = Enum_Value(i);
case i32be: ev = Enum_Value(i);
case i64be: ev = Enum_Value(i);
case i128be: ev = Enum_Value(i);
case u16be: ev = Enum_Value(i);
case u32be: ev = Enum_Value(i);
case u64be: ev = Enum_Value(i);
case u128be: ev = Enum_Value(i);
case:
ok = false;
}
if ok {
if len(e.values) == 0 { if len(e.values) == 0 {
return "", true; return "", true;
} else { } else {
for _, idx in e.values { for val, idx in e.values {
val := &e.values[idx]; if val == ev {
// NOTE(bill): Removes need for parametric polymorphic check
res := mem.compare_ptrs(val, data, e.base.size);
if res == 0 {
return e.names[idx], true; return e.names[idx], true;
} }
} }
} }
return "", false; return "", false;
} }
return get_str(v.data, e);
} }
return "", false; return "", false;
@@ -1001,81 +1046,28 @@ stored_enum_value_to_string :: proc(enum_type: ^runtime.Type_Info, ev: runtime.T
#partial switch e in et.variant { #partial switch e in et.variant {
case: return "", false; case: return "", false;
case runtime.Type_Info_Enum: case runtime.Type_Info_Enum:
get_str :: proc(i: $T, e: runtime.Type_Info_Enum) -> (string, bool) { if reflect.is_string(e.base) {
if reflect.is_string(e.base) { for val, idx in e.values {
for val, idx in e.values { if val == ev {
if v, ok := val.(T); ok && v == i { return e.names[idx], true;
return e.names[idx], true;
}
} }
} else if len(e.values) == 0 { }
return "", true; } else if len(e.values) == 0 {
} else { return "", true;
for val, idx in e.values { } else {
if v, ok := val.(T); ok && v == i { for val, idx in e.values {
return e.names[idx], true; if val == ev {
} return e.names[idx], true;
} }
} }
return "", false;
}
switch v in ev {
case rune: return get_str(v + auto_cast offset, e);
case i8: return get_str(v + auto_cast offset, e);
case i16: return get_str(v + auto_cast offset, e);
case i32: return get_str(v + auto_cast offset, e);
case i64: return get_str(v + auto_cast offset, e);
case int: return get_str(v + auto_cast offset, e);
case u8: return get_str(v + auto_cast offset, e);
case u16: return get_str(v + auto_cast offset, e);
case u32: return get_str(v + auto_cast offset, e);
case u64: return get_str(v + auto_cast offset, e);
case uint: return get_str(v + auto_cast offset, e);
case uintptr: return get_str(v + auto_cast offset, e);
} }
return "", false;
} }
return "", false; return "", false;
} }
enum_value_to_u64 :: proc(ev: runtime.Type_Info_Enum_Value) -> u64 {
switch i in ev {
case rune: return u64(i);
case i8: return u64(i);
case i16: return u64(i);
case i32: return u64(i);
case i64: return u64(i);
case int: return u64(i);
case u8: return u64(i);
case u16: return u64(i);
case u32: return u64(i);
case u64: return u64(i);
case uint: return u64(i);
case uintptr: return u64(i);
}
return 0;
}
enum_value_to_i64 :: proc(ev: runtime.Type_Info_Enum_Value) -> i64 {
switch i in ev {
case rune: return i64(i);
case i8: return i64(i);
case i16: return i64(i);
case i32: return i64(i);
case i64: return i64(i);
case int: return i64(i);
case u8: return i64(i);
case u16: return i64(i);
case u32: return i64(i);
case u64: return i64(i);
case uint: return i64(i);
case uintptr: return i64(i);
}
return 0;
}
fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") { fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool { is_bit_set_different_endian_to_platform :: proc(ti: ^runtime.Type_Info) -> bool {
if ti == nil { if ti == nil {
@@ -1152,7 +1144,7 @@ fmt_bit_set :: proc(fi: ^Info, v: any, name: string = "") {
if commas > 0 do strings.write_string(fi.buf, ", "); if commas > 0 do strings.write_string(fi.buf, ", ");
if is_enum do for ev, evi in e.values { if is_enum do for ev, evi in e.values {
v := enum_value_to_u64(ev); v := u64(ev);
if v == u64(i) { if v == u64(i) {
strings.write_string(fi.buf, e.names[evi]); strings.write_string(fi.buf, e.names[evi]);
commas += 1; commas += 1;
@@ -1437,7 +1429,7 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
strings.write_byte(fi.buf, '.'); strings.write_byte(fi.buf, '.');
strings.write_string(fi.buf, idx); strings.write_string(fi.buf, idx);
} else { } else {
strings.write_i64(fi.buf, enum_value_to_i64(info.min_value)+i64(i)); strings.write_i64(fi.buf, i64(info.min_value)+i64(i));
} }
strings.write_string(fi.buf, " = "); strings.write_string(fi.buf, " = ");
+1 -5
View File
@@ -34,11 +34,7 @@ Calling_Convention :: enum u8 {
Fast = 5, Fast = 5,
} }
Type_Info_Enum_Value :: union { Type_Info_Enum_Value :: distinct i64;
rune,
i8, i16, i32, i64, int,
u8, u16, u32, u64, uint, uintptr,
};
Platform_Endianness :: enum u8 { Platform_Endianness :: enum u8 {
Platform = 0, Platform = 0,
+5 -5
View File
@@ -9799,7 +9799,7 @@ void ir_build_range_enum(irProcedure *proc, Type *enum_type, Type *val_type, irV
GB_ASSERT(are_types_identical(enum_type, val_type)); GB_ASSERT(are_types_identical(enum_type, val_type));
if (is_type_integer(core_elem)) { if (is_type_integer(core_elem)) {
irValue *i = ir_emit_load(proc, ir_emit_conv(proc, val_ptr, t_i64_ptr)); irValue *i = ir_emit_load(proc, val_ptr);
val = ir_emit_conv(proc, i, t); val = ir_emit_conv(proc, i, t);
} else { } else {
GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem)); GB_PANIC("TODO(bill): enum core type %s", type_to_string(core_elem));
@@ -11812,8 +11812,8 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
irValue *min_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.min_value); irValue *min_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.min_value);
irValue *max_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.max_value); irValue *max_v = ir_value_constant(core_type(t->EnumeratedArray.index), t->EnumeratedArray.max_value);
ir_emit_store_union_variant(proc, min_value, min_v, ir_type(min_v)); ir_emit_store(proc, min_value, min_v);
ir_emit_store_union_variant(proc, max_value, max_v, ir_type(max_v)); ir_emit_store(proc, max_value, max_v);
break; break;
} }
case Type_DynamicArray: { case Type_DynamicArray: {
@@ -11907,9 +11907,9 @@ void ir_setup_type_info_data(irProcedure *proc) { // NOTE(bill): Setup type_info
irValue *value_ep = ir_emit_array_epi(proc, value_array, cast(i32)i); irValue *value_ep = ir_emit_array_epi(proc, value_array, cast(i32)i);
ExactValue value = fields[i]->Constant.value; ExactValue value = fields[i]->Constant.value;
irValue *v = ir_value_constant(t->Enum.base_type, value); irValue *v = ir_value_constant(t_i64, value);
ir_emit_store_union_variant(proc, value_ep, v, ir_type(v)); ir_emit_store(proc, value_ep, v);
ir_emit_store(proc, name_ep, ir_const_string(proc->module, fields[i]->token.string)); ir_emit_store(proc, name_ep, ir_const_string(proc->module, fields[i]->token.string));
} }
+19 -20
View File
@@ -2027,6 +2027,11 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity) {
p->value = LLVMAddFunction(m->mod, c_link_name, func_type); p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
lbCallingConventionKind cc_kind = lbCallingConvention_C;
// TODO(bill): Clean up this logic
if (build_context.metrics.os != TargetOs_js) {
cc_kind = lb_calling_convention_map[pt->Proc.calling_convention];
}
LLVMSetFunctionCallConv(p->value, lb_calling_convention_map[pt->Proc.calling_convention]); LLVMSetFunctionCallConv(p->value, lb_calling_convention_map[pt->Proc.calling_convention]);
lbValue proc_value = {p->value, p->type}; lbValue proc_value = {p->value, p->type};
lb_add_entity(m, entity, proc_value); lb_add_entity(m, entity, proc_value);
@@ -4464,6 +4469,7 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
LLVMSetInitializer(global_data, data); LLVMSetInitializer(global_data, data);
LLVMSetLinkage(global_data, LLVMInternalLinkage);
LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
string_map_set(&m->const_strings, key, ptr); string_map_set(&m->const_strings, key, ptr);
@@ -4500,6 +4506,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
} }
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
LLVMSetInitializer(global_data, data); LLVMSetInitializer(global_data, data);
LLVMSetLinkage(global_data, LLVMInternalLinkage);
LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true); LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true);
@@ -11211,22 +11218,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
LLVMTypeRef align_type = lb_alignment_prefix_type_hack(m, type_align_of(t)); LLVMTypeRef align_type = lb_alignment_prefix_type_hack(m, type_align_of(t));
LLVMTypeRef array_type = LLVMArrayType(lb_type(m, t_u8), 8); LLVMTypeRef array_type = LLVMArrayType(lb_type(m, t_u8), 8);
LLVMTypeRef u64_type = lb_type(m, t_u64);
for_array(i, fields) { for_array(i, fields) {
ExactValue value = fields[i]->Constant.value;
lbValue v = lb_const_value(m, t->Enum.base_type, value);
LLVMValueRef zv = LLVMConstZExt(v.value, u64_type);
lbValue tag = lb_const_union_tag(m, t_type_info_enum_value, v.type);
LLVMValueRef vals[3] = {
LLVMConstNull(align_type),
zv,
tag.value,
};
name_values[i] = lb_const_string(m, fields[i]->token.string).value; name_values[i] = lb_const_string(m, fields[i]->token.string).value;
value_values[i] = LLVMConstStruct(vals, gb_count_of(vals), false); value_values[i] = lb_const_value(m, t_i64, fields[i]->Constant.value).value;
} }
LLVMValueRef name_init = LLVMConstArray(lb_type(m, t_string), name_values, cast(unsigned)fields.count); LLVMValueRef name_init = LLVMConstArray(lb_type(m, t_string), name_values, cast(unsigned)fields.count);
@@ -12211,21 +12206,25 @@ void lb_generate_code(lbGenerator *gen) {
} }
LLVMDIBuilderFinalize(m->debug_builder);
if (LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error)) {
gb_printf_err("LLVM Error: %s\n", llvm_error);
return;
}
llvm_error = nullptr;
if (build_context.keep_temp_files) { if (build_context.keep_temp_files) {
TIME_SECTION("LLVM Print Module to File"); TIME_SECTION("LLVM Print Module to File");
LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error); if (LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error)) {
// exit(1); gb_printf_err("LLVM Error: %s\n", llvm_error);
return;
}
} }
LLVMDIBuilderFinalize(m->debug_builder);
LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error);
llvm_error = nullptr;
TIME_SECTION("LLVM Object Generation"); TIME_SECTION("LLVM Object Generation");
LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile; LLVMCodeGenFileType code_gen_file_type = LLVMObjectFile;
LLVMBool was_an_error = LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error); if (LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, code_gen_file_type, &llvm_error)) {
if (was_an_error) {
gb_printf_err("LLVM Error: %s\n", llvm_error); gb_printf_err("LLVM Error: %s\n", llvm_error);
gb_exit(1); gb_exit(1);
return; return;