summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c33
1 files changed, 21 insertions, 12 deletions
diff --git a/eval.c b/eval.c
index de6da1d62f..88b2cf346e 100644
--- a/eval.c
+++ b/eval.c
@@ -3986,15 +3986,24 @@ static int STACK_LEVEL_MAX = 655300;
extern VALUE *rb_gc_stack_start;
static int
-stack_length()
+stack_length(p)
+ VALUE **p;
{
- VALUE pos;
+#ifdef C_ALLOCA
+ VALUE stack_end;
+ alloca(0);
+# define STACK_END (&stack_end)
+#else
+ VALUE *stack_end = alloca(1);
+# define STACK_END (stack_end)
+#endif
+ if (p) *p = STACK_END;
#ifdef sparc
- return rb_gc_stack_start - &pos + 0x80;
+ return rb_gc_stack_start - STACK_END + 0x80;
#else
- return (&pos < rb_gc_stack_start) ? rb_gc_stack_start - &pos
- : &pos - rb_gc_stack_start;
+ return (STACK_END < rb_gc_stack_start) ? rb_gc_stack_start - STACK_END
+ : STACK_END - rb_gc_stack_start;
#endif
}
@@ -4113,7 +4122,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper)
if ((++tick & 0xff) == 0) {
CHECK_INTS; /* better than nothing */
- if (stack_length() > STACK_LEVEL_MAX) {
+ if (stack_length(0) > STACK_LEVEL_MAX) {
rb_raise(rb_eSysStackError, "stack level too deep");
}
}
@@ -6111,7 +6120,7 @@ proc_arity(proc)
if (data->var == 0) return INT2FIX(-1);
switch (nd_type(data->var)) {
default:
- return INT2FIX(-2);
+ return INT2FIX(-1);
case NODE_MASGN:
list = data->var->nd_head;
n = 0;
@@ -6736,15 +6745,15 @@ static void
rb_thread_save_context(th)
rb_thread_t th;
{
- VALUE v;
+ VALUE *pos;
int len;
- len = stack_length();
+ len = stack_length(&pos);
th->stk_len = 0;
- th->stk_pos = (rb_gc_stack_start<(VALUE*)&v)?rb_gc_stack_start
- :rb_gc_stack_start - len;
- if (len > th->stk_max) {
+ th->stk_pos = (rb_gc_stack_start<pos)?rb_gc_stack_start
+ :rb_gc_stack_start - len;
+ if (len > th->stk_max) {
REALLOC_N(th->stk_ptr, VALUE, len);
th->stk_max = len;
}