Skip to content

Commit 6ad04b2

Browse files
committed
Fix: use the SetAttributeNode in the RFFI function Rf_setAttrib
This means that the correct coercion and validation will take place.
1 parent fa79549 commit 6ad04b2

File tree

3 files changed

+59
-31
lines changed

3 files changed

+59
-31
lines changed

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/common/JavaUpCallsRFFIImpl.java

Lines changed: 2 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -320,35 +320,8 @@ public Object Rf_getAttrib(Object obj, Object name) {
320320
}
321321

322322
@Override
323-
@TruffleBoundary
324323
public void Rf_setAttrib(Object obj, Object name, Object val) {
325-
if (obj == RNull.instance) {
326-
return;
327-
}
328-
if (obj instanceof RAttributable) {
329-
RAttributable attrObj = (RAttributable) obj;
330-
String nameAsString;
331-
if (name instanceof RSymbol) {
332-
nameAsString = ((RSymbol) name).getName();
333-
} else {
334-
nameAsString = RRuntime.asString(name);
335-
assert nameAsString != null;
336-
}
337-
nameAsString = Utils.intern(nameAsString);
338-
if (val == RNull.instance) {
339-
if ("class" == nameAsString) {
340-
removeClassAttr(attrObj);
341-
} else {
342-
removeAttr(attrObj, nameAsString);
343-
}
344-
} else if ("class" == nameAsString) {
345-
attrObj.initAttributes().define(nameAsString, val);
346-
} else {
347-
attrObj.setAttr(nameAsString, val);
348-
}
349-
} else {
350-
throw RInternalError.shouldNotReachHere();
351-
}
324+
throw implementedAsNode();
352325
}
353326

354327
@TruffleBoundary

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/nodes/AttributesAccessNodes.java

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -34,11 +34,13 @@
3434
import com.oracle.truffle.api.profiles.ConditionProfile;
3535
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodesFactory.ATTRIBNodeGen;
3636
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodesFactory.CopyMostAttribNodeGen;
37+
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodesFactory.RfSetAttribNodeGen;
3738
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodesFactory.SetAttribNodeGen;
3839
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodesFactory.TAGNodeGen;
3940
import com.oracle.truffle.r.nodes.attributes.CopyOfRegAttributesNode;
4041
import com.oracle.truffle.r.nodes.attributes.GetAttributeNode;
4142
import com.oracle.truffle.r.nodes.attributes.GetAttributesNode;
43+
import com.oracle.truffle.r.nodes.attributes.RemoveAttributeNode;
4244
import com.oracle.truffle.r.nodes.attributes.SetAttributeNode;
4345
import com.oracle.truffle.r.nodes.attributes.SpecialAttributesFunctions.GetRowNamesAttributeNode;
4446
import com.oracle.truffle.r.nodes.function.opt.UpdateShareableChildValueNode;
@@ -91,6 +93,53 @@ private String castToString(Object name) {
9193
}
9294
}
9395

96+
/**
97+
* Sets a single attribute.
98+
*/
99+
public abstract static class RfSetAttribNode extends FFIUpCallNode.Arg3 {
100+
@Child private CastNode castNameNode;
101+
102+
public static RfSetAttribNode create() {
103+
return RfSetAttribNodeGen.create();
104+
}
105+
106+
@Specialization(guards = "!isNull(value)")
107+
protected Object setValue(RAttributable target, Object name, Object value,
108+
@Cached("create()") SetAttributeNode setAttribNode) {
109+
setAttribNode.execute(target, (String) getCastNameNode().doCast(name), value);
110+
return RNull.instance;
111+
}
112+
113+
@Specialization
114+
protected Object setValue(@SuppressWarnings("unused") RNull target, @SuppressWarnings("unused") Object name, @SuppressWarnings("unused") Object value) {
115+
return RNull.instance;
116+
}
117+
118+
@Specialization
119+
protected Object unsetValue(RAttributable target, Object name, @SuppressWarnings("unused") RNull nullVal,
120+
@Cached("create()") RemoveAttributeNode removeAttributeNode) {
121+
removeAttributeNode.execute(target, (String) getCastNameNode().doCast(name));
122+
return RNull.instance;
123+
}
124+
125+
@Fallback
126+
protected Object others(Object target, Object name, Object value) {
127+
throw unsupportedTypes("Rf_setAttrib", target, name, value);
128+
}
129+
130+
protected static boolean isNull(Object o) {
131+
return o == RNull.instance;
132+
}
133+
134+
private CastNode getCastNameNode() {
135+
if (castNameNode == null) {
136+
CompilerDirectives.transferToInterpreterAndInvalidate();
137+
castNameNode = insert(newCastBuilder().asStringVector().findFirst().buildCastNode());
138+
}
139+
return castNameNode;
140+
}
141+
}
142+
94143
public abstract static class ATTRIB extends FFIUpCallNode.Arg1 {
95144

96145
@Specialization
@@ -208,6 +257,10 @@ public static CopyMostAttrib create() {
208257
}
209258
}
210259

260+
/**
261+
* Overrides the attributes pairlist of given object with a new pairlist. In FastR, we have to
262+
* convert the pairlist to our representation.
263+
*/
211264
public abstract static class SetAttribNode extends FFIUpCallNode.Arg2 {
212265

213266
public static SetAttribNode create() {

com.oracle.truffle.r.ffi.impl/src/com/oracle/truffle/r/ffi/impl/upcalls/StdUpCallsRFFI.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2014, 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2014, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
2929
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.ATTRIB;
3030
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.CopyMostAttrib;
3131
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.GetAttrib;
32+
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.RfSetAttribNode;
3233
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.SetAttribNode;
3334
import com.oracle.truffle.r.ffi.impl.nodes.AttributesAccessNodes.TAG;
3435
import com.oracle.truffle.r.ffi.impl.nodes.CoerceNodes.AsCharacterFactor;
@@ -216,6 +217,7 @@ public interface StdUpCallsRFFI {
216217
@RFFIUpCallNode(GetAttrib.class)
217218
Object Rf_getAttrib(@RFFIResultOwner Object obj, Object name);
218219

220+
@RFFIUpCallNode(RfSetAttribNode.class)
219221
void Rf_setAttrib(Object obj, Object name, Object val);
220222

221223
int Rf_inherits(Object x, @RFFICstring String clazz);

0 commit comments

Comments
 (0)