mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Correct reflection usage of maps
This commit is contained in:
@@ -257,21 +257,18 @@ marshal_to_writer :: proc(w: io.Writer, v: any, opt: ^Marshal_Options) -> (err:
|
|||||||
opt_write_start(w, opt, '{') or_return
|
opt_write_start(w, opt, '{') or_return
|
||||||
|
|
||||||
if m != nil {
|
if m != nil {
|
||||||
if info.generated_struct == nil {
|
if info.map_info == nil {
|
||||||
return .Unsupported_Type
|
return .Unsupported_Type
|
||||||
}
|
}
|
||||||
entries := &m.entries
|
map_cap := uintptr(runtime.map_cap(m^))
|
||||||
gs := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct)
|
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(m^, info.map_info)
|
||||||
ed := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array)
|
for bucket_index in 0..<map_cap {
|
||||||
entry_type := ed.elem.variant.(runtime.Type_Info_Struct)
|
if !runtime.map_hash_is_valid(hs[bucket_index]) {
|
||||||
entry_size := ed.elem_size
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
for i in 0..<entries.len {
|
key := rawptr(runtime.map_cell_index_dynamic(ks, &info.map_info.ks, bucket_index))
|
||||||
opt_write_iteration(w, opt, i) or_return
|
value := rawptr(runtime.map_cell_index_dynamic(vs, &info.map_info.vs, bucket_index))
|
||||||
|
|
||||||
data := uintptr(entries.data) + uintptr(i*entry_size)
|
|
||||||
key := rawptr(data + entry_type.offsets[2])
|
|
||||||
value := rawptr(data + entry_type.offsets[3])
|
|
||||||
|
|
||||||
// check for string type
|
// check for string type
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -399,12 +399,10 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
|||||||
return UNSUPPORTED_TYPE
|
return UNSUPPORTED_TYPE
|
||||||
}
|
}
|
||||||
raw_map := (^mem.Raw_Map)(v.data)
|
raw_map := (^mem.Raw_Map)(v.data)
|
||||||
if raw_map.entries.allocator.procedure == nil {
|
if raw_map.allocator.procedure == nil {
|
||||||
raw_map.entries.allocator = p.allocator
|
raw_map.allocator = p.allocator
|
||||||
}
|
}
|
||||||
|
|
||||||
header := runtime.__get_map_header_table_runtime(t)
|
|
||||||
|
|
||||||
elem_backing := bytes_make(t.value.size, t.value.align, p.allocator) or_return
|
elem_backing := bytes_make(t.value.size, t.value.align, p.allocator) or_return
|
||||||
defer delete(elem_backing, p.allocator)
|
defer delete(elem_backing, p.allocator)
|
||||||
|
|
||||||
@@ -421,7 +419,6 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
key_hash := runtime.default_hasher_string(&key, 0)
|
|
||||||
key_ptr := rawptr(&key)
|
key_ptr := rawptr(&key)
|
||||||
|
|
||||||
key_cstr: cstring
|
key_cstr: cstring
|
||||||
@@ -430,7 +427,7 @@ unmarshal_object :: proc(p: ^Parser, v: any, end_token: Token_Kind) -> (err: Unm
|
|||||||
key_ptr = &key_cstr
|
key_ptr = &key_cstr
|
||||||
}
|
}
|
||||||
|
|
||||||
set_ptr := runtime.__dynamic_map_set(raw_map, header, key_hash, key_ptr, map_backing_value.data)
|
set_ptr := runtime.__dynamic_map_set(raw_map, t.map_info, key_ptr, map_backing_value.data)
|
||||||
if set_ptr == nil {
|
if set_ptr == nil {
|
||||||
delete(key, p.allocator)
|
delete(key, p.allocator)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
package reflect
|
|
||||||
|
|
||||||
import "core:runtime"
|
|
||||||
_ :: runtime
|
|
||||||
|
|
||||||
Map_Entry_Info :: struct($Key, $Value: typeid) {
|
|
||||||
hash: uintptr,
|
|
||||||
key: Key,
|
|
||||||
value: Value,
|
|
||||||
}
|
|
||||||
|
|
||||||
map_entry_info_slice :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry_Info(K, V), err: runtime.Allocator_Error) #no_bounds_check {
|
|
||||||
m := m
|
|
||||||
rm := (^runtime.Raw_Map)(&m)
|
|
||||||
|
|
||||||
info := type_info_base(type_info_of(M)).variant.(Type_Info_Map)
|
|
||||||
if info.map_info != nil {
|
|
||||||
entries = make(type_of(entries), len(m), allocator) or_return
|
|
||||||
|
|
||||||
map_cap := uintptr(cap(m))
|
|
||||||
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(rm^, info.map_info)
|
|
||||||
entry_index := 0
|
|
||||||
for bucket_index in 0..<map_cap {
|
|
||||||
if hash := hs[bucket_index]; runtime.map_hash_is_valid(hash) {
|
|
||||||
key := runtime.map_cell_index_dynamic(ks, &info.map_info.ks, bucket_index)
|
|
||||||
value := runtime.map_cell_index_dynamic(vs, &info.map_info.vs, bucket_index)
|
|
||||||
entries[entry_index].hash = hash
|
|
||||||
entries[entry_index].key = (^K)(key)^
|
|
||||||
entries[entry_index].value = (^V)(value)^
|
|
||||||
|
|
||||||
entry_index += 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
+22
-26
@@ -6,8 +6,8 @@ import "core:runtime"
|
|||||||
_ :: intrinsics
|
_ :: intrinsics
|
||||||
_ :: runtime
|
_ :: runtime
|
||||||
|
|
||||||
map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K) {
|
map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K, err: runtime.Allocator_Error) {
|
||||||
keys = make(type_of(keys), len(m), allocator)
|
keys = make(type_of(keys), len(m), allocator) or_return
|
||||||
i := 0
|
i := 0
|
||||||
for key in m {
|
for key in m {
|
||||||
keys[i] = key
|
keys[i] = key
|
||||||
@@ -15,8 +15,8 @@ map_keys :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (keys: []K)
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (values: []V) {
|
map_values :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (values: []V, err: runtime.Allocator_Error) {
|
||||||
values = make(type_of(values), len(m), allocator)
|
values = make(type_of(values), len(m), allocator) or_return
|
||||||
i := 0
|
i := 0
|
||||||
for _, value in m {
|
for _, value in m {
|
||||||
values[i] = value
|
values[i] = value
|
||||||
@@ -37,8 +37,8 @@ Map_Entry_Info :: struct($Key, $Value: typeid) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry(K, V)) {
|
map_entries :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (entries: []Map_Entry(K, V), err: runtime.Allocator) {
|
||||||
entries = make(type_of(entries), len(m), allocator)
|
entries = make(type_of(entries), len(m), allocator) or_return
|
||||||
i := 0
|
i := 0
|
||||||
for key, value in m {
|
for key, value in m {
|
||||||
entries[i].key = key
|
entries[i].key = key
|
||||||
@@ -52,28 +52,24 @@ map_entry_infos :: proc(m: $M/map[$K]$V, allocator := context.allocator) -> (ent
|
|||||||
m := m
|
m := m
|
||||||
rm := (^runtime.Raw_Map)(&m)
|
rm := (^runtime.Raw_Map)(&m)
|
||||||
|
|
||||||
info := runtime.type_info_base(type_info_of(M)).variant.(runtime.Type_Info_Map)
|
info := type_info_base(type_info_of(M)).variant.(Type_Info_Map)
|
||||||
gs := runtime.type_info_base(info.generated_struct).variant.(runtime.Type_Info_Struct)
|
if info.map_info != nil {
|
||||||
ed := runtime.type_info_base(gs.types[1]).variant.(runtime.Type_Info_Dynamic_Array)
|
entries = make(type_of(entries), len(m), allocator) or_return
|
||||||
entry_type := ed.elem.variant.(runtime.Type_Info_Struct)
|
|
||||||
key_offset := entry_type.offsets[2]
|
|
||||||
value_offset := entry_type.offsets[3]
|
|
||||||
entry_size := uintptr(ed.elem_size)
|
|
||||||
|
|
||||||
entries = make(type_of(entries), rm.entries.len)
|
map_cap := uintptr(cap(m))
|
||||||
|
ks, vs, hs, _, _ := runtime.map_kvh_data_dynamic(rm^, info.map_info)
|
||||||
|
entry_index := 0
|
||||||
|
for bucket_index in 0..<map_cap {
|
||||||
|
if hash := hs[bucket_index]; runtime.map_hash_is_valid(hash) {
|
||||||
|
key := runtime.map_cell_index_dynamic(ks, &info.map_info.ks, bucket_index)
|
||||||
|
value := runtime.map_cell_index_dynamic(vs, &info.map_info.vs, bucket_index)
|
||||||
|
entries[entry_index].hash = hash
|
||||||
|
entries[entry_index].key = (^K)(key)^
|
||||||
|
entries[entry_index].value = (^V)(value)^
|
||||||
|
|
||||||
data := uintptr(rm.entries.data)
|
entry_index += 1
|
||||||
for i in 0..<rm.entries.len {
|
}
|
||||||
header := (^runtime.Map_Entry_Header)(data)
|
}
|
||||||
|
|
||||||
hash := header.hash
|
|
||||||
key := (^K)(data + key_offset)^
|
|
||||||
value := (^V)(data + value_offset)^
|
|
||||||
|
|
||||||
entries[i] = {hash, key, value}
|
|
||||||
|
|
||||||
data += entry_size
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user