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/