Skip to content

internal.h: allocator function in rb_classext_t #176

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions class.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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));
}
Expand Down Expand Up @@ -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 */
Expand Down
1 change: 0 additions & 1 deletion include/ruby/intern.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@ extern "C" {
* the kernel.
*/

#define ID_ALLOCATOR 1
#define UNLIMITED_ARGUMENTS (-1)

/* array.c */
Expand Down
1 change: 1 addition & 0 deletions internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 8 additions & 1 deletion object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1655,14 +1655,21 @@ 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");
}
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");
}
Expand Down
4 changes: 1 addition & 3 deletions vm_backtrace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}
}
Expand Down
4 changes: 0 additions & 4 deletions vm_eval.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
29 changes: 10 additions & 19 deletions vm_method.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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*
Expand Down
7 changes: 0 additions & 7 deletions vm_trace.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down