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;
  }
Example #2
0
  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);
  }