public DynamicObject getNormalObjectSingletonClass(DynamicObject object) { CompilerAsserts.neverPartOfCompilation(); if (RubyGuards.isRubyClass(object)) { // For the direct caller return ClassNodes.getSingletonClass(object); } if (Layouts.CLASS.getIsSingleton(Layouts.BASIC_OBJECT.getMetaClass(object))) { return Layouts.BASIC_OBJECT.getMetaClass(object); } CompilerDirectives.transferToInterpreter(); final DynamicObject logicalClass = BasicObjectNodes.getLogicalClass(object); DynamicObject attached = null; if (RubyGuards.isRubyModule(object)) { attached = object; } final String name = String.format( "#<Class:#<%s:0x%x>>", Layouts.MODULE.getFields(logicalClass).getName(), BasicObjectNodes.verySlowGetObjectID(object)); final DynamicObject singletonClass = ClassNodes.createSingletonClassOfObject(getContext(), logicalClass, attached, name); propagateFrozen(object, singletonClass); Layouts.BASIC_OBJECT.setMetaClass(object, singletonClass); return singletonClass; }
public static DynamicObject createOneSingletonClass(DynamicObject rubyClass) { CompilerAsserts.neverPartOfCompilation(); if (Layouts.CLASS.getIsSingleton(Layouts.BASIC_OBJECT.getMetaClass(rubyClass))) { return Layouts.BASIC_OBJECT.getMetaClass(rubyClass); } final DynamicObject singletonSuperclass; if (getSuperClass(rubyClass) == null) { singletonSuperclass = Layouts.BASIC_OBJECT.getLogicalClass(rubyClass); } else { singletonSuperclass = createOneSingletonClass(getSuperClass(rubyClass)); } String name = String.format("#<Class:%s>", Layouts.MODULE.getFields(rubyClass).getName()); Layouts.BASIC_OBJECT.setMetaClass( rubyClass, ClassNodes.createRubyClass( Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(rubyClass)).getContext(), Layouts.BASIC_OBJECT.getLogicalClass(rubyClass), null, singletonSuperclass, name, true, rubyClass)); return Layouts.BASIC_OBJECT.getMetaClass(rubyClass); }