[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]