summaryrefslogtreecommitdiff
path: root/vm.c
diff options
context:
space:
mode:
Diffstat (limited to 'vm.c')
-rw-r--r--vm.c27
1 files changed, 15 insertions, 12 deletions
diff --git a/vm.c b/vm.c
index 19f5ce95f0..ad687d579a 100644
--- a/vm.c
+++ b/vm.c
@@ -223,7 +223,7 @@ vm_passed_block_handler(rb_execution_context_t *ec)
}
static rb_cref_t *
-vm_cref_new0(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int use_prev_prev)
+vm_cref_new0(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int use_prev_prev, int singleton)
{
VALUE refinements = Qnil;
int omod_shared = FALSE;
@@ -248,24 +248,27 @@ vm_cref_new0(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_
}
}
+ VM_ASSERT(singleton || klass);
+
cref = (rb_cref_t *)rb_imemo_new(imemo_cref, klass, (VALUE)(use_prev_prev ? CREF_NEXT(prev_cref) : prev_cref), scope_visi.value, refinements);
if (pushed_by_eval) CREF_PUSHED_BY_EVAL_SET(cref);
if (omod_shared) CREF_OMOD_SHARED_SET(cref);
+ if (singleton) CREF_SINGLETON_SET(cref);
return cref;
}
static rb_cref_t *
-vm_cref_new(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
+vm_cref_new(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval, int singleton)
{
- return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, FALSE);
+ return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, FALSE, singleton);
}
static rb_cref_t *
vm_cref_new_use_prev(VALUE klass, rb_method_visibility_t visi, int module_func, rb_cref_t *prev_cref, int pushed_by_eval)
{
- return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, TRUE);
+ return vm_cref_new0(klass, visi, module_func, prev_cref, pushed_by_eval, TRUE, FALSE);
}
static int
@@ -277,18 +280,18 @@ ref_delete_symkey(VALUE key, VALUE value, VALUE unused)
static rb_cref_t *
vm_cref_dup(const rb_cref_t *cref)
{
- VALUE klass = CREF_CLASS(cref);
const rb_scope_visibility_t *visi = CREF_SCOPE_VISI(cref);
rb_cref_t *next_cref = CREF_NEXT(cref), *new_cref;
int pushed_by_eval = CREF_PUSHED_BY_EVAL(cref);
+ int singleton = CREF_SINGLETON(cref);
- new_cref = vm_cref_new(klass, visi->method_visi, visi->module_func, next_cref, pushed_by_eval);
+ new_cref = vm_cref_new(cref->klass_or_self, visi->method_visi, visi->module_func, next_cref, pushed_by_eval, singleton);
if (!NIL_P(CREF_REFINEMENTS(cref))) {
VALUE ref = rb_hash_dup(CREF_REFINEMENTS(cref));
rb_hash_foreach(ref, ref_delete_symkey, Qnil);
CREF_REFINEMENTS_SET(new_cref, ref);
- CREF_OMOD_SHARED_UNSET(new_cref);
+ CREF_OMOD_SHARED_UNSET(new_cref);
}
return new_cref;
@@ -298,12 +301,12 @@ vm_cref_dup(const rb_cref_t *cref)
rb_cref_t *
rb_vm_cref_dup_without_refinements(const rb_cref_t *cref)
{
- VALUE klass = CREF_CLASS(cref);
const rb_scope_visibility_t *visi = CREF_SCOPE_VISI(cref);
rb_cref_t *next_cref = CREF_NEXT(cref), *new_cref;
int pushed_by_eval = CREF_PUSHED_BY_EVAL(cref);
+ int singleton = CREF_SINGLETON(cref);
- new_cref = vm_cref_new(klass, visi->method_visi, visi->module_func, next_cref, pushed_by_eval);
+ new_cref = vm_cref_new(cref->klass_or_self, visi->method_visi, visi->module_func, next_cref, pushed_by_eval, singleton);
if (!NIL_P(CREF_REFINEMENTS(cref))) {
CREF_REFINEMENTS_SET(new_cref, Qnil);
@@ -316,11 +319,11 @@ rb_vm_cref_dup_without_refinements(const rb_cref_t *cref)
static rb_cref_t *
vm_cref_new_toplevel(rb_execution_context_t *ec)
{
- rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE /* toplevel visibility is private */, FALSE, NULL, FALSE);
+ rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE /* toplevel visibility is private */, FALSE, NULL, FALSE, FALSE);
VALUE top_wrapper = rb_ec_thread_ptr(ec)->top_wrapper;
if (top_wrapper) {
- cref = vm_cref_new(top_wrapper, METHOD_VISI_PRIVATE, FALSE, cref, FALSE);
+ cref = vm_cref_new(top_wrapper, METHOD_VISI_PRIVATE, FALSE, cref, FALSE, FALSE);
}
return cref;
@@ -3742,7 +3745,7 @@ Init_VM(void)
th->ec->cfp->self = th->top_self;
VM_ENV_FLAGS_UNSET(th->ec->cfp->ep, VM_FRAME_FLAG_CFRAME);
- VM_STACK_ENV_WRITE(th->ec->cfp->ep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, FALSE, NULL, FALSE));
+ VM_STACK_ENV_WRITE(th->ec->cfp->ep, VM_ENV_DATA_INDEX_ME_CREF, (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, FALSE, NULL, FALSE, FALSE));
/*
* The Binding of the top level scope