From 5fbfc21b67f4bd68502e186024636f5bf4350f90 Mon Sep 17 00:00:00 2001 From: nobu Date: Sat, 8 Sep 2012 09:52:26 +0000 Subject: [PATCH] internal.h: allocator function in rb_classext_t * internal.h (struct rb_classext_struct): move allocator function into rb_classext_t from ordinary method table. [ruby-dev:46121] [Feature #6993] * object.c (rb_obj_alloc): call allocator function directly. * vm_method.c (rb_define_alloc_func, rb_undef_alloc_func) (rb_get_alloc_func): use allocator function in rb_classext_t. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36925 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 11 +++++++++++ class.c | 7 +++---- include/ruby/intern.h | 1 - internal.h | 1 + object.c | 9 ++++++++- vm_backtrace.c | 4 +--- vm_eval.c | 4 ---- vm_method.c | 29 ++++++++++------------------- vm_trace.c | 7 ------- 9 files changed, 34 insertions(+), 39 deletions(-) diff --git a/ChangeLog b/ChangeLog index 88edf06796..12f9927ed5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +Sat Sep 8 18:52:22 2012 Nobuyoshi Nakada + + * internal.h (struct rb_classext_struct): move allocator function into + rb_classext_t from ordinary method table. [ruby-dev:46121] + [Feature #6993] + + * object.c (rb_obj_alloc): call allocator function directly. + + * vm_method.c (rb_define_alloc_func, rb_undef_alloc_func) + (rb_get_alloc_func): use allocator function in rb_classext_t. + Fri Sep 7 01:21:51 2012 Nobuyoshi Nakada * ext/extmk.rb (extmake), lib/mkmf.rb (have_framework): fix splitting diff --git a/class.c b/class.c index 1d871fb7ee..8d9889ec3b 100644 --- a/class.c +++ b/class.c @@ -59,6 +59,7 @@ class_alloc(VALUE flags, VALUE klass) RCLASS_ORIGIN(obj) = (VALUE)obj; RCLASS_IV_INDEX_TBL(obj) = 0; RCLASS_REFINED_CLASS(obj) = Qnil; + RCLASS_EXT(obj)->allocator = 0; return (VALUE)obj; } @@ -169,6 +170,7 @@ rb_mod_init_copy(VALUE clone, VALUE orig) rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); } RCLASS_SUPER(clone) = RCLASS_SUPER(orig); + RCLASS_EXT(clone)->allocator = RCLASS_EXT(orig)->allocator; if (RCLASS_IV_TBL(orig)) { st_data_t id; @@ -236,6 +238,7 @@ rb_singleton_class_clone(VALUE obj) } RCLASS_SUPER(clone) = RCLASS_SUPER(klass); + RCLASS_EXT(clone)->allocator = RCLASS_EXT(klass)->allocator; if (RCLASS_IV_TBL(klass)) { RCLASS_IV_TBL(clone) = st_copy(RCLASS_IV_TBL(klass)); } @@ -897,10 +900,6 @@ method_entry_i(st_data_t key, st_data_t value, st_data_t data) st_table *list = (st_table *)data; long type; - if ((ID)key == ID_ALLOCATOR) { - return ST_CONTINUE; - } - if (!st_lookup(list, key, 0)) { if (UNDEFINED_METHOD_ENTRY_P(me)) { type = -1; /* none */ diff --git a/include/ruby/intern.h b/include/ruby/intern.h index 3f03d4dab7..e4b568d32e 100644 --- a/include/ruby/intern.h +++ b/include/ruby/intern.h @@ -42,7 +42,6 @@ extern "C" { * the kernel. */ -#define ID_ALLOCATOR 1 #define UNLIMITED_ARGUMENTS (-1) /* array.c */ diff --git a/internal.h b/internal.h index 57c1fc8cfa..e67273e0e8 100644 --- a/internal.h +++ b/internal.h @@ -29,6 +29,7 @@ struct rb_classext_struct { struct st_table *const_tbl; VALUE origin; VALUE refined_class; + rb_alloc_func_t allocator; }; #undef RCLASS_SUPER diff --git a/object.c b/object.c index d487fe82cc..8b6334020f 100644 --- a/object.c +++ b/object.c @@ -1655,6 +1655,7 @@ VALUE rb_obj_alloc(VALUE klass) { VALUE obj; + rb_alloc_func_t allocator; if (RCLASS_SUPER(klass) == 0 && klass != rb_cBasicObject) { rb_raise(rb_eTypeError, "can't instantiate uninitialized class"); @@ -1662,7 +1663,13 @@ rb_obj_alloc(VALUE klass) if (FL_TEST(klass, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't create instance of singleton class"); } - obj = rb_funcall(klass, ID_ALLOCATOR, 0, 0); + allocator = rb_get_alloc_func(klass); + if (!allocator) { + rb_raise(rb_eTypeError, "allocator undefined for %"PRIsVALUE, + klass); + } + + obj = (*allocator)(klass); if (rb_obj_class(obj) != rb_class_real(klass)) { rb_raise(rb_eTypeError, "wrong instance allocation"); } diff --git a/vm_backtrace.c b/vm_backtrace.c index c4fbaba33e..4e01c7b723 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -401,9 +401,7 @@ backtrace_each(rb_thread_t *th, else if (RUBYVM_CFUNC_FRAME_P(cfp)) { ID mid = cfp->me->def ? cfp->me->def->original_id : cfp->me->called_id; - if (mid != ID_ALLOCATOR) { - iter_cfunc(arg, mid); - } + iter_cfunc(arg, mid); } } } diff --git a/vm_eval.c b/vm_eval.c index 10eae1af33..897b0b0659 100644 --- a/vm_eval.c +++ b/vm_eval.c @@ -571,10 +571,6 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status) if (id == idMethodMissing) { raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING); } - else if (id == ID_ALLOCATOR) { - rb_raise(rb_eTypeError, "allocator undefined for %s", - rb_class2name(obj)); - } if (argc < 0x100) { nargv = ALLOCA_N(VALUE, argc + 1); diff --git a/vm_method.c b/vm_method.c index 6582bd1716..43b9ddb107 100644 --- a/vm_method.c +++ b/vm_method.c @@ -190,13 +190,6 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, (mid == rb_intern("initialize") || mid == rb_intern("initialize_copy"))) { noex = NOEX_PRIVATE | noex; } - else if (FL_TEST(klass, FL_SINGLETON) && - type == VM_METHOD_TYPE_CFUNC && - mid == rb_intern("allocate")) { - rb_warn("defining %s.allocate is deprecated; use rb_define_alloc_func()", - rb_class2name(rb_ivar_get(klass, attached))); - mid = ID_ALLOCATOR; - } rb_check_frozen(klass); #if NOEX_NOREDEF @@ -289,7 +282,7 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, static void method_added(VALUE klass, ID mid) { - if (mid != ID_ALLOCATOR && ruby_running) { + if (ruby_running) { CALL_METHOD_HOOK(klass, added, mid); } } @@ -355,34 +348,32 @@ rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_ return newme; } +#define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1) + void rb_define_alloc_func(VALUE klass, VALUE (*func)(VALUE)) { Check_Type(klass, T_CLASS); - rb_add_method_cfunc(rb_singleton_class(klass), ID_ALLOCATOR, - func, 0, NOEX_PRIVATE); + RCLASS_EXT(klass)->allocator = func; } void rb_undef_alloc_func(VALUE klass) { - Check_Type(klass, T_CLASS); - rb_add_method(rb_singleton_class(klass), ID_ALLOCATOR, VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF); + rb_define_alloc_func(klass, UNDEF_ALLOC_FUNC); } rb_alloc_func_t rb_get_alloc_func(VALUE klass) { - rb_method_entry_t *me; Check_Type(klass, T_CLASS); - me = rb_method_entry(CLASS_OF(klass), ID_ALLOCATOR, 0); - if (me && me->def && me->def->type == VM_METHOD_TYPE_CFUNC) { - return (rb_alloc_func_t)me->def->body.cfunc.func; - } - else { - return 0; + for (; klass; klass = RCLASS_SUPER(klass)) { + rb_alloc_func_t allocator = RCLASS_EXT(klass)->allocator; + if (allocator == UNDEF_ALLOC_FUNC) break; + if (allocator) return allocator; } + return 0; } static rb_method_entry_t* diff --git a/vm_trace.c b/vm_trace.c index 349063e1ec..90c2bd25ff 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -554,9 +554,6 @@ call_trace_func(rb_event_flag_t event, VALUE proc, VALUE self, ID id, VALUE klas rb_thread_method_id_and_class(th, &id, &klass); } - if (id == ID_ALLOCATOR) - return; - if (klass) { if (RB_TYPE_P(klass, T_ICLASS)) { klass = RBASIC(klass)->klass; @@ -778,10 +775,6 @@ tp_call_trace(VALUE tpval, rb_trace_arg_t *trace_arg) rb_thread_t *th = GET_THREAD(); int state; - if (UNLIKELY(trace_arg->id == ID_ALLOCATOR)) { - return; - } - tp->trace_arg = trace_arg; TH_PUSH_TAG(th);