Recursion
A.M. Kuchling
amk at mira.erols.com
Tue Jan 2 19:30:35 EST 2001
On Mon, 1 Jan 2001 16:31:42 -0500, Tim Peters <tim.one at home.com> wrote:
>> In Ruby, you can input a value as high as 763 before you get a
>> SystemStackError (stack level too deep) error.
>
>The recursion limit in Python varies across platforms; I assume that's true
>in Ruby too; in Python you can use sys.setrecursionlimit() to fiddle it (but
>if you set it "too high", you risk having the interpreter blow up due to C
>stack corruption).
The value of 763 is interesting; since it's not a magic constant that
a human would have chosen, that means Ruby must be detecting when the
stack is near overflow. This might be worth borrowing for Python, so
I decided to take a look.
Digging into ruby-1.6.1, the code that trips the error is this:
if ((++tick & 0xff) == 0) {
CHECK_INTS; /* better than nothing */
if (stack_length() > STACK_LEVEL_MAX) {
rb_raise(rb_eSysStackError, "stack level too deep");
}
}
Very similar to the corresponding bit of ceval.c. STACK_LEVEL_MAX is
either a constant or a value obtained from getrlimit().
stack_length(), then, is the last piece:
extern VALUE *rb_gc_stack_start;
static int
stack_length()
{
VALUE pos;
#ifdef sparc
return rb_gc_stack_start - &pos + 0x80;
#else
return (&pos < rb_gc_stack_start) ? rb_gc_stack_start - &pos
: &pos - rb_gc_stack_start;
#endif
}
Ignore the "#ifdef sparc" branch, and it's quite
simple. rb_gc_stack_start is determined by doing {VALUE start;
rb_gc_stack_start = &start;} during program initialization.
Is this approach worth pursuing for Python? This probably depends on
nonportable behaviour not guaranteed by ANSI C (the stack pointer is
continuously incremented/decremented, and not segmented or something
weird), but for most practical platforms these assumptions probably
hold.
--amk
More information about the Python-list
mailing list