@@ -819,6 +819,92 @@ TermCompareResult term_compare(term t, term other, TermCompareOpts opts, GlobalC
819819 }
820820 }
821821 }
822+ case TERM_TYPE_INDEX_FUNCTION : {
823+ if (term_is_external_fun (t ) && term_is_external_fun (other )) {
824+ const term * boxed_value = term_to_const_term_ptr (t );
825+ term module_atom = boxed_value [1 ];
826+ term function_atom = boxed_value [2 ];
827+ term arity = boxed_value [3 ];
828+
829+ const term * other_boxed_value = term_to_const_term_ptr (other );
830+ term other_module_atom = other_boxed_value [1 ];
831+ term other_function_atom = other_boxed_value [2 ];
832+ term other_arity = other_boxed_value [3 ];
833+
834+ if (temp_stack_push (& temp_stack , arity ) != TempStackOk
835+ || temp_stack_push (& temp_stack , other_arity ) != TempStackOk
836+ || temp_stack_push (& temp_stack , function_atom ) != TempStackOk
837+ || temp_stack_push (& temp_stack , other_function_atom ) != TempStackOk ) {
838+ return TermCompareMemoryAllocFail ;
839+ }
840+
841+ t = module_atom ;
842+ other = other_module_atom ;
843+ } else if (!term_is_external_fun (t ) && !term_is_external_fun (other )) {
844+ const term * boxed_value = term_to_const_term_ptr (t );
845+ Module * fun_module = (Module * ) boxed_value [1 ];
846+ term module_name_atom = module_get_name (fun_module );
847+ atom_index_t module_atom_index = term_to_atom_index (module_name_atom );
848+
849+ const term * other_boxed_value = term_to_const_term_ptr (other );
850+ Module * other_fun_module = (Module * ) other_boxed_value [1 ];
851+ term other_module_name_atom = module_get_name (other_fun_module );
852+ atom_index_t other_module_atom_index = term_to_atom_index (other_module_name_atom );
853+
854+ int module_cmp_result = atom_table_cmp_using_atom_index (
855+ global -> atom_table , module_atom_index , other_module_atom_index );
856+
857+ if (module_cmp_result != 0 ) {
858+ result = (module_cmp_result > 0 ) ? TermGreaterThan : TermLessThan ;
859+ goto unequal ;
860+ }
861+
862+ uint32_t fun_index = term_to_int32 (boxed_value [2 ]);
863+ uint32_t other_fun_index = term_to_int32 (other_boxed_value [2 ]);
864+
865+ if (fun_index != other_fun_index ) {
866+ result = (fun_index > other_fun_index ) ? TermGreaterThan : TermLessThan ;
867+ goto unequal ;
868+ }
869+
870+ uint32_t arity , old_index , old_uniq ;
871+ module_get_fun_arity_old_index_uniq (fun_module , fun_index , & arity , & old_index , & old_uniq );
872+ uint32_t other_arity , other_old_index , other_old_uniq ;
873+ module_get_fun_arity_old_index_uniq (other_fun_module , other_fun_index , & other_arity , & other_old_index , & other_old_uniq );
874+
875+ if (old_uniq != other_old_uniq ) {
876+ result = (old_uniq > other_old_uniq ) ? TermGreaterThan : TermLessThan ;
877+ goto unequal ;
878+ }
879+
880+ uint32_t num_freeze = module_get_fun_freeze (fun_module , fun_index );
881+ uint32_t other_num_freeze = module_get_fun_freeze (other_fun_module , other_fun_index );
882+
883+ if (num_freeze != other_num_freeze ) {
884+ result = (num_freeze > other_num_freeze ) ? TermGreaterThan : TermLessThan ;
885+ goto unequal ;
886+ } else if (num_freeze == 0 ) {
887+ CMP_POP_AND_CONTINUE ();
888+ } else {
889+ uint32_t freeze_base = 3 ;
890+ for (uint32_t i = num_freeze - 1 ; i >= 1 ; i -- ) {
891+ if (temp_stack_push (& temp_stack , boxed_value [i + freeze_base ]) != TempStackOk
892+ || temp_stack_push (& temp_stack , other_boxed_value [i + freeze_base ]) != TempStackOk ) {
893+ return TermCompareMemoryAllocFail ;
894+ }
895+ }
896+
897+ t = boxed_value [freeze_base ];
898+ other = other_boxed_value [freeze_base ];
899+ }
900+
901+ } else {
902+ result = term_is_external_fun (t ) ? TermGreaterThan : TermLessThan ;
903+ goto unequal ;
904+ }
905+
906+ break ;
907+ }
822908 case TERM_TYPE_INDEX_NON_EMPTY_LIST : {
823909 term t_tail = term_get_list_tail (t );
824910 term other_tail = term_get_list_tail (other );
0 commit comments