summaryrefslogtreecommitdiff
path: root/proc.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-16 03:21:10 (GMT)
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-10-16 03:21:10 (GMT)
commit6291c6ad77a0587d3d7d5461d969f1bc9bbe866d (patch)
tree70f691e52ce7e69d0cb3859f2e36bfe7961a2fe5 /proc.c
parent2fda4a5568e703192cb5eb719b99c067ab5c6db7 (diff)
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
Diffstat (limited to 'proc.c')
-rw-r--r--proc.c44
1 files changed, 25 insertions, 19 deletions
diff --git a/proc.c b/proc.c
index 8ede200..818853e 100644
--- a/proc.c
+++ b/proc.c
@@ -579,6 +579,20 @@ bind_receiver(VALUE bindval)
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)
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_proc)
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_proc)
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)
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)
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)
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,