ruby-changes:40057
From: nobu <ko1@a...>
Date: Fri, 16 Oct 2015 12:21:32 +0900 (JST)
Subject: [ruby-changes:40057] nobu:r52138 (trunk): vm_args.c: symbol proc
nobu 2015-10-16 12:21:10 +0900 (Fri, 16 Oct 2015) New Revision: 52138 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=52138 Log: vm_args.c: symbol proc * vm_args.c (vm_caller_setup_arg_block): store symbols instead of ifuncs. Modified files: trunk/proc.c trunk/vm.c trunk/vm_args.c trunk/vm_dump.c trunk/vm_insnhelper.c Index: proc.c =================================================================== --- proc.c (revision 52137) +++ proc.c (revision 52138) @@ -579,6 +579,20 @@ bind_receiver(VALUE bindval) https://github.com/ruby/ruby/blob/trunk/proc.c#L579 return env->block.self; } +static VALUE +sym_proc_new(VALUE klass, VALUE sym) +{ + rb_proc_t *proc; + sym_proc_t *symproc; + VALUE procval = TypedData_Make_Struct(klass, sym_proc_t, &proc_data_type, symproc); + symproc->env[0] = VM_ENVVAL_BLOCK_PTR(0); + proc = &symproc->basic; + proc->block.ep = symproc->env; + proc->block.iseq = (rb_iseq_t *)sym; + proc->block.proc = procval; + return procval; +} + static const char proc_without_block[] = "tried to create Proc object without a block"; static VALUE @@ -609,13 +623,9 @@ proc_new(VALUE klass, int8_t is_lambda) https://github.com/ruby/ruby/blob/trunk/proc.c#L623 procval = block->proc; if (procval) { - if (RUBY_VM_IFUNC_P(procval)) { - VALUE newprocval = rb_proc_alloc(klass); - rb_proc_t *proc = RTYPEDDATA_DATA(newprocval); - proc->block = *block; - proc->block.iseq = (rb_iseq_t *)procval; - proc->block.proc = newprocval; - return newprocval; + if (SYMBOL_P(procval)) { + if (klass != rb_cProc) return sym_proc_new(klass, procval); + return rb_sym_to_proc(procval); } if (RBASIC(procval)->klass == klass) { return procval; @@ -952,6 +962,7 @@ rb_proc_get_iseq(VALUE self, int *is_pro https://github.com/ruby/ruby/blob/trunk/proc.c#L962 const rb_proc_t *proc; const rb_iseq_t *iseq; + again: GetProcPtr(self, proc); iseq = proc->block.iseq; if (is_proc) *is_proc = !proc->is_lambda; @@ -964,6 +975,10 @@ rb_proc_get_iseq(VALUE self, int *is_pro https://github.com/ruby/ruby/blob/trunk/proc.c#L975 if (is_proc) *is_proc = 0; } } + else if (SYMBOL_P(iseq)) { + self = rb_sym_to_proc((VALUE)iseq); + goto again; + } return iseq; } @@ -1070,15 +1085,7 @@ rb_sym_to_proc(VALUE sym) https://github.com/ruby/ruby/blob/trunk/proc.c#L1085 return aryp[index + 1]; } else { - rb_proc_t *ptr; - sym_proc_t *symproc; - VALUE ifunc = (VALUE)IFUNC_NEW(rb_sym_proc_call, (VALUE)id, 0); - proc = TypedData_Make_Struct(rb_cProc, sym_proc_t, &proc_data_type, symproc); - symproc->env[0] = VM_ENVVAL_BLOCK_PTR(0); - ptr = &symproc->basic; - ptr->block.ep = symproc->env; - ptr->block.iseq = (rb_iseq_t *)ifunc; - ptr->block.proc = ifunc; + proc = sym_proc_new(rb_cProc, ID2SYM(id)); aryp[index] = sym; aryp[index + 1] = proc; return proc; @@ -1120,7 +1127,6 @@ proc_to_s(VALUE self) https://github.com/ruby/ruby/blob/trunk/proc.c#L1127 const char *cname = rb_obj_classname(self); const rb_iseq_t *iseq; const char *is_lambda; - const struct vm_ifunc *ifunc; GetProcPtr(self, proc); iseq = proc->block.iseq; @@ -1135,9 +1141,9 @@ proc_to_s(VALUE self) https://github.com/ruby/ruby/blob/trunk/proc.c#L1141 str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self, iseq->body->location.path, first_lineno, is_lambda); } - else if ((ifunc = (struct vm_ifunc *)iseq)->func == rb_sym_proc_call) { + else if (SYMBOL_P(iseq)) { str = rb_sprintf("#<%s:%p(&%+"PRIsVALUE")%s>", cname, (void *)self, - ID2SYM((ID)ifunc->data), is_lambda); + (VALUE)iseq, is_lambda); } else { str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq, Index: vm.c =================================================================== --- vm.c (revision 52137) +++ vm.c (revision 52138) @@ -839,7 +839,7 @@ invoke_block_from_c_0(rb_thread_t *th, c https://github.com/ruby/ruby/blob/trunk/vm.c#L839 VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr, const rb_cref_t *cref, const int splattable) { - if (UNLIKELY(SPECIAL_CONST_P(block->iseq))) { + if (UNLIKELY(!RTEST(block->iseq))) { return Qnil; } else if (LIKELY(RUBY_VM_NORMAL_ISEQ_P(block->iseq))) { Index: vm_dump.c =================================================================== --- vm_dump.c (revision 52137) +++ vm_dump.c (revision 52138) @@ -98,6 +98,12 @@ control_frame_dump(rb_thread_t *th, rb_c https://github.com/ruby/ruby/blob/trunk/vm_dump.c#L98 if (RUBY_VM_IFUNC_P(cfp->iseq)) { iseq_name = "<ifunc>"; } + else if (SYMBOL_P(cfp->iseq)) { + tmp = rb_sym2str((VALUE)cfp->iseq); + iseq_name = RSTRING_PTR(tmp); + snprintf(posbuf, MAX_POSBUF, ":%s", iseq_name); + line = -1; + } else { pc = cfp->pc - cfp->iseq->body->iseq_encoded; iseq_name = RSTRING_PTR(cfp->iseq->body->location.label); Index: vm_insnhelper.c =================================================================== --- vm_insnhelper.c (revision 52137) +++ vm_insnhelper.c (revision 52138) @@ -2283,11 +2283,13 @@ vm_yield_with_cfunc(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2283 const rb_block_t *blockargptr) { const struct vm_ifunc *ifunc = (struct vm_ifunc *)block->iseq; - VALUE val, arg, blockarg; + VALUE val, arg, blockarg, data; + rb_block_call_func *func; const rb_callable_method_entry_t *me = th->passed_bmethod_me; th->passed_bmethod_me = NULL; - if (!RUBY_VM_IFUNC_P(block->proc) && block_proc_is_lambda(block->proc)) { + if (!RUBY_VM_IFUNC_P(block->proc) && !SYMBOL_P(block->proc) && + block_proc_is_lambda(block->proc)) { arg = rb_ary_new4(argc, argv); } else if (argc == 0) { @@ -2313,7 +2315,15 @@ vm_yield_with_cfunc(rb_thread_t *th, con https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.c#L2315 self, VM_ENVVAL_PREV_EP_PTR(block->ep), (VALUE)me, 0, th->cfp->sp, 1, 0); - val = (*ifunc->func) (arg, ifunc->data, argc, argv, blockarg); + if (SYMBOL_P(ifunc)) { + func = rb_sym_proc_call; + data = SYM2ID((VALUE)ifunc); + } + else { + func = ifunc->func; + data = (VALUE)ifunc->data; + } + val = (*func)(arg, data, argc, argv, blockarg); th->cfp++; return val; Index: vm_args.c =================================================================== --- vm_args.c (revision 52137) +++ vm_args.c (revision 52138) @@ -477,9 +477,8 @@ args_setup_block_parameter(rb_thread_t * https://github.com/ruby/ruby/blob/trunk/vm_args.c#L477 GetProcPtr(blockval, proc); calling->blockptr = &proc->block; } - else if (RUBY_VM_IFUNC_P(blockptr->proc)) { - const ID mid = (ID)((struct vm_ifunc *)blockptr->proc)->data; - blockval = rb_sym_to_proc(ID2SYM(mid)); + else if (SYMBOL_P(blockptr->proc)) { + blockval = rb_sym_to_proc(blockptr->proc); } else { blockval = blockptr->proc; @@ -783,9 +782,8 @@ vm_caller_setup_arg_block(const rb_threa https://github.com/ruby/ruby/blob/trunk/vm_args.c#L782 } else if (SYMBOL_P(proc) && rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) { calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp); - blockiseq = (rb_iseq_t *)IFUNC_NEW(rb_sym_proc_call, SYM2ID(proc), 0); - calling->blockptr->iseq = blockiseq; - calling->blockptr->proc = (VALUE)blockiseq; + calling->blockptr->iseq = (rb_iseq_t *)proc; + calling->blockptr->proc = proc; } else if (RUBY_VM_IFUNC_P(proc)) { calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/