Bug #926
module_function中のsuperでSystemStackError
| Status: | Closed | Start date: | ||
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 100% |
||
| Category: | YARV | |||
| Target version: | 1.9.1 Release Candidate | |||
| ruby -v: |
Description
ワナベと申します。
以下のスクリプトでSystemStackErrorになります。
$ ./ruby -ve '
module Foo
def foo
super
end
module_function :foo
end
Foo.foo
'
ruby 1.9.1 (2008-12-24 patchlevel-5000 trunk 20971) [i386-mingw32]
-e:4:in `foo': stack level too deep (SystemStackError)
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
... 8720 levels...
from -e:4:in `foo'
from -e:4:in `foo'
from -e:4:in `foo'
from -e:8:in `<main>'
vm_search_normal_superclass() がスーパークラスを見つけられなかったときに
渡された元クラスをそのまま返しているのが原因のように思います。
この場合の適切なスーパークラスを決める方法がわからなかったので、
0を返すようにしてパッチを書いてみました。
副作用で [Bug #730] も SystemStackError にならなくなるようです。
Index: insns.def
===================================================================
--- insns.def (revision 20971)
+++ insns.def (working copy)
@@ -1015,13 +1015,15 @@
rb_block_t *blockptr = !(op_flag & VM_CALL_ARGS_BLOCKARG_BIT) ?
GET_BLOCK_PTR() : 0;
int num = caller_setup_args(th, GET_CFP(), op_flag, op_argc,
blockiseq, &blockptr);
VALUE recv, klass;
- NODE *mn;
+ NODE *mn = 0;
ID id;
const VALUE flag = VM_CALL_SUPER_BIT | VM_CALL_FCALL_BIT;
recv = GET_SELF();
vm_search_superclass(GET_CFP(), GET_ISEQ(), recv, TOPN(num), &id, &klass);
- mn = rb_method_node(klass, id);
+ if (klass) {
+ mn = rb_method_node(klass, id);
+ }
CALL_METHOD(num, blockptr, flag, id, mn, recv);
}
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c (revision 20971)
+++ vm_insnhelper.c (working copy)
@@ -1179,6 +1179,9 @@
}
k = RCLASS_SUPER(k);
}
+ if (!k) {
+ klass = 0;
+ }
}
return klass;
}
--
ワナベ
Associated revisions
* vm_insnhelper.c (vm_method_search): return rb_cObject if there is no
super class. [ruby-dev:37587]
* bootstraptest/test_method.rb: add tests for above.
History
Updated by Yuki Sonoda about 3 years ago
- Category set to YARV
- Assignee set to Koichi Sasada
- Priority changed from Low to Normal
- Target version set to 1.9.1 Release Candidate
Updated by Koichi Sasada about 3 years ago
ささだです.
見つからない場合は Object を見に行くようなので,rb_cObject を返すよう
にしてみました.
Index: vm_insnhelper.c
===================================================================
--- vm_insnhelper.c (リビジョン 20980)
+++ vm_insnhelper.c (作業コピー)
@@ -1172,20 +1172,24 @@ vm_method_search(VALUE id, VALUE klass,
static inline VALUE
vm_search_normal_superclass(VALUE klass, VALUE recv)
{
+ VALUE sk = 0;
+
if (BUILTIN_TYPE(klass) == T_CLASS) {
- klass = RCLASS_SUPER(klass);
+ sk = RCLASS_SUPER(klass);
}
else if (BUILTIN_TYPE(klass) == T_MODULE) {
VALUE k = CLASS_OF(recv);
while (k) {
if (BUILTIN_TYPE(k) == T_ICLASS && RBASIC(k)->klass == klass) {
- klass = RCLASS_SUPER(k);
+ sk = RCLASS_SUPER(k);
break;
}
k = RCLASS_SUPER(k);
}
+ sk = rb_cObject;
}
- return klass;
+
+ return sk;
}
static void
--
// SASADA Koichi at atdot dot net
Updated by Koichi Sasada about 3 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
Applied in changeset r20981.