mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-04 14:48:47 +00:00
Relative pointers
This commit is contained in:
@@ -8,6 +8,7 @@ import "core:unicode/utf8"
|
||||
import "core:strconv"
|
||||
import "core:strings"
|
||||
import "core:reflect"
|
||||
import "intrinsics"
|
||||
|
||||
|
||||
@private
|
||||
@@ -1712,6 +1713,117 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
|
||||
|
||||
case runtime.Type_Info_Opaque:
|
||||
fmt_opaque(fi, v);
|
||||
|
||||
case runtime.Type_Info_Relative_Pointer:
|
||||
ptr_any := any{v.data, info.base_integer.id};
|
||||
ptr: rawptr;
|
||||
switch i in &ptr_any {
|
||||
case u8: ptr = handle_relative_pointer(&i);
|
||||
case u16: ptr = handle_relative_pointer(&i);
|
||||
case u32: ptr = handle_relative_pointer(&i);
|
||||
case u64: ptr = handle_relative_pointer(&i);
|
||||
case i8: ptr = handle_relative_pointer(&i);
|
||||
case i16: ptr = handle_relative_pointer(&i);
|
||||
case i32: ptr = handle_relative_pointer(&i);
|
||||
case i64: ptr = handle_relative_pointer(&i);
|
||||
case u16le: ptr = handle_relative_pointer(&i);
|
||||
case u32le: ptr = handle_relative_pointer(&i);
|
||||
case u64le: ptr = handle_relative_pointer(&i);
|
||||
case i16le: ptr = handle_relative_pointer(&i);
|
||||
case i32le: ptr = handle_relative_pointer(&i);
|
||||
case i64le: ptr = handle_relative_pointer(&i);
|
||||
case u16be: ptr = handle_relative_pointer(&i);
|
||||
case u32be: ptr = handle_relative_pointer(&i);
|
||||
case u64be: ptr = handle_relative_pointer(&i);
|
||||
case i16be: ptr = handle_relative_pointer(&i);
|
||||
case i32be: ptr = handle_relative_pointer(&i);
|
||||
case i64be: ptr = handle_relative_pointer(&i);
|
||||
}
|
||||
absolute_ptr := any{ptr, info.pointer.id};
|
||||
|
||||
fmt_value(fi, absolute_ptr, verb);
|
||||
|
||||
case runtime.Type_Info_Relative_Slice:
|
||||
ptr_any := any{v.data, info.base_integer.id};
|
||||
ptr: rawptr;
|
||||
switch i in &ptr_any {
|
||||
case u8: ptr = handle_relative_pointer(&i);
|
||||
case u16: ptr = handle_relative_pointer(&i);
|
||||
case u32: ptr = handle_relative_pointer(&i);
|
||||
case u64: ptr = handle_relative_pointer(&i);
|
||||
case i8: ptr = handle_relative_pointer(&i);
|
||||
case i16: ptr = handle_relative_pointer(&i);
|
||||
case i32: ptr = handle_relative_pointer(&i);
|
||||
case i64: ptr = handle_relative_pointer(&i);
|
||||
case u16le: ptr = handle_relative_pointer(&i);
|
||||
case u32le: ptr = handle_relative_pointer(&i);
|
||||
case u64le: ptr = handle_relative_pointer(&i);
|
||||
case i16le: ptr = handle_relative_pointer(&i);
|
||||
case i32le: ptr = handle_relative_pointer(&i);
|
||||
case i64le: ptr = handle_relative_pointer(&i);
|
||||
case u16be: ptr = handle_relative_pointer(&i);
|
||||
case u32be: ptr = handle_relative_pointer(&i);
|
||||
case u64be: ptr = handle_relative_pointer(&i);
|
||||
case i16be: ptr = handle_relative_pointer(&i);
|
||||
case i32be: ptr = handle_relative_pointer(&i);
|
||||
case i64be: ptr = handle_relative_pointer(&i);
|
||||
}
|
||||
|
||||
if verb == 'p' {
|
||||
fmt_pointer(fi, ptr, 'p');
|
||||
} else if ptr == nil {
|
||||
strings.write_string(fi.buf, "[]");
|
||||
} else {
|
||||
len_ptr := uintptr(v.data) + uintptr(info.base_integer.size);
|
||||
len_any := any{rawptr(len_ptr), info.base_integer.id};
|
||||
len: int = 0;
|
||||
switch i in len_any {
|
||||
case u8: len = int(i);
|
||||
case u16: len = int(i);
|
||||
case u32: len = int(i);
|
||||
case u64: len = int(i);
|
||||
case i8: len = int(i);
|
||||
case i16: len = int(i);
|
||||
case i32: len = int(i);
|
||||
case i64: len = int(i);
|
||||
case u16le: len = int(i);
|
||||
case u32le: len = int(i);
|
||||
case u64le: len = int(i);
|
||||
case i16le: len = int(i);
|
||||
case i32le: len = int(i);
|
||||
case i64le: len = int(i);
|
||||
case u16be: len = int(i);
|
||||
case u32be: len = int(i);
|
||||
case u64be: len = int(i);
|
||||
case i16be: len = int(i);
|
||||
case i32be: len = int(i);
|
||||
case i64be: len = int(i);
|
||||
}
|
||||
|
||||
slice_type := reflect.type_info_base(info.slice).variant.(runtime.Type_Info_Slice);
|
||||
|
||||
strings.write_byte(fi.buf, '[');
|
||||
defer strings.write_byte(fi.buf, ']');
|
||||
|
||||
for i in 0..<len {
|
||||
if i > 0 do strings.write_string(fi.buf, ", ");
|
||||
|
||||
data := uintptr(ptr) + uintptr(i*slice_type.elem_size);
|
||||
fmt_arg(fi, any{rawptr(data), slice_type.elem.id}, verb);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handle_relative_pointer :: proc(ptr: ^$T) -> rawptr where intrinsics.type_is_integer(T) {
|
||||
if ptr^ == 0 {
|
||||
return nil;
|
||||
}
|
||||
when intrinsics.type_is_unsigned(T) {
|
||||
return rawptr(uintptr(ptr) + uintptr(ptr^));
|
||||
} else {
|
||||
return rawptr(uintptr(ptr) + uintptr(i64(ptr^)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ Type_Info_Bit_Field :: runtime.Type_Info_Bit_Field;
|
||||
Type_Info_Bit_Set :: runtime.Type_Info_Bit_Set;
|
||||
Type_Info_Opaque :: runtime.Type_Info_Opaque;
|
||||
Type_Info_Simd_Vector :: runtime.Type_Info_Simd_Vector;
|
||||
Type_Info_Relative_Pointer :: runtime.Type_Info_Relative_Pointer;
|
||||
Type_Info_Relative_Slice :: runtime.Type_Info_Relative_Slice;
|
||||
|
||||
|
||||
Type_Kind :: enum {
|
||||
@@ -60,6 +62,8 @@ Type_Kind :: enum {
|
||||
Bit_Set,
|
||||
Opaque,
|
||||
Simd_Vector,
|
||||
Relative_Pointer,
|
||||
Relative_Slice,
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +96,8 @@ type_kind :: proc(T: typeid) -> Type_Kind {
|
||||
case Type_Info_Bit_Set: return .Bit_Set;
|
||||
case Type_Info_Opaque: return .Opaque;
|
||||
case Type_Info_Simd_Vector: return .Simd_Vector;
|
||||
case Type_Info_Relative_Pointer: return .Relative_Pointer;
|
||||
case Type_Info_Relative_Slice: return .Relative_Slice;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -184,6 +184,16 @@ are_types_identical :: proc(a, b: ^Type_Info) -> bool {
|
||||
y, ok := b.variant.(Type_Info_Simd_Vector);
|
||||
if !ok do return false;
|
||||
return x.count == y.count && x.elem == y.elem;
|
||||
|
||||
case Type_Info_Relative_Pointer:
|
||||
y, ok := b.variant.(Type_Info_Relative_Pointer);
|
||||
if !ok do return false;
|
||||
return x.base_integer == y.base_integer && x.pointer == y.pointer;
|
||||
|
||||
case Type_Info_Relative_Slice:
|
||||
y, ok := b.variant.(Type_Info_Relative_Slice);
|
||||
if !ok do return false;
|
||||
return x.base_integer == y.base_integer && x.slice == y.slice;
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -322,6 +332,16 @@ is_simd_vector :: proc(info: ^Type_Info) -> bool {
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Simd_Vector);
|
||||
return ok;
|
||||
}
|
||||
is_relative_pointer :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Relative_Pointer);
|
||||
return ok;
|
||||
}
|
||||
is_relative_slice :: proc(info: ^Type_Info) -> bool {
|
||||
if info == nil do return false;
|
||||
_, ok := type_info_base(info).variant.(Type_Info_Relative_Slice);
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -567,6 +587,19 @@ write_type :: proc(buf: ^strings.Builder, ti: ^Type_Info) {
|
||||
write_byte(buf, ']');
|
||||
write_type(buf, info.elem);
|
||||
}
|
||||
|
||||
case Type_Info_Relative_Pointer:
|
||||
write_string(buf, "#relative(");
|
||||
write_type(buf, info.base_integer);
|
||||
write_string(buf, ") ");
|
||||
write_type(buf, info.pointer);
|
||||
|
||||
case Type_Info_Relative_Slice:
|
||||
write_string(buf, "#relative(");
|
||||
write_type(buf, info.base_integer);
|
||||
write_string(buf, ") ");
|
||||
write_type(buf, info.slice);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-1
@@ -143,7 +143,15 @@ Type_Info_Simd_Vector :: struct {
|
||||
elem_size: int,
|
||||
count: int,
|
||||
is_x86_mmx: bool,
|
||||
}
|
||||
};
|
||||
Type_Info_Relative_Pointer :: struct {
|
||||
pointer: ^Type_Info,
|
||||
base_integer: ^Type_Info,
|
||||
};
|
||||
Type_Info_Relative_Slice :: struct {
|
||||
slice: ^Type_Info,
|
||||
base_integer: ^Type_Info,
|
||||
};
|
||||
|
||||
Type_Info :: struct {
|
||||
size: int,
|
||||
@@ -176,6 +184,8 @@ Type_Info :: struct {
|
||||
Type_Info_Bit_Set,
|
||||
Type_Info_Opaque,
|
||||
Type_Info_Simd_Vector,
|
||||
Type_Info_Relative_Pointer,
|
||||
Type_Info_Relative_Slice,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -205,6 +215,9 @@ Typeid_Kind :: enum u8 {
|
||||
Bit_Field,
|
||||
Bit_Set,
|
||||
Opaque,
|
||||
Simd_Vector,
|
||||
Relative_Pointer,
|
||||
Relative_Slice,
|
||||
}
|
||||
#assert(len(Typeid_Kind) < 32);
|
||||
|
||||
|
||||
@@ -442,6 +442,18 @@ print_type :: proc(fd: os.Handle, ti: ^Type_Info) {
|
||||
os.write_byte(fd, ']');
|
||||
print_type(fd, info.elem);
|
||||
}
|
||||
|
||||
case Type_Info_Relative_Pointer:
|
||||
os.write_string(fd, "#relative(");
|
||||
print_type(fd, info.base_integer);
|
||||
os.write_string(fd, ") ");
|
||||
print_type(fd, info.pointer);
|
||||
|
||||
case Type_Info_Relative_Slice:
|
||||
os.write_string(fd, "#relative(");
|
||||
print_type(fd, info.base_integer);
|
||||
os.write_string(fd, ") ");
|
||||
print_type(fd, info.slice);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user