@@ -1024,7 +1024,93 @@ TermCompareResult term_compare(term t, term other, TermCompareOpts opts, GlobalC
10241024 break ;
10251025 }
10261026 }
1027- default :
1027+ case TERM_TYPE_INDEX_FUNCTION :
1028+ if (term_is_external_fun (t ) && term_is_external_fun (other )) {
1029+ const term * boxed_value = term_to_const_term_ptr (t );
1030+ term module_atom = boxed_value [1 ];
1031+ term function_atom = boxed_value [2 ];
1032+ term arity = boxed_value [3 ];
1033+
1034+ const term * other_boxed_value = term_to_const_term_ptr (other );
1035+ term other_module_atom = other_boxed_value [1 ];
1036+ term other_function_atom = other_boxed_value [2 ];
1037+ term other_arity = other_boxed_value [3 ];
1038+
1039+ if (temp_stack_push (& temp_stack , arity ) != TempStackOk
1040+ || temp_stack_push (& temp_stack , other_arity ) != TempStackOk
1041+ || temp_stack_push (& temp_stack , function_atom ) != TempStackOk
1042+ || temp_stack_push (& temp_stack , other_function_atom ) != TempStackOk ) {
1043+ return TermCompareMemoryAllocFail ;
1044+ }
1045+
1046+ t = module_atom ;
1047+ other = other_module_atom ;
1048+ } else if (!term_is_external_fun (t ) && !term_is_external_fun (other )) {
1049+ const term * boxed_value = term_to_const_term_ptr (t );
1050+ Module * fun_module = (Module * ) boxed_value [1 ];
1051+ term module_name_atom = module_get_name (fun_module );
1052+ atom_index_t module_atom_index = term_to_atom_index (module_name_atom );
1053+
1054+ const term * other_boxed_value = term_to_const_term_ptr (other );
1055+ Module * other_fun_module = (Module * ) other_boxed_value [1 ];
1056+ term other_module_name_atom = module_get_name (other_fun_module );
1057+ atom_index_t other_module_atom_index = term_to_atom_index (other_module_name_atom );
1058+
1059+ int module_cmp_result = atom_table_cmp_using_atom_index (
1060+ global -> atom_table , module_atom_index , other_module_atom_index );
1061+
1062+ if (module_cmp_result != 0 ) {
1063+ result = (module_cmp_result > 0 ) ? TermGreaterThan : TermLessThan ;
1064+ goto unequal ;
1065+ }
1066+
1067+ uint32_t fun_index = term_to_int32 (boxed_value [2 ]);
1068+ uint32_t other_fun_index = term_to_int32 (other_boxed_value [2 ]);
1069+
1070+ if (fun_index != other_fun_index ) {
1071+ result = (fun_index > other_fun_index ) ? TermGreaterThan : TermLessThan ;
1072+ goto unequal ;
1073+ }
1074+
1075+ uint32_t arity , old_index , old_uniq ;
1076+ module_get_fun_arity_old_index_uniq (fun_module , fun_index , & arity , & old_index , & old_uniq );
1077+ uint32_t other_arity , other_old_index , other_old_uniq ;
1078+ module_get_fun_arity_old_index_uniq (other_fun_module , other_fun_index , & other_arity , & other_old_index , & other_old_uniq );
1079+
1080+ if (old_uniq != other_old_uniq ) {
1081+ result = (old_uniq > other_old_uniq ) ? TermGreaterThan : TermLessThan ;
1082+ goto unequal ;
1083+ }
1084+
1085+ uint32_t num_freeze = module_get_fun_freeze (fun_module , fun_index );
1086+ uint32_t other_num_freeze = module_get_fun_freeze (other_fun_module , other_fun_index );
1087+
1088+ if (num_freeze != other_num_freeze ) {
1089+ result = (num_freeze > other_num_freeze ) ? TermGreaterThan : TermLessThan ;
1090+ goto unequal ;
1091+ } else if (num_freeze == 0 ) {
1092+ CMP_POP_AND_CONTINUE ();
1093+ } else {
1094+ uint32_t freeze_base = 3 ;
1095+ for (uint32_t i = num_freeze ; i >= 1 ; i -- ) {
1096+ if (temp_stack_push (& temp_stack , boxed_value [i + freeze_base ]) != TempStackOk
1097+ || temp_stack_push (& temp_stack , other_boxed_value [i + freeze_base ]) != TempStackOk ) {
1098+ return TermCompareMemoryAllocFail ;
1099+ }
1100+ }
1101+
1102+ t = boxed_value [freeze_base ];
1103+ other = other_boxed_value [freeze_base ];
1104+ }
1105+
1106+ } else {
1107+ result = term_is_external_fun (t ) ? TermGreaterThan : TermLessThan ;
1108+ goto unequal ;
1109+ }
1110+
1111+ break ;
1112+ case TERM_TYPE_INDEX_NIL : // This would mean we compare two equal terms, we check for that earlier
1113+ case TERM_TYPE_INDEX_INVALID :
10281114 UNREACHABLE ();
10291115 }
10301116 } else if ((((type_t == TERM_TYPE_INDEX_FLOAT && type_other == TERM_TYPE_INDEX_INTEGER )
0 commit comments