@@ -763,6 +763,7 @@ static PyObject* insertion_sort_llvm(PyObject* self, PyObject* args, PyObject* k
763763 if (PyObject_HasAttrString (arr_obj, " _data" )) {
764764 buffer_obj = PyObject_GetAttrString (arr_obj, " _data" );
765765 is_dynamic = true ;
766+ if (!buffer_obj) return NULL ;
766767 } else {
767768 Py_INCREF (buffer_obj);
768769 }
@@ -783,7 +784,6 @@ static PyObject* insertion_sort_llvm(PyObject* self, PyObject* args, PyObject* k
783784 PyLong_Check (first) ? " int32" :
784785 PyFloat_Check (first) ? " float64" : NULL
785786 );
786-
787787 Py_DECREF (first);
788788
789789 if (!inferred_dtype) {
@@ -792,139 +792,125 @@ static PyObject* insertion_sort_llvm(PyObject* self, PyObject* args, PyObject* k
792792 return NULL ;
793793 }
794794
795+ // Import llvm_algorithms module and get function pointer
795796 PyObject* sys = PyImport_ImportModule (" sys" );
797+ if (!sys) { Py_DECREF (buffer_obj); return NULL ; }
796798 PyObject* sys_path = PyObject_GetAttrString (sys, " path" );
797799 Py_DECREF (sys);
800+ if (!sys_path) { Py_DECREF (buffer_obj); return NULL ; }
798801
799- Py_ssize_t original_len = PyList_Size (sys_path);
800- if (original_len == -1 ) {
801- Py_DECREF (sys_path);
802- return NULL ;
803- }
802+ Py_ssize_t orig_len = PyList_Size (sys_path);
803+ if (orig_len == -1 ) { Py_DECREF (sys_path); Py_DECREF (buffer_obj); return NULL ; }
804804
805805 PyObject* path = PyUnicode_FromString (" pydatastructs/linear_data_structures/_backend/cpp/algorithms" );
806- if (!path) {
807- Py_DECREF (sys_path);
808- return NULL ;
809- }
810-
811- int append_result = PyList_Append (sys_path, path);
806+ if (!path) { Py_DECREF (sys_path); Py_DECREF (buffer_obj); return NULL ; }
807+ PyList_Append (sys_path, path);
812808 Py_DECREF (path);
813- if (append_result != 0 ) {
814- Py_DECREF (sys_path);
815- return NULL ;
816- }
817809
818810 PyObject* mod = PyImport_ImportModule (" llvm_algorithms" );
819-
820- if (PyList_SetSlice (sys_path, original_len, original_len + 1 , NULL ) != 0 ) {
821- PyErr_Clear ();
822- }
811+ if (!mod) { Py_DECREF (sys_path); Py_DECREF (buffer_obj); return NULL ; }
812+ PyList_SetSlice (sys_path, orig_len, orig_len+1 , NULL ); // cleanup
823813 Py_DECREF (sys_path);
824814
825815 PyObject* fn = PyObject_GetAttrString (mod, " get_insertion_sort_ptr" );
826816 Py_DECREF (mod);
817+ if (!fn) { Py_DECREF (buffer_obj); return NULL ; }
827818
828819 PyObject* arg = PyUnicode_FromString (inferred_dtype);
829- if (!arg) {
830- Py_DECREF (fn);
831- return NULL ;
832- }
820+ if (!arg) { Py_DECREF (fn); Py_DECREF (buffer_obj); return NULL ; }
833821
834822 PyObject* addr_obj = PyObject_CallFunctionObjArgs (fn, arg, NULL );
835823 Py_DECREF (fn);
836824 Py_DECREF (arg);
837- if (!addr_obj) {
838- Py_DECREF (buffer_obj);
839- return NULL ;
840- }
825+ if (!addr_obj) { Py_DECREF (buffer_obj); return NULL ; }
841826
842827 long long addr = PyLong_AsLongLong (addr_obj);
843828 Py_DECREF (addr_obj);
844-
845- if (PyErr_Occurred ()) {
846- Py_DECREF (buffer_obj);
847- return NULL ;
848- }
849-
850- if (strcmp (inferred_dtype, " int32" ) == 0 ) {
851- typedef void (*fn_t )(int *, int );
852- fn_t insertion_sort_fn = (fn_t )(intptr_t )addr;
853- int * arr = (int *)malloc (sizeof (int ) * arr_len);
854- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
855- PyObject* item = PySequence_GetItem (buffer_obj, i);
856- arr[i] = (int )PyLong_AsLong (item);
857- Py_DECREF (item);
858- }
859- insertion_sort_fn (arr, (int )arr_len);
860- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
861- PyObject* v = PyLong_FromLong (arr[i]);
862- PySequence_SetItem (buffer_obj, i, v);
863- Py_DECREF (v);
864- }
865- free (arr);
866- } else if (strcmp (inferred_dtype, " int64" ) == 0 ) {
867- typedef void (*fn_t )(long long *, int );
868- fn_t insertion_sort_fn = (fn_t )(intptr_t )addr;
869- long long * arr = (long long *)malloc (sizeof (long long ) * arr_len);
870- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
871- PyObject* item = PySequence_GetItem (buffer_obj, i);
872- arr[i] = PyLong_AsLongLong (item);
873- Py_DECREF (item);
874- }
875- insertion_sort_fn (arr, (int )arr_len);
876- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
877- PyObject* v = PyLong_FromLongLong (arr[i]);
878- PySequence_SetItem (buffer_obj, i, v);
879- Py_DECREF (v);
880- }
881- free (arr);
882- } else if (strcmp (inferred_dtype, " float32" ) == 0 ) {
883- typedef void (*fn_t )(float *, int );
884- fn_t insertion_sort_fn = (fn_t )(intptr_t )addr;
885- float * arr = (float *)malloc (sizeof (float ) * arr_len);
886- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
887- PyObject* item = PySequence_GetItem (buffer_obj, i);
829+ if (PyErr_Occurred ()) { Py_DECREF (buffer_obj); return NULL ; }
830+
831+ // Helper macro for type-safe execution
832+ #define RUN_SORT (TYPE, CAST ) do { \
833+ TYPE* arr = (TYPE*)malloc (sizeof (TYPE) * arr_len); \
834+ if (!arr) { Py_DECREF (buffer_obj); PyErr_SetString (PyExc_MemoryError, " malloc failed" ); return NULL ; } \
835+ for (Py_ssize_t i=0 ;i<arr_len;i++) { \
836+ PyObject* item = PySequence_GetItem (buffer_obj, i); \
837+ if (!item) { free (arr); Py_DECREF (buffer_obj); return NULL ; } \
838+ arr[i] = (CAST)PyLong_AsLong (item); \
839+ Py_DECREF (item); \
840+ if (PyErr_Occurred ()) { free (arr); Py_DECREF (buffer_obj); return NULL ; } \
841+ } \
842+ typedef void (*fn_t )(TYPE*, int ); \
843+ fn_t sort_fn = (fn_t )(intptr_t )addr; \
844+ sort_fn (arr, (int )arr_len); \
845+ for (Py_ssize_t i=0 ;i<arr_len;i++) { \
846+ PyObject* v = PyLong_FromLong ((long )arr[i]); \
847+ if (!v) { free (arr); Py_DECREF (buffer_obj); return NULL ; } \
848+ int res = PyObject_SetItem (buffer_obj, PyLong_FromSsize_t (i), v); \
849+ Py_DECREF (v); \
850+ if (res < 0 ) { free (arr); Py_DECREF (buffer_obj); return NULL ; } \
851+ } \
852+ free (arr); \
853+ } while (0 )
854+
855+ if (strcmp (inferred_dtype," int32" )==0 ) {
856+ RUN_SORT (int ,int );
857+ } else if (strcmp (inferred_dtype," int64" )==0 ) {
858+ RUN_SORT (long long ,long long );
859+ } else if (strcmp (inferred_dtype," float32" )==0 ) {
860+ // float version
861+ float * arr = (float *)malloc (sizeof (float )*arr_len);
862+ if (!arr) { Py_DECREF (buffer_obj); PyErr_SetString (PyExc_MemoryError," malloc failed" ); return NULL ; }
863+ for (Py_ssize_t i=0 ;i<arr_len;i++){
864+ PyObject* item = PySequence_GetItem (buffer_obj,i);
865+ if (!item){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
888866 arr[i] = (float )PyFloat_AsDouble (item);
889867 Py_DECREF (item);
868+ if (PyErr_Occurred ()){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
890869 }
891- insertion_sort_fn (arr, (int )arr_len);
892- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
870+ typedef void (*fn_t )(float *,int );
871+ fn_t sort_fn = (fn_t )(intptr_t )addr;
872+ sort_fn (arr,(int )arr_len);
873+ for (Py_ssize_t i=0 ;i<arr_len;i++){
893874 PyObject* v = PyFloat_FromDouble (arr[i]);
894- PySequence_SetItem (buffer_obj, i, v);
875+ if (!v){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
876+ int res = PyObject_SetItem (buffer_obj, PyLong_FromSsize_t (i), v);
895877 Py_DECREF (v);
878+ if (res<0 ){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
896879 }
897880 free (arr);
898- } else if (strcmp (inferred_dtype, " float64" ) == 0 ) {
899- typedef void (* fn_t )( double *, int );
900- fn_t insertion_sort_fn = ( fn_t )( intptr_t )addr;
901- double * arr = ( double *) malloc ( sizeof ( double ) * arr_len);
902- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
903- PyObject* item = PySequence_GetItem (buffer_obj, i);
881+ } else if (strcmp (inferred_dtype," float64" )== 0 ) {
882+ double * arr = ( double *) malloc ( sizeof ( double )*arr_len );
883+ if (!arr){ Py_DECREF (buffer_obj); PyErr_SetString (PyExc_MemoryError, " malloc failed " ); return NULL ; }
884+ for (Py_ssize_t i= 0 ;i< arr_len;i++){
885+ PyObject* item = PySequence_GetItem (buffer_obj,i);
886+ if (! item){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
904887 arr[i] = PyFloat_AsDouble (item);
905888 Py_DECREF (item);
889+ if (PyErr_Occurred ()){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
906890 }
907- insertion_sort_fn (arr, (int )arr_len);
908- for (Py_ssize_t i = 0 ; i < arr_len; i++) {
891+ typedef void (*fn_t )(double *,int );
892+ fn_t sort_fn = (fn_t )(intptr_t )addr;
893+ sort_fn (arr,(int )arr_len);
894+ for (Py_ssize_t i=0 ;i<arr_len;i++){
909895 PyObject* v = PyFloat_FromDouble (arr[i]);
910- PySequence_SetItem (buffer_obj, i, v);
896+ if (!v){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
897+ int res = PyObject_SetItem (buffer_obj, PyLong_FromSsize_t (i), v);
911898 Py_DECREF (v);
899+ if (res<0 ){ free (arr); Py_DECREF (buffer_obj); return NULL ; }
912900 }
913901 free (arr);
914902 } else {
915903 Py_DECREF (buffer_obj);
916- PyErr_SetString (PyExc_TypeError, " Unsupported dtype for insertion_sort_llvm" );
904+ PyErr_SetString (PyExc_TypeError," Unsupported dtype for insertion_sort_llvm" );
917905 return NULL ;
918906 }
919907
920- if (is_dynamic && PyObject_HasAttrString (arr_obj, " _modify" )) {
921- PyObject* modify_fn = PyObject_GetAttrString (arr_obj, " _modify" );
922- if (modify_fn) {
923- PyObject_CallFunctionObjArgs (modify_fn, NULL );
908+ if (is_dynamic && PyObject_HasAttrString (arr_obj," _modify" )){
909+ PyObject* modify_fn = PyObject_GetAttrString (arr_obj," _modify" );
910+ if (modify_fn){
911+ PyObject_CallFunctionObjArgs (modify_fn,NULL );
924912 Py_DECREF (modify_fn);
925- } else {
926- PyErr_Clear ();
927- }
913+ } else { PyErr_Clear (); }
928914 }
929915
930916 Py_DECREF (buffer_obj);
0 commit comments