Browse Source

Fix cyclic check in `is_type_polymorphic`

gingerBill 4 years ago
parent
commit
44baf56d62
3 changed files with 19 additions and 8 deletions
  1. 1 1
      core/intrinsics/intrinsics.odin
  2. 5 6
      core/runtime/procs_windows_amd64.odin
  3. 13 1
      src/types.cpp

+ 1 - 1
core/intrinsics/intrinsics.odin

@@ -114,7 +114,7 @@ type_is_ordered_numeric :: proc($T: typeid) -> bool ---
 type_is_indexable       :: proc($T: typeid) -> bool ---
 type_is_sliceable       :: proc($T: typeid) -> bool ---
 type_is_comparable      :: proc($T: typeid) -> bool ---
-type_is_simple_compare  :: proc($T: typeid) -> bool --- // easily compared using memcmp
+type_is_simple_compare  :: proc($T: typeid) -> bool --- // easily compared using memcmp (== and !=)
 type_is_dereferenceable :: proc($T: typeid) -> bool ---
 type_is_valid_map_key   :: proc($T: typeid) -> bool ---
 

+ 5 - 6
core/runtime/procs_windows_amd64.odin

@@ -2,15 +2,14 @@ package runtime
 
 foreign import kernel32 "system:Kernel32.lib"
 
-windows_trap_array_bounds :: proc "contextless" () -> ! {
-	DWORD :: u32;
-	ULONG_PTR :: uint;
+@(private)
+foreign kernel32 {
+	RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: u32, lpArguments: ^uint) -> ! ---
+}
 
+windows_trap_array_bounds :: proc "contextless" () -> ! {
 	EXCEPTION_ARRAY_BOUNDS_EXCEEDED :: 0xC000008C;
 
-	foreign kernel32 {
-		RaiseException :: proc "stdcall" (dwExceptionCode, dwExceptionFlags, nNumberOfArguments: DWORD, lpArguments: ^ULONG_PTR) -> ! ---
-	}
 
 	RaiseException(EXCEPTION_ARRAY_BOUNDS_EXCEEDED, 0, 0, nil);
 }

+ 13 - 1
src/types.cpp

@@ -323,6 +323,7 @@ String const type_strings[] = {
 enum TypeFlag : u32 {
 	TypeFlag_Polymorphic     = 1<<1,
 	TypeFlag_PolySpecialized = 1<<2,
+	TypeFlag_InProcessOfCheckingPolymorphic = 1<<3,
 };
 
 struct Type {
@@ -1695,12 +1696,23 @@ TypeTuple *get_record_polymorphic_params(Type *t) {
 
 
 bool is_type_polymorphic(Type *t, bool or_specialized=false) {
+	if (t->flags & TypeFlag_InProcessOfCheckingPolymorphic) {
+		return false;
+	}
+
 	switch (t->kind) {
 	case Type_Generic:
 		return true;
 
 	case Type_Named:
-		return is_type_polymorphic(t->Named.base, or_specialized);
+		{
+			u32 flags = t->flags;
+			t->flags |= TypeFlag_InProcessOfCheckingPolymorphic;
+			bool ok = is_type_polymorphic(t->Named.base, or_specialized);
+			t->flags = flags;
+			return ok;
+		}
+
 	case Type_Opaque:
 		return is_type_polymorphic(t->Opaque.elem, or_specialized);
 	case Type_Pointer: