diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-20 00:17:25 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2015-11-20 00:17:25 +0000 |
commit | c267d24ef0b4955ee5d0538707ed47d1b6278699 (patch) | |
tree | 7cc4faa9287f8400cfec82f20e1900def66a705b /vm_insnhelper.c | |
parent | 895b44dcf6d94e58f3daaf78d58453e2735ee827 (diff) |
* vm.c (rb_vm_cref_replace_with_duplicated_cref): added.
CREFs should not be shared by methods between `using'.
[Bug #11247]
* vm_insnhelper.c (vm_cref_replace_with_duplicated_cref): ditto.
* vm.c (vm_cref_dup): should copy refinements correctly.
* eval.c: use rb_vm_cref_replace_with_duplicated_cref().
* eval_intern.h: add a decl. of
rb_vm_cref_replace_with_duplicated_cref().
* vm_eval.c (eval_string_with_cref): do not need to pass
scope's CREF because VM can find out CREF from stack frames.
* test/ruby/test_refinement.rb: add a test.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52677 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm_insnhelper.c')
-rw-r--r-- | vm_insnhelper.c | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 3b89b3a695..033edea5fd 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -488,6 +488,58 @@ vm_env_cref_by_cref(const VALUE *ep) } static rb_cref_t * +cref_replace_with_duplicated_cref_each_frame(VALUE *vptr, int can_be_svar, VALUE parent) +{ + const VALUE v = *vptr; + rb_cref_t *cref, *new_cref; + + if (RB_TYPE_P(v, T_IMEMO)) { + switch (imemo_type(v)) { + case imemo_cref: + cref = (rb_cref_t *)v; + new_cref = vm_cref_dup(cref); + if (parent) { + /* this pointer is in svar */ + RB_OBJ_WRITE(parent, vptr, new_cref); + } + else { + *vptr = (VALUE)new_cref; + } + return (rb_cref_t *)new_cref; + case imemo_svar: + if (can_be_svar) { + return cref_replace_with_duplicated_cref_each_frame((VALUE *)&((struct vm_svar *)v)->cref_or_me, FALSE, v); + } + case imemo_ment: + rb_bug("cref_replace_with_duplicated_cref_each_frame: unreachable"); + default: + break; + } + } + return FALSE; +} + +static rb_cref_t * +vm_cref_replace_with_duplicated_cref(const VALUE *ep) +{ + if (vm_env_cref_by_cref(ep)) { + rb_cref_t *cref; + + while (!VM_EP_LEP_P(ep)) { + if ((cref = cref_replace_with_duplicated_cref_each_frame((VALUE *)&ep[-1], FALSE, Qfalse)) != NULL) { + return cref; + } + ep = VM_EP_PREV_EP(ep); + } + return cref_replace_with_duplicated_cref_each_frame((VALUE *)&ep[-1], TRUE, Qfalse); + } + else { + rb_bug("vm_cref_dup: unreachable"); + } +} + + +static rb_cref_t * rb_vm_get_cref(const VALUE *ep) { rb_cref_t *cref = vm_env_cref(ep); |