Example #1
0
 private void setSlowCase(DynamicObject store, Object value) {
   Shape oldShape = store.getShape();
   Shape newShape = oldShape.defineProperty(getKey(), value, getFlags());
   if (store.updateShape()) {
     oldShape = store.getShape();
   }
   assert newShape.isValid() && oldShape.isValid();
   Property newProperty = newShape.getProperty(getKey());
   newProperty.setSafe(store, value, oldShape, newShape);
 }
  protected Location getLocation(DynamicObject object, Object value) {
    object.updateShape();
    final Shape oldShape = object.getShape();
    final Property property = oldShape.getProperty(name);

    if (property != null && property.getLocation().canSet(object, value)) {
      return property.getLocation();
    } else {
      return null;
    }
  }
  @TruffleBoundary
  @Specialization
  public void writeUncached(DynamicObject object, Object value) {
    object.updateShape();
    final Shape shape = object.getShape();
    final Property property = shape.getProperty(name);

    if (property == null) {
      object.define(name, value, 0);
    } else {
      property.setGeneric(object, value, shape);
    }
  }
Example #4
0
  @Override
  public Object executeDispatch(
      final VirtualFrame frame,
      final Object receiverObject,
      final Object methodName,
      DynamicObject blockObject,
      final Object[] argumentsObjects) {
    CompilerDirectives.transferToInterpreterAndInvalidate();

    // Make sure to have an up-to-date Shape.
    if (receiverObject instanceof DynamicObject) {
      ((DynamicObject) receiverObject).updateShape();
    }

    final DispatchNode dispatch =
        atomic(
            new Callable<DispatchNode>() {
              @Override
              public DispatchNode call() throws Exception {
                final DispatchNode first = getHeadNode().getFirstDispatchNode();

                // First try to see if we did not a miss a specialization added by another thread.

                DispatchNode lookupDispatch = first;
                while (lookupDispatch != null) {
                  if (lookupDispatch.guard(methodName, receiverObject)) {
                    // This one worked, no need to rewrite anything.
                    return lookupDispatch;
                  }
                  lookupDispatch = lookupDispatch.getNext();
                }

                // We need a new node to handle this case.

                final DispatchNode newDispathNode;

                if (depth == getContext().getOptions().DISPATCH_CACHE) {
                  newDispathNode =
                      new UncachedDispatchNode(
                          getContext(), ignoreVisibility, getDispatchAction(), missingBehavior);
                } else {
                  depth++;
                  if (RubyGuards.isForeignObject(receiverObject)) {
                    newDispathNode = createForeign(argumentsObjects, first, methodName);
                  } else if (RubyGuards.isRubyBasicObject(receiverObject)) {
                    newDispathNode =
                        doDynamicObject(frame, first, receiverObject, methodName, argumentsObjects);
                  } else {
                    newDispathNode = doUnboxedObject(frame, first, receiverObject, methodName);
                  }
                }

                first.replace(newDispathNode);
                return newDispathNode;
              }
            });

    return dispatch.executeDispatch(
        frame, receiverObject, methodName, blockObject, argumentsObjects);
  }
Example #5
0
 @Override
 public final void set(DynamicObject store, Object value, Shape oldShape, Shape newShape)
     throws IncompatibleLocationException {
   assert store.getShape() == oldShape : "wrong shape";
   assert newShape.isValid();
   assert getLocation() != null;
   getLocation().set(store, value, oldShape, newShape);
 }
Example #6
0
  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;
  }
Example #7
0
 @Override
 public final void setSafe(DynamicObject store, Object value, Shape shape) {
   assert shape == null || store.getShape() == shape : "wrong shape";
   try {
     getLocation().set(store, value, shape);
   } catch (IncompatibleLocationException | FinalLocationException ex) {
     throw new IllegalStateException();
   }
 }
Example #8
0
 @Override
 public final void setGeneric(DynamicObject store, Object value, Shape shape) {
   assert shape == null || store.getShape() == shape : "wrong shape";
   try {
     set(store, value, shape);
   } catch (IncompatibleLocationException | FinalLocationException ex) {
     setSlowCase(store, value);
   }
 }
 @Override
 public String toString() {
   return String.format(
       "CachedBoxedDispatchNode(:%s, %s@%x, %s)",
       getCachedNameAsSymbol().toString(),
       expectedReceiver,
       expectedReceiver.hashCode(),
       method == null ? "null" : method.toString());
 }
Example #10
0
  private void setWithShapeSlowCase(
      DynamicObject store, Object value, Shape currentShape, Shape nextShape) {
    Shape oldShape = currentShape;
    if (store.updateShape()) {
      oldShape = store.getShape();
    }
    LayoutStrategy strategy = ((LayoutImpl) currentShape.getLayout()).getStrategy();
    LayoutStrategy.ShapeAndProperty newShapeAndProperty =
        strategy.generalizeProperty(this, value, (ShapeImpl) oldShape, (ShapeImpl) nextShape);
    if (store.updateShape()) {
      oldShape = store.getShape();
    }

    Shape newNextShape = newShapeAndProperty.getShape();
    Property newProperty = newShapeAndProperty.getProperty();

    assert newNextShape.isValid() && oldShape.isValid();
    newProperty.setSafe(store, value, oldShape, newNextShape);
  }
