vm_args.c: symbol proc
* vm_args.c (vm_caller_setup_arg_block): store symbols instead of ifuncs. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@52138 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
2fda4a5568
commit
6291c6ad77
44
proc.c
44
proc.c
@ -579,6 +579,20 @@ bind_receiver(VALUE bindval)
|
|||||||
return env->block.self;
|
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 const char proc_without_block[] = "tried to create Proc object without a block";
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -609,13 +623,9 @@ proc_new(VALUE klass, int8_t is_lambda)
|
|||||||
procval = block->proc;
|
procval = block->proc;
|
||||||
|
|
||||||
if (procval) {
|
if (procval) {
|
||||||
if (RUBY_VM_IFUNC_P(procval)) {
|
if (SYMBOL_P(procval)) {
|
||||||
VALUE newprocval = rb_proc_alloc(klass);
|
if (klass != rb_cProc) return sym_proc_new(klass, procval);
|
||||||
rb_proc_t *proc = RTYPEDDATA_DATA(newprocval);
|
return rb_sym_to_proc(procval);
|
||||||
proc->block = *block;
|
|
||||||
proc->block.iseq = (rb_iseq_t *)procval;
|
|
||||||
proc->block.proc = newprocval;
|
|
||||||
return newprocval;
|
|
||||||
}
|
}
|
||||||
if (RBASIC(procval)->klass == klass) {
|
if (RBASIC(procval)->klass == klass) {
|
||||||
return procval;
|
return procval;
|
||||||
@ -952,6 +962,7 @@ rb_proc_get_iseq(VALUE self, int *is_proc)
|
|||||||
const rb_proc_t *proc;
|
const rb_proc_t *proc;
|
||||||
const rb_iseq_t *iseq;
|
const rb_iseq_t *iseq;
|
||||||
|
|
||||||
|
again:
|
||||||
GetProcPtr(self, proc);
|
GetProcPtr(self, proc);
|
||||||
iseq = proc->block.iseq;
|
iseq = proc->block.iseq;
|
||||||
if (is_proc) *is_proc = !proc->is_lambda;
|
if (is_proc) *is_proc = !proc->is_lambda;
|
||||||
@ -964,6 +975,10 @@ rb_proc_get_iseq(VALUE self, int *is_proc)
|
|||||||
if (is_proc) *is_proc = 0;
|
if (is_proc) *is_proc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (SYMBOL_P(iseq)) {
|
||||||
|
self = rb_sym_to_proc((VALUE)iseq);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
return iseq;
|
return iseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1070,15 +1085,7 @@ rb_sym_to_proc(VALUE sym)
|
|||||||
return aryp[index + 1];
|
return aryp[index + 1];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
rb_proc_t *ptr;
|
proc = sym_proc_new(rb_cProc, ID2SYM(id));
|
||||||
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;
|
|
||||||
aryp[index] = sym;
|
aryp[index] = sym;
|
||||||
aryp[index + 1] = proc;
|
aryp[index + 1] = proc;
|
||||||
return proc;
|
return proc;
|
||||||
@ -1120,7 +1127,6 @@ proc_to_s(VALUE self)
|
|||||||
const char *cname = rb_obj_classname(self);
|
const char *cname = rb_obj_classname(self);
|
||||||
const rb_iseq_t *iseq;
|
const rb_iseq_t *iseq;
|
||||||
const char *is_lambda;
|
const char *is_lambda;
|
||||||
const struct vm_ifunc *ifunc;
|
|
||||||
|
|
||||||
GetProcPtr(self, proc);
|
GetProcPtr(self, proc);
|
||||||
iseq = proc->block.iseq;
|
iseq = proc->block.iseq;
|
||||||
@ -1135,9 +1141,9 @@ proc_to_s(VALUE self)
|
|||||||
str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self,
|
str = rb_sprintf("#<%s:%p@%"PRIsVALUE":%d%s>", cname, (void *)self,
|
||||||
iseq->body->location.path, first_lineno, is_lambda);
|
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,
|
str = rb_sprintf("#<%s:%p(&%+"PRIsVALUE")%s>", cname, (void *)self,
|
||||||
ID2SYM((ID)ifunc->data), is_lambda);
|
(VALUE)iseq, is_lambda);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
|
str = rb_sprintf("#<%s:%p%s>", cname, (void *)proc->block.iseq,
|
||||||
|
2
vm.c
2
vm.c
@ -839,7 +839,7 @@ invoke_block_from_c_0(rb_thread_t *th, const rb_block_t *block,
|
|||||||
VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr,
|
VALUE self, int argc, const VALUE *argv, const rb_block_t *blockptr,
|
||||||
const rb_cref_t *cref, const int splattable)
|
const rb_cref_t *cref, const int splattable)
|
||||||
{
|
{
|
||||||
if (UNLIKELY(SPECIAL_CONST_P(block->iseq))) {
|
if (UNLIKELY(!RTEST(block->iseq))) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
else if (LIKELY(RUBY_VM_NORMAL_ISEQ_P(block->iseq))) {
|
else if (LIKELY(RUBY_VM_NORMAL_ISEQ_P(block->iseq))) {
|
||||||
|
10
vm_args.c
10
vm_args.c
@ -477,9 +477,8 @@ args_setup_block_parameter(rb_thread_t *th, struct rb_calling_info *calling, VAL
|
|||||||
GetProcPtr(blockval, proc);
|
GetProcPtr(blockval, proc);
|
||||||
calling->blockptr = &proc->block;
|
calling->blockptr = &proc->block;
|
||||||
}
|
}
|
||||||
else if (RUBY_VM_IFUNC_P(blockptr->proc)) {
|
else if (SYMBOL_P(blockptr->proc)) {
|
||||||
const ID mid = (ID)((struct vm_ifunc *)blockptr->proc)->data;
|
blockval = rb_sym_to_proc(blockptr->proc);
|
||||||
blockval = rb_sym_to_proc(ID2SYM(mid));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
blockval = blockptr->proc;
|
blockval = blockptr->proc;
|
||||||
@ -783,9 +782,8 @@ vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
|
|||||||
}
|
}
|
||||||
else if (SYMBOL_P(proc) && rb_method_basic_definition_p(rb_cSymbol, idTo_proc)) {
|
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);
|
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 = (rb_iseq_t *)proc;
|
||||||
calling->blockptr->iseq = blockiseq;
|
calling->blockptr->proc = proc;
|
||||||
calling->blockptr->proc = (VALUE)blockiseq;
|
|
||||||
}
|
}
|
||||||
else if (RUBY_VM_IFUNC_P(proc)) {
|
else if (RUBY_VM_IFUNC_P(proc)) {
|
||||||
calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp);
|
calling->blockptr = RUBY_VM_GET_BLOCK_PTR_IN_CFP(reg_cfp);
|
||||||
|
@ -98,6 +98,12 @@ control_frame_dump(rb_thread_t *th, rb_control_frame_t *cfp)
|
|||||||
if (RUBY_VM_IFUNC_P(cfp->iseq)) {
|
if (RUBY_VM_IFUNC_P(cfp->iseq)) {
|
||||||
iseq_name = "<ifunc>";
|
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 {
|
else {
|
||||||
pc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
pc = cfp->pc - cfp->iseq->body->iseq_encoded;
|
||||||
iseq_name = RSTRING_PTR(cfp->iseq->body->location.label);
|
iseq_name = RSTRING_PTR(cfp->iseq->body->location.label);
|
||||||
|
@ -2283,11 +2283,13 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, VALUE self,
|
|||||||
const rb_block_t *blockargptr)
|
const rb_block_t *blockargptr)
|
||||||
{
|
{
|
||||||
const struct vm_ifunc *ifunc = (struct vm_ifunc *)block->iseq;
|
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;
|
const rb_callable_method_entry_t *me = th->passed_bmethod_me;
|
||||||
th->passed_bmethod_me = NULL;
|
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);
|
arg = rb_ary_new4(argc, argv);
|
||||||
}
|
}
|
||||||
else if (argc == 0) {
|
else if (argc == 0) {
|
||||||
@ -2313,7 +2315,15 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, VALUE self,
|
|||||||
self, VM_ENVVAL_PREV_EP_PTR(block->ep), (VALUE)me,
|
self, VM_ENVVAL_PREV_EP_PTR(block->ep), (VALUE)me,
|
||||||
0, th->cfp->sp, 1, 0);
|
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++;
|
th->cfp++;
|
||||||
return val;
|
return val;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user