Skip to content

Commit b1d8302

Browse files
jgarzikclaude
andcommitted
Fix int_mul SmallInt overflow clobber + get_iterator exception loss
Two critical crash fixes: 1. int_mul: `mov rcx, rsi` clobbered ecx (right_tag) before the overflow path could use it. When SmallInt multiply overflowed (e.g. sys.maxsize * 2), the GMP conversion path used the clobbered tag, treating a SmallInt value as a heap pointer. Fix: save/restore ecx around the multiply. 2. get_iterator: when dunder_call_1 for __iter__ raised an exception (e.g. KeyboardInterrupt), get_iterator silently dropped it and fell through to __getitem__ fallback, corrupting state for subsequent operations. Fix: check current_exception after dunder_call_1 failure, propagate via eval_exception_unwind. Real CPython test_list.py: 30/52 pass (was 20, no more crashes). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 909c33a commit b1d8302

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

src/itertools.asm

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,12 @@ DEF_FUNC get_iterator
153153
test edx, edx
154154
jnz .validate_iter
155155

156+
; __iter__ returned NULL — check if exception pending (vs not found)
157+
extern current_exception
158+
mov rax, [rel current_exception]
159+
test rax, rax
160+
jnz .iter_exc_pending ; exception raised by __iter__, propagate
161+
156162
; __iter__ not found — try __getitem__ sequence protocol
157163
mov rdi, rbx
158164
jmp .try_getitem
@@ -223,6 +229,17 @@ DEF_FUNC get_iterator
223229
lea rdi, [rel exc_TypeError_type]
224230
CSTRING rsi, "object is not iterable"
225231
call raise_exception
232+
233+
.iter_exc_pending:
234+
; Exception was raised by __iter__. Propagate it via eval_exception_unwind.
235+
extern eval_exception_unwind
236+
extern eval_saved_r13
237+
extern eval_saved_r15
238+
mov [rel eval_saved_r13], r13
239+
mov [rel eval_saved_r15], r15
240+
pop rbx
241+
leave
242+
jmp eval_exception_unwind
226243
END_FUNC get_iterator
227244

228245
;; ============================================================================

src/pyo/int.asm

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1206,12 +1206,16 @@ DEF_FUNC_BARE int_mul
12061206
jne .gmp_path
12071207

12081208
mov rax, rdi
1209+
push rcx ; save right_tag (ecx) before clobber
12091210
mov rcx, rsi
12101211
imul rax, rcx
1211-
jo .gmp_path
1212+
jo .gmp_path_pop
1213+
add rsp, 8 ; discard saved right_tag
12121214
RET_TAG_SMALLINT
12131215
ret
12141216

1217+
.gmp_path_pop:
1218+
pop rcx ; restore right_tag
12151219
.gmp_path:
12161220
push rbp
12171221
mov rbp, rsp

0 commit comments

Comments
 (0)