Example #11
0
 @Override
 public final void setGeneric(DynamicObject store, Object value, Shape oldShape, Shape newShape) {
   assert store.getShape() == oldShape : "wrong old shape";
   assert newShape.isValid();
   assert getLocation() != null;
   try {
     getLocation().set(store, value, oldShape, newShape);
   } catch (IncompatibleLocationException ex) {
     setWithShapeSlowCase(store, value, oldShape, newShape);
   }
 }
Example #12
0
 @Override
 public final void setSafe(DynamicObject store, Object value, Shape oldShape, Shape newShape) {
   assert store.getShape() == oldShape : "wrong old shape";
   assert newShape.isValid();
   assert getLocation() != null;
   try {
     getLocation().set(store, value, oldShape, newShape);
   } catch (IncompatibleLocationException ex) {
     throw new IllegalStateException();
   }
 }
 protected Shape transitionWithNewField(Shape oldShape, Object value) {
   // This duplicates quite a bit of DynamicObject.define(), but should be fixed in Truffle soon.
   final Property oldProperty = oldShape.getProperty(name);
   if (oldProperty != null) {
     if (oldProperty.getFlags() == 0 && oldProperty.getLocation().canSet(null, value)) {
       return oldShape; // already the right shape
     } else {
       DynamicObject copy = oldShape.getLayout().newInstance(oldShape);
       copy.define(name, value, 0);
       return copy.getShape();
     }
   } else {
     final Location location =
         oldShape
             .allocator()
             .locationForValue(
                 value, EnumSet.of(LocationModifier.Final, LocationModifier.NonNull));
     final Property newProperty = Property.create(name, location, 0);
     return oldShape.addProperty(newProperty);
   }
 }
Example #14
0
  /**
   * 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;
  }
Example #15
0
  /** 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;
  }
Example #16
0
    @Specialization(guards = "isRubyString(index)")
    public Object getIndexString(DynamicObject matchData, DynamicObject index, NotProvided length) {
      CompilerDirectives.transferToInterpreter();

      try {
        final int i = getBackrefNumber(matchData, Layouts.STRING.getByteList(index));

        return getIndex(matchData, i, NotProvided.INSTANCE);
      } catch (final ValueException e) {
        CompilerDirectives.transferToInterpreter();

        throw new RaiseException(
            getContext()
                .getCoreLibrary()
                .indexError(
                    String.format("undefined group name reference: %s", index.toString()), this));
      }
    }
Example #17
0
  /** Set the value of a constant, possibly redefining it. */
  @CompilerDirectives.TruffleBoundary
  public void setConstant(Node currentNode, String name, Object value) {
    if (getContext().getCoreLibrary().isLoadingRubyCore()) {
      final RubyConstant currentConstant = constants.get(name);

      if (currentConstant != null) {
        return;
      }
    }

    if (RubyGuards.isRubyModule(value)) {
      Layouts.MODULE
          .getFields(((DynamicObject) value))
          .getAdoptedByLexicalParent(rubyModuleObject, name, currentNode);
    } else {
      setConstantInternal(currentNode, name, value, false);
    }
  }
Example #18
0
  @Specialization(
      guards = "object.getShape() == cachedShape",
      assumptions = "cachedShape.getValidAssumption()",
      limit = "CACHE_LIMIT")
  @ExplodeLoop
  protected void shareCached(
      DynamicObject object,
      @Cached("ensureSharedClasses(object.getShape())") Shape cachedShape,
      @Cached("createShareInternalFieldsNode()") ShareInternalFieldsNode shareInternalFieldsNode,
      @Cached("createReadAndShareFieldNodes(getObjectProperties(cachedShape))")
          ReadAndShareFieldNode[] readAndShareFieldNodes,
      @Cached("createSharedShape(object)") Shape sharedShape) {
    assert !SharedObjects.isShared(cachedShape);

    // Mark the object as shared first to avoid recursion
    object.setShapeAndGrow(cachedShape, sharedShape);

    shareInternalFieldsNode.executeShare(object);

    for (ReadAndShareFieldNode readAndShareFieldNode : readAndShareFieldNodes) {
      readAndShareFieldNode.executeReadFieldAndShare(object);
    }
  }
Example #19
0
 public static boolean updateShape(DynamicObject object) {
   CompilerDirectives.transferToInterpreter();
   return object.updateShape();
 }
Example #20
0
 protected static Shape createSharedShape(DynamicObject object) {
   object.updateShape();
   final Shape oldShape = object.getShape();
   return oldShape.makeSharedShape();
 }
 @Override
 Object execute(DynamicObject receiver, String name, Object value) {
   Property property = receiver.getShape().getProperty(name);
   return receiver.set(property.getKey(), value);
 }
 @Specialization
 public DynamicObject exceptionErrnoError(DynamicObject message, int errno) {
   return getContext().getCoreLibrary().errnoError(errno, message.toString(), this);
 }
Example #23
0
 @Override
 public final void set(DynamicObject store, Object value, Shape shape)
     throws IncompatibleLocationException, FinalLocationException {
   assert shape == null || store.getShape() == shape : "wrong shape";
   getLocation().set(store, value, shape);
 }