summaryrefslogtreecommitdiff
path: root/insns.def
diff options
context:
space:
mode:
authornagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-08-24 16:13:22 +0000
committernagachika <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-08-24 16:13:22 +0000
commitd93cfe5d9ec178cf4a460eae2220aa044b5ce99b (patch)
treea7caa1a51523ebb743e5e040c3ec8f1a7d5894bd /insns.def
parent6a13cf0052144266e78d0b78f159e04316451fa9 (diff)
* insns.def (defineclass): introduce an ad-hoc patch to avoid
an issue reported on [Bug #10871]. This patch does not fix completely. For example, method definition in a block (like 1.times{def ...; end}) still causes same issue. To solve all, we need a huge patch and it seems difficult for stable branch. Use Ruby 2.3 and later to solve this issue completely. (See [Bug #10943]) git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_2@51673 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'insns.def')
-rw-r--r--insns.def21
1 files changed, 20 insertions, 1 deletions
diff --git a/insns.def b/insns.def
index eae0b8e1d8..d0d7913ec6 100644
--- a/insns.def
+++ b/insns.def
@@ -914,6 +914,8 @@ defineclass
(VALUE val)
{
VALUE klass;
+ VALUE class_iseq_val = class_iseq->self;
+ rb_iseq_t *orig_class_iseq = NULL;
rb_vm_defineclass_type_t type = VM_DEFINECLASS_TYPE(flags);
switch (type) {
@@ -963,7 +965,18 @@ defineclass
case VM_DEFINECLASS_TYPE_SINGLETON_CLASS:
/* val is dummy. classdef returns class scope value */
/* super is dummy */
- klass = rb_singleton_class(cbase);
+ {
+ klass = rb_singleton_class(cbase);
+
+ /* Copy iseq to duplicate cref_stack place.
+ * This is ad-hoc solution for [Bug #10871].
+ * and this does not solve more complicated source code with singleton class.
+ * If you need to solve everything, use Ruby 2.3 and later.
+ */
+ orig_class_iseq = class_iseq;
+ class_iseq_val = rb_iseq_clone(class_iseq->self, cbase);
+ GetISeqPtr(class_iseq_val, class_iseq);
+ }
break;
case VM_DEFINECLASS_TYPE_MODULE:
/* val is dummy. classdef returns class scope value */
@@ -992,12 +1005,18 @@ defineclass
}
COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL));
+ if (orig_class_iseq) {
+ COPY_CREF(orig_class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL));
+ }
/* enter scope */
vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS,
klass, 0, VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()),
class_iseq->iseq_encoded, GET_SP(),
class_iseq->local_size, 0, class_iseq->stack_max);
+
+ RB_GC_GUARD(class_iseq_val);
+
RESTORE_REGS();
NEXT_INSN();
}