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 void initialize(DynamicObject rubyClass, DynamicObject superclass) { assert RubyGuards.isRubyClass(superclass); Layouts.MODULE.getFields(rubyClass).parentModule = Layouts.MODULE.getFields(superclass).start; Layouts.MODULE.getFields(superclass).addDependent(rubyClass); Layouts.MODULE.getFields(rubyClass).newVersion(); ensureSingletonConsistency(rubyClass); DynamicObjectFactory factory = Layouts.CLASS.getInstanceFactory(superclass); factory = Layouts.BASIC_OBJECT.setLogicalClass(factory, rubyClass); factory = Layouts.BASIC_OBJECT.setMetaClass(factory, rubyClass); Layouts.CLASS.setInstanceFactoryUnsafe(rubyClass, factory); }
public void getAdoptedByLexicalParent( DynamicObject lexicalParent, String name, Node currentNode) { assert RubyGuards.isRubyModule(lexicalParent); Layouts.MODULE .getFields(lexicalParent) .setConstantInternal(currentNode, name, rubyModuleObject, false); Layouts.MODULE.getFields(lexicalParent).addLexicalDependent(rubyModuleObject); if (this.name == null) { // Tricky, we need to compare with the Object class, but we only have a Class at hand. final DynamicObject classClass = Layouts.BASIC_OBJECT.getLogicalClass(getLogicalClass()); final DynamicObject objectClass = ClassNodes.getSuperClass(ClassNodes.getSuperClass(classClass)); if (lexicalParent == objectClass) { this.name = name; updateAnonymousChildrenModules(); } else if (Layouts.MODULE.getFields(lexicalParent).hasName()) { this.name = Layouts.MODULE.getFields(lexicalParent).getName() + "::" + name; updateAnonymousChildrenModules(); } // else: Our lexicalParent is also an anonymous module // and will name us when it gets named via updateAnonymousChildrenModules() } }
private Object coerceObject(VirtualFrame frame, Object object) { if (toIntNode == null) { CompilerDirectives.transferToInterpreter(); toIntNode = insert(DispatchHeadNodeFactory.createMethodCall(getContext())); } final Object coerced; try { coerced = toIntNode.call(frame, object, "to_int", null); } catch (RaiseException e) { if (Layouts.BASIC_OBJECT.getLogicalClass(e.getRubyException()) == getContext().getCoreLibrary().getNoMethodErrorClass()) { CompilerDirectives.transferToInterpreter(); throw new RaiseException( getContext().getCoreLibrary().typeErrorNoImplicitConversion(object, "Integer", this)); } else { throw e; } } if (getContext().getCoreLibrary().getLogicalClass(coerced) == getContext().getCoreLibrary().getFixnumClass()) { return coerced; } else { CompilerDirectives.transferToInterpreter(); throw new RaiseException( getContext() .getCoreLibrary() .typeErrorBadCoercion(object, "Integer", "to_int", coerced, this)); } }
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); }
public static DynamicObject createRubyClass( RubyContext context, DynamicObject classClass, DynamicObject lexicalParent, DynamicObject superclass, String name, boolean isSingleton, DynamicObject attached) { final ModuleFields model = new ModuleFields(context, lexicalParent, name); final DynamicObject rubyClass = Layouts.CLASS.createClass( Layouts.CLASS.getInstanceFactory(classClass), model, isSingleton, attached, null); assert RubyGuards.isRubyClass(rubyClass) : classClass.getShape().getObjectType().getClass(); assert RubyGuards.isRubyModule(rubyClass) : classClass.getShape().getObjectType().getClass(); model.rubyModuleObject = rubyClass; if (model.lexicalParent == null) { // bootstrap or anonymous module Layouts.MODULE.getFields(rubyClass).name = Layouts.MODULE.getFields(rubyClass).givenBaseName; } else { Layouts.MODULE .getFields(rubyClass) .getAdoptedByLexicalParent(model.lexicalParent, model.givenBaseName, null); } if (superclass != null) { assert RubyGuards.isRubyClass(superclass); assert RubyGuards.isRubyClass(Layouts.MODULE.getFields(rubyClass).rubyModuleObject); Layouts.MODULE.getFields(rubyClass).parentModule = Layouts.MODULE.getFields(superclass).start; Layouts.MODULE .getFields(superclass) .addDependent(Layouts.MODULE.getFields(rubyClass).rubyModuleObject); Layouts.MODULE.getFields(rubyClass).newVersion(); } DynamicObjectFactory factory = Layouts.CLASS.getInstanceFactory(superclass); factory = Layouts.BASIC_OBJECT.setLogicalClass(factory, rubyClass); factory = Layouts.BASIC_OBJECT.setMetaClass(factory, rubyClass); Layouts.CLASS.setInstanceFactoryUnsafe(rubyClass, factory); return rubyClass; }
public static DynamicObject createRubyClass( RubyContext context, DynamicObject lexicalParent, DynamicObject superclass, String name) { final DynamicObject rubyClass = createRubyClass( context, Layouts.BASIC_OBJECT.getLogicalClass(superclass), lexicalParent, superclass, name, false, null); ensureSingletonConsistency(rubyClass); return rubyClass; }
public static DynamicObject createSingletonClassOfObject( RubyContext context, DynamicObject superclass, DynamicObject attached, String name) { // We also need to create the singleton class of a singleton class for proper lookup and // consistency. // See rb_singleton_class() documentation in MRI. // Allocator is null here, we cannot create instances of singleton classes. assert RubyGuards.isRubyClass(superclass); assert attached == null || RubyGuards.isRubyModule(attached); return ensureSingletonConsistency( createRubyClass( context, Layouts.BASIC_OBJECT.getLogicalClass(superclass), null, superclass, name, true, attached)); }
/** * This constructor supports initialization and solves boot-order problems and should not normally * be used from outside this class. */ public static DynamicObject createBootClass( DynamicObject classClass, DynamicObject superclass, String name) { assert RubyGuards.isRubyClass(classClass); assert superclass == null || RubyGuards.isRubyClass(superclass); final ModuleFields model = new ModuleFields( Layouts.MODULE.getFields(Layouts.BASIC_OBJECT.getLogicalClass(classClass)).getContext(), null, name); final DynamicObject rubyClass = Layouts.CLASS.createClass( Layouts.CLASS.getInstanceFactory(classClass), model, false, null, null); assert RubyGuards.isRubyClass(rubyClass) : classClass.getShape().getObjectType().getClass(); assert RubyGuards.isRubyModule(rubyClass) : classClass.getShape().getObjectType().getClass(); model.rubyModuleObject = rubyClass; if (model.lexicalParent == null) { // bootstrap or anonymous module Layouts.MODULE.getFields(rubyClass).name = Layouts.MODULE.getFields(rubyClass).givenBaseName; } else { Layouts.MODULE .getFields(rubyClass) .getAdoptedByLexicalParent(model.lexicalParent, model.givenBaseName, null); } if (superclass != null) { assert RubyGuards.isRubyClass(superclass); assert RubyGuards.isRubyClass(Layouts.MODULE.getFields(rubyClass).rubyModuleObject); Layouts.MODULE.getFields(rubyClass).parentModule = Layouts.MODULE.getFields(superclass).start; Layouts.MODULE .getFields(superclass) .addDependent(Layouts.MODULE.getFields(rubyClass).rubyModuleObject); Layouts.MODULE.getFields(rubyClass).newVersion(); } return rubyClass; }
/** Special constructor for class Class */ public static DynamicObject createClassClass(RubyContext context) { final ModuleFields model = new ModuleFields(context, null, "Class"); final DynamicObject rubyClass = LAYOUT.newInstance(LAYOUT.createShape(new ObjectType())); final DynamicObjectFactory factory = Layouts.CLASS.createClassShape(rubyClass, rubyClass); rubyClass.setShapeAndGrow(rubyClass.getShape(), factory.getShape()); assert RubyGuards.isRubyModule(rubyClass); assert RubyGuards.isRubyClass(rubyClass); model.rubyModuleObject = rubyClass; Layouts.CLASS.setInstanceFactoryUnsafe(rubyClass, factory); Layouts.MODULE.setFields(rubyClass, model); model.name = model.givenBaseName; assert RubyGuards.isRubyModule(rubyClass); assert RubyGuards.isRubyClass(rubyClass); assert Layouts.MODULE.getFields(rubyClass) == model; assert Layouts.BASIC_OBJECT.getLogicalClass(rubyClass) == rubyClass; return rubyClass; }
@Override public Object isDefined(VirtualFrame frame) { final RubyConstant constant; try { constant = lookupConstantNode.executeLookupConstant(frame); } catch (RaiseException e) { if (Layouts.BASIC_OBJECT.getLogicalClass(((DynamicObject) e.getRubyException())) == getContext().getCoreLibrary().getNameErrorClass()) { // private constant return nil(); } throw e; } if (constant == null) { return nil(); } else { return Layouts.STRING.createString( getContext().getCoreLibrary().getStringFactory(), RubyString.encodeBytelist("constant", UTF8Encoding.INSTANCE), StringSupport.CR_7BIT, null); } }
private DynamicObject translate(UnsupportedSpecializationException exception) { if (getContext().getOptions().EXCEPTIONS_PRINT_JAVA) { exception.printStackTrace(); } final StringBuilder builder = new StringBuilder(); builder.append("Truffle doesn't have a case for the "); builder.append(exception.getNode().getClass().getName()); builder.append(" node with values of type "); for (Object value : exception.getSuppliedValues()) { builder.append(" "); if (value == null) { builder.append("null"); } else if (value instanceof DynamicObject) { builder.append( Layouts.MODULE .getFields(Layouts.BASIC_OBJECT.getLogicalClass(((DynamicObject) value))) .getName()); builder.append("("); builder.append(value.getClass().getName()); builder.append(")"); if (RubyGuards.isRubyArray(value)) { final DynamicObject array = (DynamicObject) value; builder.append("["); if (Layouts.ARRAY.getStore(array) == null) { builder.append("null"); } else { builder.append(Layouts.ARRAY.getStore(array).getClass().getName()); } builder.append(","); builder.append(Layouts.ARRAY.getSize(array)); builder.append("]"); } else if (RubyGuards.isRubyHash(value)) { final Object store = Layouts.HASH.getStore((DynamicObject) value); if (store == null) { builder.append("[null]"); } else { builder.append("["); builder.append(store.getClass().getName()); builder.append("]"); } } } else { builder.append(value.getClass().getName()); } if (value instanceof Number || value instanceof Boolean) { builder.append("="); builder.append(value.toString()); } } switch (unsupportedOperationBehavior) { case TYPE_ERROR: return getContext().getCoreLibrary().typeError(builder.toString(), this); case ARGUMENT_ERROR: return getContext().getCoreLibrary().argumentError(builder.toString(), this); default: throw new UnsupportedOperationException(); } }
public DynamicObject getLogicalClass() { return Layouts.BASIC_OBJECT.getLogicalClass(rubyModuleObject); }