Reduce the size of runtime.Type_Info

This commit is contained in:
gingerBill
2024-07-14 21:37:35 +01:00
parent e7d37607ef
commit 399c3ab067
11 changed files with 114 additions and 94 deletions
+13 -13
View File
@@ -391,7 +391,7 @@ Struct_Field :: struct {
struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
if 0 <= i && i < len(s.names) {
if 0 <= i && i < int(s.field_count) {
field.name = s.names[i]
field.type = s.types[i]
field.tag = Struct_Tag(s.tags[i])
@@ -406,7 +406,7 @@ struct_field_at :: proc(T: typeid, i: int) -> (field: Struct_Field) {
struct_field_by_name :: proc(T: typeid, name: string) -> (field: Struct_Field) {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
for fname, i in s.names {
for fname, i in s.names[:s.field_count] {
if fname == name {
field.name = s.names[i]
field.type = s.types[i]
@@ -427,7 +427,7 @@ struct_field_value_by_name :: proc(a: any, field: string, allow_using := false)
ti := runtime.type_info_base(type_info_of(a.id))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
for name, i in s.names {
for name, i in s.names[:s.field_count] {
if name == field {
return any{
rawptr(uintptr(a.data) + s.offsets[i]),
@@ -463,7 +463,7 @@ struct_field_value :: proc(a: any, field: Struct_Field) -> any {
struct_field_names :: proc(T: typeid) -> []string {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
return s.names
return s.names[:s.field_count]
}
return nil
}
@@ -472,7 +472,7 @@ struct_field_names :: proc(T: typeid) -> []string {
struct_field_types :: proc(T: typeid) -> []^Type_Info {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
return s.types
return s.types[:s.field_count]
}
return nil
}
@@ -482,7 +482,7 @@ struct_field_types :: proc(T: typeid) -> []^Type_Info {
struct_field_tags :: proc(T: typeid) -> []Struct_Tag {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
return transmute([]Struct_Tag)s.tags
return transmute([]Struct_Tag)s.tags[:s.field_count]
}
return nil
}
@@ -491,7 +491,7 @@ struct_field_tags :: proc(T: typeid) -> []Struct_Tag {
struct_field_offsets :: proc(T: typeid) -> []uintptr {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
return s.offsets
return s.offsets[:s.field_count]
}
return nil
}
@@ -501,11 +501,11 @@ struct_fields_zipped :: proc(T: typeid) -> (fields: #soa[]Struct_Field) {
ti := runtime.type_info_base(type_info_of(T))
if s, ok := ti.variant.(runtime.Type_Info_Struct); ok {
return soa_zip(
name = s.names,
type = s.types,
tag = transmute([]Struct_Tag)s.tags,
offset = s.offsets,
is_using = s.usings,
name = s.names[:s.field_count],
type = s.types[:s.field_count],
tag = ([^]Struct_Tag)(s.tags)[:s.field_count],
offset = s.offsets[:s.field_count],
is_using = s.usings[:s.field_count],
)
}
return nil
@@ -1569,7 +1569,7 @@ equal :: proc(a, b: any, including_indirect_array_recursion := false, recursion_
if v.equal != nil {
return v.equal(a.data, b.data)
} else {
for offset, i in v.offsets {
for offset, i in v.offsets[:v.field_count] {
x := rawptr(uintptr(a.data) + offset)
y := rawptr(uintptr(b.data) + offset)
id := v.types[i].id
+13 -14
View File
@@ -115,16 +115,14 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
case Type_Info_Struct:
y := b.variant.(Type_Info_Struct) or_return
switch {
case len(x.types) != len(y.types),
x.is_packed != y.is_packed,
x.is_raw_union != y.is_raw_union,
x.custom_align != y.custom_align,
case x.field_count != y.field_count,
x.flags != y.flags,
x.soa_kind != y.soa_kind,
x.soa_base_type != y.soa_base_type,
x.soa_len != y.soa_len:
return false
}
for _, i in x.types {
for i in 0..<x.field_count {
xn, yn := x.names[i], y.names[i]
xt, yt := x.types[i], y.types[i]
xl, yl := x.tags[i], y.tags[i]
@@ -179,8 +177,8 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
case Type_Info_Bit_Field:
y := b.variant.(Type_Info_Bit_Field) or_return
if !are_types_identical(x.backing_type, y.backing_type) { return false }
if len(x.names) != len(y.names) { return false }
for _, i in x.names {
if x.field_count != y.field_count { return false }
for _, i in x.names[:x.field_count] {
if x.names[i] != y.names[i] {
return false
}
@@ -368,13 +366,13 @@ is_tuple :: proc(info: ^Type_Info) -> bool {
is_struct :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
s, ok := type_info_base(info).variant.(Type_Info_Struct)
return ok && !s.is_raw_union
return ok && .raw_union not_in s.flags
}
@(require_results)
is_raw_union :: proc(info: ^Type_Info) -> bool {
if info == nil { return false }
s, ok := type_info_base(info).variant.(Type_Info_Struct)
return ok && s.is_raw_union
return ok && .raw_union in s.flags
}
@(require_results)
is_union :: proc(info: ^Type_Info) -> bool {
@@ -656,15 +654,16 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -
}
io.write_string(w, "struct ", &n) or_return
if info.is_packed { io.write_string(w, "#packed ", &n) or_return }
if info.is_raw_union { io.write_string(w, "#raw_union ", &n) or_return }
if info.custom_align {
if .packed in info.flags { io.write_string(w, "#packed ", &n) or_return }
if .raw_union in info.flags { io.write_string(w, "#raw_union ", &n) or_return }
if .no_copy in info.flags { io.write_string(w, "#no_copy ", &n) or_return }
if .align in info.flags {
io.write_string(w, "#align(", &n) or_return
io.write_i64(w, i64(ti.align), 10, &n) or_return
io.write_string(w, ") ", &n) or_return
}
io.write_byte(w, '{', &n) or_return
for name, i in info.names {
for name, i in info.names[:info.field_count] {
if i > 0 { io.write_string(w, ", ", &n) or_return }
io.write_string(w, name, &n) or_return
io.write_string(w, ": ", &n) or_return
@@ -722,7 +721,7 @@ write_type_writer :: proc(w: io.Writer, ti: ^Type_Info, n_written: ^int = nil) -
io.write_string(w, "bit_field ", &n) or_return
write_type(w, info.backing_type, &n) or_return
io.write_string(w, " {", &n) or_return
for name, i in info.names {
for name, i in info.names[:info.field_count] {
if i > 0 { io.write_string(w, ", ", &n) or_return }
io.write_string(w, name, &n) or_return
io.write_string(w, ": ", &n) or_return