Bug #926

module_function中のsuperでSystemStackError

Added by _ wanabe about 3 years ago. Updated 10 months ago.

[ruby-dev:37587]
Status:Closed Start date:
Priority:Normal Due date:
Assignee:Koichi Sasada % 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

Revision 20981
Added by Koichi Sasada about 3 years ago

* 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.

Also available in: Atom PDF