瀏覽代碼

Add more to package reflect (as_string, as_pointer, as_raw_data, relative_pointer_to_absolute)

gingerBill 5 年之前
父節點
當前提交
626d0736f4
共有 2 個文件被更改,包括 118 次插入48 次删除
  1. 2 48
      core/fmt/fmt.odin
  2. 116 0
      core/reflect/reflect.odin

+ 2 - 48
core/fmt/fmt.odin

@@ -1877,59 +1877,13 @@ fmt_value :: proc(fi: ^Info, v: any, verb: rune) {
 		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);
-		}
+		ptr := reflect.relative_pointer_to_absolute_raw(v.data, info.base_integer.id);
 		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);
-		}
+		ptr := reflect.relative_pointer_to_absolute_raw(v.data, info.base_integer.id);
 
 		if verb == 'p' {
 			fmt_pointer(fi, ptr, 'p');

+ 116 - 0
core/reflect/reflect.odin

@@ -2,6 +2,8 @@ package reflect
 
 import "core:runtime"
 import "core:mem"
+import "intrinsics"
+_ :: intrinsics;
 
 Type_Info :: runtime.Type_Info;
 
@@ -1090,3 +1092,117 @@ as_string :: proc(a: any) -> (value: string, valid: bool) {
 
 	return;
 }
+
+relative_pointer_to_absolute :: proc(a: any) -> rawptr {
+	if a == nil { return nil; }
+	a := a;
+	ti := runtime.type_info_core(type_info_of(a.id));
+	a.id = ti.id;
+
+	#partial switch info in ti.variant {
+	case Type_Info_Relative_Pointer:
+		return relative_pointer_to_absolute_raw(a.data, info.base_integer.id);
+	}
+	return nil;
+}
+
+
+relative_pointer_to_absolute_raw :: proc(data: rawptr, base_integer_id: typeid) -> rawptr {
+	_handle :: 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^)));
+		}
+	}
+
+	ptr_any := any{data, base_integer_id};
+	ptr: rawptr;
+	switch i in &ptr_any {
+	case u8:    ptr = _handle(&i);
+	case u16:   ptr = _handle(&i);
+	case u32:   ptr = _handle(&i);
+	case u64:   ptr = _handle(&i);
+	case i8:    ptr = _handle(&i);
+	case i16:   ptr = _handle(&i);
+	case i32:   ptr = _handle(&i);
+	case i64:   ptr = _handle(&i);
+	case u16le: ptr = _handle(&i);
+	case u32le: ptr = _handle(&i);
+	case u64le: ptr = _handle(&i);
+	case i16le: ptr = _handle(&i);
+	case i32le: ptr = _handle(&i);
+	case i64le: ptr = _handle(&i);
+	case u16be: ptr = _handle(&i);
+	case u32be: ptr = _handle(&i);
+	case u64be: ptr = _handle(&i);
+	case i16be: ptr = _handle(&i);
+	case i32be: ptr = _handle(&i);
+	case i64be: ptr = _handle(&i);
+	}
+	return ptr;
+
+}
+
+
+
+as_pointer :: proc(a: any) -> (value: rawptr, valid: bool) {
+	if a == nil { return; }
+	a := a;
+	ti := runtime.type_info_core(type_info_of(a.id));
+	a.id = ti.id;
+
+	#partial switch info in ti.variant {
+	case Type_Info_Pointer:
+		valid = true;
+		value = a.data;
+
+	case Type_Info_String:
+		valid = true;
+		switch v in a {
+		case cstring: value = rawptr(v);
+		case: valid = false;
+		}
+
+	case Type_Info_Relative_Pointer:
+		valid = true;
+		value = relative_pointer_to_absolute_raw(a.data, info.base_integer.id);
+	}
+
+	return;
+}
+
+
+as_raw_data :: proc(a: any) -> (value: rawptr, valid: bool) {
+	if a == nil { return; }
+	a := a;
+	ti := runtime.type_info_core(type_info_of(a.id));
+	a.id = ti.id;
+
+	#partial switch info in ti.variant {
+	case Type_Info_String:
+		valid = true;
+		switch v in a {
+		case string:  value = raw_data(v);
+		case cstring: value = rawptr(v); // just in case
+		case: valid = false;
+		}
+
+	case Type_Info_Array:
+		valid = true;
+		value = a.data;
+
+	case Type_Info_Slice:
+		valid = true;
+		value = (^mem.Raw_Slice)(a.data).data;
+
+	case Type_Info_Dynamic_Array:
+		valid = true;
+		value = (^mem.Raw_Dynamic_Array)(a.data).data;
+	}
+
+	return;
+}