diff --git a/ChangeLog b/ChangeLog index 0a34310070..51a7676e94 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,26 @@ +Wed Mar 11 22:27:05 2015 Koichi Sasada + + * node.h: remove NODE_IFUNC, NEW_IFUNC. + + * internal.h: use T_IMEMO for IFUNC. + + rename `struct IFUNC' to `struct vm_ifunc' and move the definition + from vm_insnhelper.h. Add imemo_ifunc. + + * gc.c (gc_mark_children): mark imemo_ifunc type T_IMEMO object. + + * compile.c: catch up these changes. + + * proc.c: ditto. + + * vm_core.h (RUBY_VM_IFUNC_P): ditto. + + * vm_eval.c (rb_iterate): ditto. + + * vm_insnhelper.c: ditto. + + * ext/objspace/objspace.c: ditto. + Wed Mar 11 21:53:43 2015 Koichi Sasada * internal.h, eval_intern.h: move CREF accessors. diff --git a/compile.c b/compile.c index e459bb90ab..13015dfbf8 100644 --- a/compile.c +++ b/compile.c @@ -520,9 +520,10 @@ rb_iseq_compile_node(VALUE self, NODE *node) } } } - else if (nd_type(node) == NODE_IFUNC) { + else if (RB_TYPE_P((VALUE)node, T_IMEMO)) { + const struct vm_ifunc *ifunc = (struct vm_ifunc *)node; /* user callback */ - (*node->nd_cfnc)(iseq, ret, node->nd_tval); + (*ifunc->func)(iseq, ret, ifunc->data); } else { switch (iseq->type) { @@ -5396,7 +5397,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) */ int is_index = iseq->is_size++; VALUE once_iseq = NEW_CHILD_ISEQVAL( - NEW_IFUNC(build_postexe_iseq, node->nd_body), + (NODE *)IFUNC_NEW(build_postexe_iseq, node->nd_body), make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); ADD_INSN2(ret, line, once, once_iseq, INT2FIX(is_index)); @@ -6314,7 +6315,7 @@ method_for_self(VALUE name, VALUE arg, rb_insn_func_t func, acc.arg = arg; acc.func = func; acc.line = caller_location(&path, &absolute_path); - return rb_iseq_new_with_opt(NEW_IFUNC(build, (VALUE)&acc), + return rb_iseq_new_with_opt((NODE *)IFUNC_NEW(build, (VALUE)&acc), rb_sym2str(name), path, absolute_path, INT2FIX(acc.line), 0, ISEQ_TYPE_METHOD, 0); } diff --git a/ext/objspace/objspace.c b/ext/objspace/objspace.c index fe07ca84f3..78715d7dae 100644 --- a/ext/objspace/objspace.c +++ b/ext/objspace/objspace.c @@ -406,7 +406,6 @@ count_nodes(int argc, VALUE *argv, VALUE os) COUNT_NODE(NODE_ALLOCA); COUNT_NODE(NODE_BMETHOD); COUNT_NODE(NODE_MEMO); - COUNT_NODE(NODE_IFUNC); COUNT_NODE(NODE_DSYM); COUNT_NODE(NODE_ATTRASGN); COUNT_NODE(NODE_PRELUDE); diff --git a/gc.c b/gc.c index ae1accd8e3..5df5eb5384 100644 --- a/gc.c +++ b/gc.c @@ -384,6 +384,7 @@ typedef struct RVALUE { rb_cref_t cref; struct vm_svar svar; struct vm_throw_data throw_data; + struct vm_ifunc ifunc; } imemo; struct { struct RBasic basic; @@ -4167,6 +4168,9 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) case imemo_throw_data: gc_mark(objspace, RANY(obj)->as.imemo.throw_data.throw_obj); return; + case imemo_ifunc: + gc_mark_maybe(objspace, (VALUE)RANY(obj)->as.imemo.ifunc.data); + return; default: rb_bug("T_IMEMO: unreachable"); } diff --git a/internal.h b/internal.h index 9069de1c83..0ac09bceeb 100644 --- a/internal.h +++ b/internal.h @@ -534,6 +534,7 @@ enum imemo_type { imemo_cref, imemo_svar, imemo_throw_data, + imemo_ifunc, imemo_mask = 0x07 }; @@ -577,6 +578,18 @@ struct vm_throw_data { #define THROW_DATA_P(err) RB_TYPE_P((err), T_IMEMO) +/* IFUNC */ + +struct vm_ifunc { + VALUE flags; + VALUE reserved; + VALUE (*func)(ANYARGS); + const void *data; + ID id; +}; + +#define IFUNC_NEW(a, b) ((struct vm_ifunc *)rb_imemo_new(imemo_ifunc, (VALUE)(a), (VALUE)(b), 0, 0)) + /* MEMO */ struct MEMO { diff --git a/node.h b/node.h index 68241b9b69..9bb29da5ff 100644 --- a/node.h +++ b/node.h @@ -220,8 +220,6 @@ enum node_type { #define NODE_BMETHOD NODE_BMETHOD NODE_MEMO, #define NODE_MEMO NODE_MEMO - NODE_IFUNC, -#define NODE_IFUNC NODE_IFUNC NODE_DSYM, #define NODE_DSYM NODE_DSYM NODE_ATTRASGN, @@ -361,7 +359,6 @@ typedef struct RNode { #define NEW_DEFN(i,a,d,p) NEW_NODE(NODE_DEFN,0,i,NEW_SCOPE(a,d)) #define NEW_DEFS(r,i,a,d) NEW_NODE(NODE_DEFS,r,i,NEW_SCOPE(a,d)) -#define NEW_IFUNC(f,c) NEW_NODE(NODE_IFUNC,f,c,0) #define NEW_SCOPE(a,b) NEW_NODE(NODE_SCOPE,local_tbl(),b,a) #define NEW_BLOCK(a) NEW_NODE(NODE_BLOCK,a,0,0) #define NEW_IF(c,t,e) NEW_NODE(NODE_IF,c,t,e) diff --git a/proc.c b/proc.c index c3ce56432a..bc1431b946 100644 --- a/proc.c +++ b/proc.c @@ -37,7 +37,7 @@ static int method_min_max_arity(VALUE, int *max); /* Proc */ -#define IS_METHOD_PROC_NODE(node) (nd_type(node) == NODE_IFUNC && (node)->nd_cfnc == bmcall) +#define IS_METHOD_PROC_ISEQ(iseq) (RB_TYPE_P((VALUE)(iseq), T_IMEMO) && ((struct vm_ifunc *)(iseq))->func == bmcall) static void proc_mark(void *ptr) @@ -850,10 +850,10 @@ rb_block_min_max_arity(rb_block_t *block, int *max) return rb_iseq_min_max_arity(iseq, max); } else { - NODE *node = (NODE *)iseq; - if (IS_METHOD_PROC_NODE(node)) { + if (IS_METHOD_PROC_ISEQ(iseq)) { + const struct vm_ifunc *ifunc = (struct vm_ifunc *)iseq; /* e.g. method(:foo).to_proc.arity */ - return method_min_max_arity(node->nd_tval, max); + return method_min_max_arity((VALUE)ifunc->data, max); } } } @@ -919,11 +919,11 @@ rb_proc_get_iseq(VALUE self, int *is_proc) iseq = proc->block.iseq; if (is_proc) *is_proc = !proc->is_lambda; if (!RUBY_VM_NORMAL_ISEQ_P(iseq)) { - NODE *node = (NODE *)iseq; + const struct vm_ifunc *ifunc = (struct vm_ifunc *)iseq; iseq = 0; - if (IS_METHOD_PROC_NODE(node)) { + if (IS_METHOD_PROC_ISEQ(ifunc)) { /* method(:foo).to_proc */ - iseq = rb_method_get_iseq(node->nd_tval); + iseq = rb_method_get_iseq((VALUE)ifunc->data); if (is_proc) *is_proc = 0; } } @@ -2465,10 +2465,10 @@ proc_binding(VALUE self) GetProcPtr(self, proc); iseq = proc->block.iseq; if (RUBY_VM_IFUNC_P(iseq)) { - if (!IS_METHOD_PROC_NODE((NODE *)iseq)) { + if (!IS_METHOD_PROC_ISEQ(iseq)) { rb_raise(rb_eArgError, "Can't create Binding from C level Proc"); } - iseq = rb_method_get_iseq(RNODE(iseq)->u2.value); + iseq = rb_method_get_iseq((VALUE)((struct vm_ifunc *)iseq)->data); } bindval = rb_binding_alloc(rb_cBinding); diff --git a/vm_core.h b/vm_core.h index 2c432ee1ad..25a5e8fbf6 100644 --- a/vm_core.h +++ b/vm_core.h @@ -910,7 +910,7 @@ rb_block_t *rb_vm_control_frame_block_ptr(const rb_control_frame_t *cfp); #define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \ (!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th))) -#define RUBY_VM_IFUNC_P(ptr) RB_TYPE_P((VALUE)(ptr), T_NODE) +#define RUBY_VM_IFUNC_P(ptr) RB_TYPE_P((VALUE)(ptr), T_IMEMO) #define RUBY_VM_NORMAL_ISEQ_P(ptr) \ ((ptr) && !RUBY_VM_IFUNC_P(ptr)) diff --git a/vm_eval.c b/vm_eval.c index 8ae70458a2..9dbb05b9ed 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -1105,7 +1105,7 @@ rb_iterate(VALUE (* it_proc) (VALUE), VALUE data1, { int state; volatile VALUE retval = Qnil; - struct IFUNC *ifunc = (struct IFUNC *)NEW_IFUNC(bl_proc, data2); + struct vm_ifunc *ifunc = IFUNC_NEW(bl_proc, data2); rb_thread_t *th = GET_THREAD(); rb_control_frame_t *volatile cfp = th->cfp; diff --git a/vm_insnhelper.c b/vm_insnhelper.c index de7d76bd65..0bede8f8ac 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -2044,7 +2044,7 @@ vm_yield_with_cfunc(rb_thread_t *th, const rb_block_t *block, int argc, const VALUE *argv, const rb_block_t *blockargptr) { - struct IFUNC *ifunc = (struct IFUNC *)block->iseq; + const struct vm_ifunc *ifunc = (struct vm_ifunc *)block->iseq; VALUE val, arg, blockarg; int lambda = block_proc_is_lambda(block->proc); diff --git a/vm_insnhelper.h b/vm_insnhelper.h index ab72b2217f..e8d9b8a88d 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -265,12 +265,4 @@ THROW_DATA_STATE(const struct vm_throw_data *obj) return (int)obj->throw_state; } -struct IFUNC { - VALUE flags; - VALUE reserved; - VALUE (*func)(ANYARGS); - void *data; - ID id; -}; - #endif /* RUBY_INSNHELPER_H */