mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-05 15:18:49 +00:00
Clean up code for initialize_symbols
This commit is contained in:
+17
-24
@@ -123,40 +123,34 @@ Returns:
|
|||||||
|
|
||||||
See doc.odin for an example.
|
See doc.odin for an example.
|
||||||
*/
|
*/
|
||||||
initialize_symbols :: proc(symbol_table: ^$T, library_path: string, symbol_prefix := "", handle_field_name := "__handle") -> (count: int, ok: bool) where intrinsics.type_is_struct(T) {
|
initialize_symbols :: proc(
|
||||||
|
symbol_table: ^$T, library_path: string,
|
||||||
|
symbol_prefix := "", handle_field_name := "__handle",
|
||||||
|
) -> (count: int = -1, ok: bool = false) where intrinsics.type_is_struct(T) {
|
||||||
assert(symbol_table != nil)
|
assert(symbol_table != nil)
|
||||||
handle: Library
|
|
||||||
|
|
||||||
if handle, ok = load_library(library_path); !ok {
|
handle := load_library(library_path) or_return
|
||||||
return -1, false
|
|
||||||
}
|
|
||||||
|
|
||||||
// `symbol_table` must be a struct because of the where clause, so this can't fail.
|
|
||||||
ti := runtime.type_info_base(type_info_of(T))
|
|
||||||
s, _ := ti.variant.(runtime.Type_Info_Struct)
|
|
||||||
|
|
||||||
// Buffer to concatenate the prefix + symbol name.
|
// Buffer to concatenate the prefix + symbol name.
|
||||||
prefixed_symbol_buf: [2048]u8 = ---
|
prefixed_symbol_buf: [2048]u8 = ---
|
||||||
|
|
||||||
sym_ptr: rawptr
|
count = 0
|
||||||
for field_name, i in s.names {
|
for field, i in reflect.struct_fields_zipped(T) {
|
||||||
// Calculate address of struct member
|
// Calculate address of struct member
|
||||||
field_ptr := rawptr(uintptr(rawptr(symbol_table)) + uintptr(s.offsets[i]))
|
field_ptr := rawptr(uintptr(symbol_table) + field.offset)
|
||||||
|
|
||||||
// If we've come across the struct member for the handle, store it and continue scanning for other symbols.
|
// If we've come across the struct member for the handle, store it and continue scanning for other symbols.
|
||||||
if field_name == handle_field_name {
|
if field.name == handle_field_name {
|
||||||
// We appear to be hot reloading. Unload previous incarnation of the library.
|
// We appear to be hot reloading. Unload previous incarnation of the library.
|
||||||
if old_handle := (^Library)(field_ptr)^; old_handle != nil {
|
if old_handle := (^Library)(field_ptr)^; old_handle != nil {
|
||||||
if ok = unload_library(old_handle); !ok {
|
unload_library(old_handle) or_return
|
||||||
return count, ok
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
(^Library)(field_ptr)^ = handle
|
(^Library)(field_ptr)^ = handle
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// We're not the library handle, so the field needs to be a pointer type, be it a procedure pointer or an exported global.
|
// We're not the library handle, so the field needs to be a pointer type, be it a procedure pointer or an exported global.
|
||||||
if !(reflect.is_procedure(s.types[i]) || reflect.is_pointer(s.types[i])) {
|
if !(reflect.is_procedure(field.type) || reflect.is_pointer(field.type)) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,22 +158,21 @@ initialize_symbols :: proc(symbol_table: ^$T, library_path: string, symbol_prefi
|
|||||||
prefixed_name: string
|
prefixed_name: string
|
||||||
|
|
||||||
// Do we have a symbol override tag?
|
// Do we have a symbol override tag?
|
||||||
if override, tag_ok := reflect.struct_tag_lookup(reflect.Struct_Tag(s.tags[i]), "dynlib"); tag_ok {
|
if override, tag_ok := reflect.struct_tag_lookup(reflect.Struct_Tag(field.tag), "dynlib"); tag_ok {
|
||||||
prefixed_name = string(override)
|
prefixed_name = string(override)
|
||||||
}
|
}
|
||||||
|
|
||||||
// No valid symbol override tag found, fall back to `<symbol_prefix>name`.
|
// No valid symbol override tag found, fall back to `<symbol_prefix>name`.
|
||||||
if len(prefixed_name) == 0 {
|
if len(prefixed_name) == 0 {
|
||||||
offset := copy(prefixed_symbol_buf[:], symbol_prefix)
|
offset := copy(prefixed_symbol_buf[:], symbol_prefix)
|
||||||
copy(prefixed_symbol_buf[offset:], field_name)
|
copy(prefixed_symbol_buf[offset:], field.name)
|
||||||
prefixed_name = string(prefixed_symbol_buf[:len(symbol_prefix) + len(field_name)])
|
prefixed_name = string(prefixed_symbol_buf[:len(symbol_prefix) + len(field.name)])
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign procedure (or global) pointer if found.
|
// Assign procedure (or global) pointer if found.
|
||||||
if sym_ptr, ok = symbol_address(handle, prefixed_name); ok {
|
sym_ptr := symbol_address(handle, prefixed_name) or_continue
|
||||||
(^rawptr)(field_ptr)^ = sym_ptr
|
(^rawptr)(field_ptr)^ = sym_ptr
|
||||||
count += 1
|
count += 1
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return count, count > 0
|
return count, count > 0
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user