зеркало из https://github.com/github/ruby.git
* 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). git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42649 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
9438bc0c86
Коммит
7e5d63f483
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
Thu Aug 22 15:42:43 2013 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* 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@fsij.org>
|
||||
|
||||
* process.c (rb_clock_gettime): Change emulation symbols for
|
||||
|
|
27
compile.c
27
compile.c
|
@ -510,6 +510,10 @@ rb_iseq_compile_node(VALUE self, NODE *node)
|
|||
}
|
||||
}
|
||||
}
|
||||
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 *args, NODE *argn, VALUE *flag)
|
|||
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_ANCHOR *ret, NODE * node, int poped)
|
|||
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_ANCHOR *ret, NODE * node, int poped)
|
|||
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);
|
||||
|
|
18
vm.c
18
vm.c
|
@ -2128,21 +2128,9 @@ m_core_undef_method(VALUE self, VALUE cbase, VALUE sym)
|
|||
}
|
||||
|
||||
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)
|
|||
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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче