Created
February 23, 2015 00:16
-
-
Save tenderlove/a8e30c1f764040de7536 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/insns.def b/insns.def | |
index 81aca8f..1c14bb9 100644 | |
--- a/insns.def | |
+++ b/insns.def | |
@@ -318,8 +318,15 @@ putspecialobject | |
val = rb_mRubyVMFrozenCore; | |
break; | |
case VM_SPECIAL_OBJECT_CBASE: | |
- val = vm_get_cbase(GET_ISEQ(), GET_EP()); | |
+ { | |
+ rb_control_frame_t *class_cfp = find_magic_class(th->cfp); | |
+ if (class_cfp) { | |
+ val = class_cfp->cklass; | |
+ } else { | |
+ val = vm_get_cbase(GET_ISEQ(), GET_EP()); | |
+ } | |
break; | |
+ } | |
case VM_SPECIAL_OBJECT_CONST_BASE: | |
val = vm_get_const_base(GET_ISEQ(), GET_EP()); | |
break; | |
@@ -914,6 +921,7 @@ defineclass | |
(VALUE val) | |
{ | |
VALUE klass; | |
+ rb_control_frame_t *cft; | |
rb_vm_defineclass_type_t type = VM_DEFINECLASS_TYPE(flags); | |
switch (type) { | |
@@ -994,10 +1002,12 @@ defineclass | |
COPY_CREF(class_iseq->cref_stack, vm_cref_push(th, klass, NOEX_PUBLIC, NULL)); | |
/* enter scope */ | |
- vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, | |
+ cft = 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); | |
+ cft->cklass = klass; | |
+ | |
RESTORE_REGS(); | |
NEXT_INSN(); | |
} | |
diff --git a/vm_core.h b/vm_core.h | |
index 8fd8ef4..32da076 100644 | |
--- a/vm_core.h | |
+++ b/vm_core.h | |
@@ -529,6 +529,7 @@ typedef struct rb_control_frame_struct { | |
#if VM_DEBUG_BP_CHECK | |
VALUE *bp_check; /* cfp[10] */ | |
#endif | |
+ VALUE cklass; | |
} rb_control_frame_t; | |
typedef struct rb_block_struct { | |
diff --git a/vm_insnhelper.c b/vm_insnhelper.c | |
index eb34119..b7e5794 100644 | |
--- a/vm_insnhelper.c | |
+++ b/vm_insnhelper.c | |
@@ -287,6 +287,21 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr) | |
return cref; | |
} | |
+static rb_control_frame_t * | |
+find_magic_class(rb_control_frame_t *frame) | |
+{ | |
+ rb_thread_t *th = GET_THREAD(); | |
+ rb_control_frame_t *cfp_limit; | |
+ | |
+ cfp_limit = (rb_control_frame_t *)(th->stack + th->stack_size); | |
+ while (cfp_limit > frame) { | |
+ if (frame->flag == VM_FRAME_MAGIC_CLASS) | |
+ return frame; | |
+ frame = RUBY_VM_PREVIOUS_CONTROL_FRAME(frame); | |
+ } | |
+ return 0; | |
+} | |
+ | |
static inline VALUE | |
vm_get_cbase(const rb_iseq_t *iseq, const VALUE *ep) | |
{ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment