зеркало из https://github.com/github/ruby.git
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
This commit is contained in:
Родитель
ea005c47fa
Коммит
5fbfc21b67
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
Sat Sep 8 18:52:22 2012 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* 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 <nobu@ruby-lang.org>
|
||||
|
||||
* ext/extmk.rb (extmake), lib/mkmf.rb (have_framework): fix splitting
|
||||
|
|
7
class.c
7
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 */
|
||||
|
|
|
@ -42,7 +42,6 @@ extern "C" {
|
|||
* the kernel.
|
||||
*/
|
||||
|
||||
#define ID_ALLOCATOR 1
|
||||
#define UNLIMITED_ARGUMENTS (-1)
|
||||
|
||||
/* array.c */
|
||||
|
|
|
@ -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
|
||||
|
|
9
object.c
9
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");
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
29
vm_method.c
29
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*
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче