@@ -479,6 +479,144 @@ DEF_FUNC range_obj_reversed
479479 ret
480480END_FUNC range_obj_reversed
481481
482+ ;; ============================================================================
483+ ;; range_obj_repr(PyRangeObject *self) -> PyStrObject*
484+ ;; Returns "range(start, stop)" or "range(start, stop, step)" if step != 1
485+ ;; ============================================================================
486+ extern str_from_cstr_heap
487+ extern obj_repr
488+ ROR_BUF equ 8
489+ ROR_POS equ 16
490+ ROR_FRAME equ 16
491+ DEF_FUNC range_obj_repr , ROR_FRAME
492+ push rbx
493+ push r12
494+ push r13
495+ push r14
496+
497+ mov rbx , rdi ; self (range object)
498+ mov r12 , [ rbx + PyRangeObject.start ]
499+ mov r13 , [ rbx + PyRangeObject.stop ]
500+ mov r14 , [ rbx + PyRangeObject.step ]
501+
502+ ; Allocate buffer (128 bytes is plenty for "range(i64, i64, i64)")
503+ mov edi , 128
504+ call ap_malloc
505+ mov [ rbp - ROR_BUF ], rax
506+ mov qword [ rbp - ROR_POS ], 0
507+
508+ ; Write "range("
509+ mov rdi , rax
510+ mov byte [ rdi ], 'r'
511+ mov byte [ rdi + 1 ], 'a'
512+ mov byte [ rdi + 2 ], 'n'
513+ mov byte [ rdi + 3 ], 'g'
514+ mov byte [ rdi + 4 ], 'e'
515+ mov byte [ rdi + 5 ], '('
516+ mov qword [ rbp - ROR_POS ], 6
517+
518+ ; Format start
519+ mov rdi , r12 ; start value (i64)
520+ call .ror_format_i64
521+
522+ ; Write ", "
523+ mov rdi , [ rbp - ROR_BUF ]
524+ mov rcx , [ rbp - ROR_POS ]
525+ mov byte [ rdi + rcx ], ','
526+ mov byte [ rdi + rcx + 1 ], ' '
527+ add qword [ rbp - ROR_POS ], 2
528+
529+ ; Format stop
530+ mov rdi , r13 ; stop value (i64)
531+ call .ror_format_i64
532+
533+ ; If step != 1, add ", step"
534+ cmp r14 , 1
535+ je .ror_close
536+ mov rdi , [ rbp - ROR_BUF ]
537+ mov rcx , [ rbp - ROR_POS ]
538+ mov byte [ rdi + rcx ], ','
539+ mov byte [ rdi + rcx + 1 ], ' '
540+ add qword [ rbp - ROR_POS ], 2
541+ mov rdi , r14 ; step value (i64)
542+ call .ror_format_i64
543+
544+ .ror_close:
545+ ; Write ")"
546+ mov rdi , [ rbp - ROR_BUF ]
547+ mov rcx , [ rbp - ROR_POS ]
548+ mov byte [ rdi + rcx ], ')'
549+ mov byte [ rdi + rcx + 1 ], 0 ; NUL terminate
550+ inc qword [ rbp - ROR_POS ]
551+
552+ ; Create string from buffer
553+ mov rdi , [ rbp - ROR_BUF ]
554+ call str_from_cstr_heap
555+ push rax ; save string
556+
557+ ; Free buffer
558+ mov rdi , [ rbp - ROR_BUF ]
559+ call ap_free
560+
561+ pop rax ; return string
562+ pop r14
563+ pop r13
564+ pop r12
565+ pop rbx
566+ leave
567+ ret
568+
569+ ; Helper: format i64 in rdi to buffer, appending at current position
570+ .ror_format_i64:
571+ push rbx
572+ push r12
573+ mov rbx , rdi ; value
574+ mov r12 , [ rbp - ROR_BUF ]
575+ mov rcx , [ rbp - ROR_POS ]
576+
577+ ; Handle negative
578+ test rbx , rbx
579+ jns .ror_fi_pos
580+ mov byte [ r12 + rcx ], '-'
581+ inc rcx
582+ mov [ rbp - ROR_POS ], rcx
583+ neg rbx
584+
585+ .ror_fi_pos:
586+ ; Convert to decimal digits (reversed)
587+ sub rsp , 24 ; temp digit buffer on stack
588+ mov rdi , rsp
589+ xor r8d , r8d ; digit count
590+ mov rax , rbx
591+ .ror_fi_loop:
592+ xor edx , edx
593+ mov rcx , 10
594+ div rcx ; rax = quotient, rdx = remainder
595+ add dl , '0'
596+ mov [ rdi + r8 ], dl
597+ inc r8
598+ test rax , rax
599+ jnz .ror_fi_loop
600+
601+ ; Copy reversed digits to buffer
602+ mov rcx , [ rbp - ROR_POS ]
603+ mov rdi , [ rbp - ROR_BUF ]
604+ .ror_fi_copy:
605+ dec r8
606+ movzx eax , byte [ rsp + r8 ]
607+ mov [ rdi + rcx ], al
608+ inc rcx
609+ test r8 , r8
610+ jnz .ror_fi_copy
611+
612+ add rsp , 24
613+ mov [ rbp - ROR_POS ], rcx
614+ pop r12
615+ pop rbx
616+ ret
617+
618+ END_FUNC range_obj_repr
619+
482620;; ============================================================================
483621;; init_iter_types
484622;; Patches list_type.tp_iter and tuple_type.tp_iter at startup
@@ -610,8 +748,8 @@ range_obj_type:
610748 dq range_obj_name ; tp_name
611749 dq PyRangeObject_size ; tp_basicsize
612750 dq range_obj_dealloc ; tp_dealloc
613- dq 0 ; tp_repr
614- dq 0 ; tp_str
751+ dq range_obj_repr ; tp_repr
752+ dq range_obj_repr ; tp_str
615753 dq 0 ; tp_hash
616754 dq 0 ; tp_call
617755 dq 0 ; tp_getattr
0 commit comments