@Specialization(guards = {"!copyAllAttributes || target != source", "containsMetadata(source)"}) protected RAbstractVector copySameLength( RAbstractVector target, RAbstractVector source, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("createDim()") RemoveFixedAttributeNode removeDim, // @Cached("createDimNames()") RemoveFixedAttributeNode removeDimNames, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createNames()") SetFixedAttributeNode putNames, // @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("createDimNames()") SetFixedAttributeNode putDimNames, // @Cached("createBinaryProfile()") ConditionProfile noDimensions, // @Cached("createBinaryProfile()") ConditionProfile hasNamesSource, // @Cached("createBinaryProfile()") ConditionProfile hasDimNames, @Cached("create()") GetDimAttributeNode getDimsNode) { RVector<?> result = target.materialize(); if (copyAllAttributes) { copyOfReg.execute(source, result); } int[] newDimensions = getDimsNode.getDimensions(source); if (noDimensions.profile(newDimensions == null)) { DynamicObject attributes = result.getAttributes(); if (attributes != null) { removeDim.execute(attributes); removeDimNames.execute(attributes); } RStringVector vecNames = getNamesNode.getNames(source); if (hasNamesSource.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); return result; } return result; } putDim.execute( initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); RList newDimNames = getDimNamesNode.getDimNames(source); if (hasDimNames.profile(newDimNames != null)) { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; return result; } return result; }
protected boolean containsMetadata(RAbstractVector vector) { return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || getNamesNode.getNames(vector) != null || getDimNamesNode.getDimNames(vector) != null; }
/** * Copies all attributes from source to target including 'names', 'dimNames' and 'dim' (unlike * {@link CopyOfRegAttributesNode}), additionally removes the 'dim' from the result if it is not * present in the source. * * <p>TODO: this logic is duplicated in RVector#copyRegAttributesFrom and UnaryMapNode, but behind * TruffleBoundary, does it have a reason for TruffleBoundary? Can we replace it with this node? */ public abstract class UnaryCopyAttributesNode extends RBaseNode { protected final boolean copyAllAttributes; @Child protected HasFixedAttributeNode hasDimNode = HasFixedAttributeNode.createDim(); @Child protected GetDimNamesAttributeNode getDimNamesNode = GetDimNamesAttributeNode.create(); @Child protected GetNamesAttributeNode getNamesNode = GetNamesAttributeNode.create(); protected UnaryCopyAttributesNode(boolean copyAllAttributes) { this.copyAllAttributes = copyAllAttributes; } public static UnaryCopyAttributesNode create() { return UnaryCopyAttributesNodeGen.create(true); } public abstract RAbstractVector execute(RAbstractVector target, RAbstractVector left); protected boolean containsMetadata(RAbstractVector vector) { return vector instanceof RVector && hasDimNode.execute(vector) || (copyAllAttributes && vector.getAttributes() != null) || getNamesNode.getNames(vector) != null || getDimNamesNode.getDimNames(vector) != null; } @SuppressWarnings("unused") @Specialization(guards = "!containsMetadata(source)") protected RAbstractVector copyNoMetadata(RAbstractVector target, RAbstractVector source) { return target; } @SuppressWarnings("unused") @Specialization(guards = {"copyAllAttributes", "target == source"}) protected RAbstractVector copySameVector(RAbstractVector target, RAbstractVector source) { return target; } @Specialization(guards = {"!copyAllAttributes || target != source", "containsMetadata(source)"}) protected RAbstractVector copySameLength( RAbstractVector target, RAbstractVector source, // @Cached("create()") CopyOfRegAttributesNode copyOfReg, // @Cached("createDim()") RemoveFixedAttributeNode removeDim, // @Cached("createDimNames()") RemoveFixedAttributeNode removeDimNames, // @Cached("create()") InitAttributesNode initAttributes, // @Cached("createNames()") SetFixedAttributeNode putNames, // @Cached("createDim()") SetFixedAttributeNode putDim, // @Cached("createDimNames()") SetFixedAttributeNode putDimNames, // @Cached("createBinaryProfile()") ConditionProfile noDimensions, // @Cached("createBinaryProfile()") ConditionProfile hasNamesSource, // @Cached("createBinaryProfile()") ConditionProfile hasDimNames, @Cached("create()") GetDimAttributeNode getDimsNode) { RVector<?> result = target.materialize(); if (copyAllAttributes) { copyOfReg.execute(source, result); } int[] newDimensions = getDimsNode.getDimensions(source); if (noDimensions.profile(newDimensions == null)) { DynamicObject attributes = result.getAttributes(); if (attributes != null) { removeDim.execute(attributes); removeDimNames.execute(attributes); } RStringVector vecNames = getNamesNode.getNames(source); if (hasNamesSource.profile(vecNames != null)) { putNames.execute(initAttributes.execute(result), vecNames); return result; } return result; } putDim.execute( initAttributes.execute(result), RDataFactory.createIntVector(newDimensions, RDataFactory.COMPLETE_VECTOR)); RList newDimNames = getDimNamesNode.getDimNames(source); if (hasDimNames.profile(newDimNames != null)) { putDimNames.execute(result.getAttributes(), newDimNames); newDimNames.elementNamePrefix = RRuntime.DIMNAMES_LIST_ELEMENT_NAME_PREFIX; return result; } return result; } }