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

ruby-changes:30570

From: ko1 <ko1@a...>
Date: Thu, 22 Aug 2013 15:50:49 +0900 (JST)
Subject: [ruby-changes:30570] ko1:r42649 (trunk): * compile.c (rb_iseq_compile_node): accept NODE_IFUNC to support

ko1	2013-08-22 15:50:42 +0900 (Thu, 22 Aug 2013)

  New Revision: 42649

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42649

  Log:
    * compile.c (rb_iseq_compile_node): accept NODE_IFUNC to support
      custom compilation.
    * compile.c (NODE_POSTEXE): compile to
      "ONCE{ VMFrozenCore::core#set_postexe{...} }" with a new custom
      compiler `build_postexe_iseq()'.
    * vm.c (m_core_set_postexe): remove parameters (passed by a block).

  Modified files:
    trunk/ChangeLog
    trunk/compile.c
    trunk/vm.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 42648)
+++ ChangeLog	(revision 42649)
@@ -1,3 +1,14 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Thu Aug 22 15:42:43 2013  Koichi Sasada  <ko1@a...>
+
+	* compile.c (rb_iseq_compile_node): accept NODE_IFUNC to support
+	  custom compilation.
+
+	* compile.c (NODE_POSTEXE): compile to
+	  "ONCE{ VMFrozenCore::core#set_postexe{...} }" with a new custom
+	  compiler `build_postexe_iseq()'.
+
+	* vm.c (m_core_set_postexe): remove parameters (passed by a block).
+
 Thu Aug 22 06:54:15 2013  Tanaka Akira  <akr@f...>
 
 	* process.c (rb_clock_gettime): Change emulation symbols for
Index: compile.c
===================================================================
--- compile.c	(revision 42648)
+++ compile.c	(revision 42649)
@@ -510,6 +510,10 @@ rb_iseq_compile_node(VALUE self, NODE *n https://github.com/ruby/ruby/blob/trunk/compile.c#L510
 	  }
 	}
     }
+    else if (nd_type(node) == NODE_IFUNC) {
+	/* user callback */
+	(*node->nd_cfnc)(iseq, ret, node->nd_tval);
+    }
     else {
 	switch (iseq->type) {
 	  case ISEQ_TYPE_METHOD:
@@ -3154,6 +3158,16 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR https://github.com/ruby/ruby/blob/trunk/compile.c#L3158
     return argc;
 }
 
+static VALUE
+build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *body)
+{
+    int line = nd_line(body);
+    VALUE argc = INT2FIX(0);
+    VALUE block = NEW_CHILD_ISEQVAL(body, make_name_for_block(iseq->parent_iseq), ISEQ_TYPE_BLOCK, line);
+    ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
+    ADD_CALL_WITH_BLOCK(ret, line, ID2SYM(id_core_set_postexe), argc, block);
+    return Qnil;
+}
 
 /**
   compile each node
@@ -4823,7 +4837,6 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L4837
 	break;
       }
       case NODE_DREGX_ONCE:{
-	/* TODO: once? */
 	int ic_index = iseq->is_size++;
 	NODE *dregx_node = NEW_NODE(NODE_DREGX, node->u1.value, node->u2.value, node->u3.value);
 	NODE *block_node = NEW_NODE(NODE_SCOPE, 0, dregx_node, 0);
@@ -5197,13 +5210,15 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ https://github.com/ruby/ruby/blob/trunk/compile.c#L5210
 	break;
       }
       case NODE_POSTEXE:{
-	VALUE block = NEW_CHILD_ISEQVAL(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
+	/* compiled to:
+	 *   ONCE{ rb_mRubyVMFrozenCore::core#set_postexe{ ... } }
+	 */
 	int is_index = iseq->is_size++;
+	VALUE once_iseq = NEW_CHILD_ISEQVAL(
+	    NEW_IFUNC(build_postexe_iseq, node->nd_body),
+	    make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line);
 
-	ADD_INSN1(ret, line, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE));
-	ADD_INSN1(ret, line, putiseq, block);
-	ADD_INSN1(ret, line, putobject, INT2FIX(is_index));
-	ADD_SEND (ret, line, ID2SYM(id_core_set_postexe), INT2FIX(2));
+	ADD_INSN2(ret, line, once, once_iseq, INT2FIX(is_index));
 
 	if (poped) {
 	    ADD_INSN(ret, line, pop);
Index: vm.c
===================================================================
--- vm.c	(revision 42648)
+++ vm.c	(revision 42649)
@@ -2128,21 +2128,9 @@ m_core_undef_method(VALUE self, VALUE cb https://github.com/ruby/ruby/blob/trunk/vm.c#L2128
 }
 
 static VALUE
-m_core_set_postexe(VALUE self, VALUE block_iseqval, VALUE is_index_val)
+m_core_set_postexe(VALUE self)
 {
-    int is_index = FIX2INT(is_index_val);
-    rb_thread_t *th = GET_THREAD();
-    rb_iseq_t *iseq = rb_vm_get_ruby_level_next_cfp(th, th->cfp)->iseq;
-    union iseq_inline_storage_entry *is = &iseq->is_entries[is_index];
-
-    REWIND_CFP({
-	if (is->once.done != Qtrue) {
-	    rb_iseq_t *block_iseq;
-	    GetISeqPtr(block_iseqval, block_iseq);
-	    rb_set_end_proc(rb_call_end_proc, vm_make_proc_with_iseq(block_iseq));
-	    is->once.done = Qtrue;
-	}
-    });
+    rb_set_end_proc(rb_call_end_proc, rb_block_proc());
     return Qnil;
 }
 
@@ -2284,7 +2272,7 @@ Init_VM(void) https://github.com/ruby/ruby/blob/trunk/vm.c#L2272
     rb_define_method_id(klass, id_core_undef_method, m_core_undef_method, 2);
     rb_define_method_id(klass, id_core_define_method, m_core_define_method, 3);
     rb_define_method_id(klass, id_core_define_singleton_method, m_core_define_singleton_method, 3);
-    rb_define_method_id(klass, id_core_set_postexe, m_core_set_postexe, 2);
+    rb_define_method_id(klass, id_core_set_postexe, m_core_set_postexe, 0);
     rb_define_method_id(klass, id_core_hash_from_ary, m_core_hash_from_ary, 1);
     rb_define_method_id(klass, id_core_hash_merge_ary, m_core_hash_merge_ary, 2);
     rb_define_method_id(klass, id_core_hash_merge_ptr, m_core_hash_merge_ptr, -1);

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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