Ejemplo n.º 1
0
SingletonClass* SingletonClass::attach(STATE, Object* obj, Class* sup) {
    SingletonClass *sc;
    sc = state->memory()->new_object_enduring<SingletonClass>(state, G(klass));
    sc->init(state);

    sc->attached_instance(state, obj);
    sc->setup(state);

    if(kind_of<PackedObject>(obj)) {
        sc->set_type_info(state->memory()->type_info[Object::type]);
    } else {
        sc->set_type_info(obj->klass()->type_info());
    }

    sc->set_packed_size(obj->klass()->packed_size());
    sc->packed_ivar_info(state, obj->klass()->packed_ivar_info());

    /* The superclass hierarchy for singleton classes lives in parallel to
     * that of classes.  This code ensures that the superclasses of singleton
     * classes are also singleton classes.
     */
    if(SingletonClass* already_sc = try_as<SingletonClass>(obj)) {
        /* If we are attaching a singleton class to something that is already a
         * SingletonClass, make the singleton class's superclass be the attachee's
         * superclass.  klass and superclass are both singleton classes in this
         * case.
         */
        sc->klass(state, sc);
        Class* super = already_sc->true_superclass(state)->singleton_class_instance(state);
        sc->superclass(state, super);
        super->track_subclass(state, sc);
    } else {
        /* If we are attaching to anything but a SingletonClass, the new
         * singleton class's class is the same as its superclass.  This is where
         * the superclass chains for singleton and non-singleton classes
         * diverge.  If no superclass argument was provided, we use the klass we
         * are replacing.
         */
        if(!sup) {
            sup = obj->klass();
        }
        /* Tell the new SingletonClass about the attachee's existing hierarchy */
        Class* super_klass = Class::real_class(state, sup)->klass();
        sc->klass(state, super_klass);
        sc->superclass(state, sup);
        sup->track_subclass(state, sc);
    }

    /* Finally, attach the new SingletonClass */
    obj->klass(state, sc);

    return sc;
}
Ejemplo n.º 2
0
  SingletonClass* SingletonClass::create(STATE, Object* obj) {
    SingletonClass *sc;
    sc = state->memory()->new_object_enduring<SingletonClass>(state, G(klass));
    sc->init(state);

    WeakRef* weakref = WeakRef::create(state, obj);
    sc->object_reference(state, weakref);

    sc->setup(state);

    return sc;
  }