Skip to content
Snippets Groups Projects
Commit 729be668 authored by Lukas Stadler's avatar Lukas Stadler
Browse files

change interop accesses in ExtractVectorNode/ReplaceVectorNode to use KEY_INFO only if necessary

parent 61c08214
No related branches found
No related tags found
No related merge requests found
......@@ -307,49 +307,90 @@ public abstract class ExtractVectorNode extends RBaseNode {
}
}
protected static ReadElementNode createReadElement() {
static ReadElementNode createReadElement() {
return new ReadElementNode();
}
static final class ReadElementNode extends RBaseNode {
abstract static class AccessElementNode extends RBaseNode {
@Child private Node foreignRead = com.oracle.truffle.api.interop.Message.READ.createNode();
@Child private Node keyInfoNode = com.oracle.truffle.api.interop.Message.KEY_INFO.createNode();
@Child private Node hasSizeNode = com.oracle.truffle.api.interop.Message.HAS_SIZE.createNode();
@Child private CastStringNode castNode = CastStringNode.create();
@Child private FirstStringNode firstString = createFirstString();
@Child private Node hasSizeNode;
@Child private CastStringNode castNode;
@Child private FirstStringNode firstString;
private final ConditionProfile isIntProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile isDoubleProfile = ConditionProfile.createBinaryProfile();
public Object execute(Object position, TruffleObject object) throws InteropException {
protected final Object extractPosition(Object position) {
Object pos = position;
if (isIntProfile.profile(pos instanceof Integer)) {
pos = ((int) pos) - 1;
} else if (isDoubleProfile.profile(pos instanceof Double)) {
pos = ((double) pos) - 1;
} else if (pos instanceof RAbstractDoubleVector) {
pos = ((RAbstractDoubleVector) pos).getDataAt(0) - 1;
RAbstractDoubleVector vector = (RAbstractDoubleVector) pos;
if (vector.getLength() == 0) {
throw error(RError.Message.GENERIC, "invalid index during foreign access");
}
pos = vector.getDataAt(0) - 1;
} else if (pos instanceof RAbstractIntVector) {
pos = ((RAbstractIntVector) pos).getDataAt(0) - 1;
RAbstractIntVector vector = (RAbstractIntVector) pos;
if (vector.getLength() == 0) {
throw error(RError.Message.GENERIC, "invalid index during foreign access");
}
pos = vector.getDataAt(0) - 1;
} else if (pos instanceof RAbstractStringVector) {
if (castNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
castNode = insert(CastStringNode.create());
}
if (firstString == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
firstString = insert(createFirstString());
}
pos = firstString.executeString(castNode.doCast(pos));
} else if (!(pos instanceof String)) {
throw error(RError.Message.GENERIC, "invalid index during foreign access");
}
return pos;
}
protected final boolean hasSize(TruffleObject object) {
if (hasSizeNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
hasSizeNode = insert(com.oracle.truffle.api.interop.Message.HAS_SIZE.createNode());
}
return ForeignAccess.sendHasSize(hasSizeNode, object);
}
}
static final class ReadElementNode extends AccessElementNode {
@Child private Node foreignRead = com.oracle.truffle.api.interop.Message.READ.createNode();
@Child private Node classForeignRead;
@Child private Node keyInfoNode;
public Object execute(Object position, TruffleObject object) throws InteropException {
Object pos = extractPosition(position);
if (keyInfoNode == null) {
try {
return ForeignAccess.sendRead(foreignRead, object, pos);
} catch (InteropException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
keyInfoNode = insert(com.oracle.truffle.api.interop.Message.KEY_INFO.createNode());
}
}
int info = ForeignAccess.sendKeyInfo(keyInfoNode, object, pos);
if (KeyInfo.isReadable(info) || ForeignAccess.sendHasSize(hasSizeNode, object)) {
if (KeyInfo.isReadable(info) || hasSize(object)) {
return ForeignAccess.sendRead(foreignRead, object, pos);
} else if (pos instanceof String && !KeyInfo.isExisting(info) && JavaInterop.isJavaObject(Object.class, object)) {
TruffleObject clazz = toJavaClass(object);
info = ForeignAccess.sendKeyInfo(keyInfoNode, clazz, pos);
if (KeyInfo.isReadable(info)) {
return ForeignAccess.sendRead(foreignRead, clazz, pos);
if (classForeignRead == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
classForeignRead = insert(com.oracle.truffle.api.interop.Message.READ.createNode());
}
return ForeignAccess.sendRead(classForeignRead, toJavaClass(object), pos);
}
CompilerDirectives.transferToInterpreter();
throw error(RError.Message.GENERIC, "invalid index/identifier during foreign access: " + pos);
}
}
......
......@@ -36,7 +36,7 @@ import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.java.JavaInterop;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.object.DynamicObject;
import com.oracle.truffle.api.profiles.ConditionProfile;
import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode.AccessElementNode;
import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode.ExtractSingleName;
import com.oracle.truffle.r.nodes.access.vector.ExtractVectorNode.ReadElementNode;
import com.oracle.truffle.r.nodes.binary.BoxPrimitiveNode;
......@@ -44,7 +44,6 @@ import com.oracle.truffle.r.nodes.builtin.CastBuilder.Predef;
import com.oracle.truffle.r.nodes.objects.GetS4DataSlot;
import com.oracle.truffle.r.nodes.profile.TruffleBoundaryNode;
import com.oracle.truffle.r.nodes.profile.VectorLengthProfile;
import com.oracle.truffle.r.nodes.unary.CastStringNode;
import com.oracle.truffle.r.nodes.unary.FirstStringNode;
import com.oracle.truffle.r.runtime.RError;
import com.oracle.truffle.r.runtime.RInternalError;
......@@ -61,10 +60,7 @@ import com.oracle.truffle.r.runtime.data.RS4Object;
import com.oracle.truffle.r.runtime.data.RScalarVector;
import com.oracle.truffle.r.runtime.data.RTypedValue;
import com.oracle.truffle.r.runtime.data.model.RAbstractAtomicVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractDoubleVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractIntVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractListVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractStringVector;
import com.oracle.truffle.r.runtime.data.model.RAbstractVector;
import com.oracle.truffle.r.runtime.env.REnvironment;
import com.oracle.truffle.r.runtime.env.REnvironment.PutException;
......@@ -304,48 +300,38 @@ public abstract class ReplaceVectorNode extends RBaseNode {
return new WriteElementNode();
}
static final class WriteElementNode extends RBaseNode {
static final class WriteElementNode extends AccessElementNode {
@Child private Node keyInfoNode = com.oracle.truffle.api.interop.Message.KEY_INFO.createNode();
@Child private Node hasSizeNode = com.oracle.truffle.api.interop.Message.HAS_SIZE.createNode();
@Child private Node keyInfoNode;
@Child private Node foreignWrite = com.oracle.truffle.api.interop.Message.WRITE.createNode();
@Child private Node classForeignWrite;
@Child private R2Foreign r2Foreign = R2Foreign.create();
@Child private CastStringNode castNode = CastStringNode.create();
@Child private FirstStringNode firstString = ExtractVectorNode.createFirstString();
private final ConditionProfile isIntProfile = ConditionProfile.createBinaryProfile();
private final ConditionProfile isDoubleProfile = ConditionProfile.createBinaryProfile();
private void execute(Object position, TruffleObject object, Object writtenValue) throws InteropException {
Object pos = position;
if (isIntProfile.profile(pos instanceof Integer)) {
pos = ((int) pos) - 1;
} else if (isDoubleProfile.profile(pos instanceof Double)) {
pos = ((double) pos) - 1;
} else if (pos instanceof RAbstractDoubleVector) {
pos = ((RAbstractDoubleVector) pos).getDataAt(0) - 1;
} else if (pos instanceof RAbstractIntVector) {
pos = ((RAbstractIntVector) pos).getDataAt(0) - 1;
} else if (pos instanceof RAbstractStringVector) {
String string = firstString.executeString(castNode.doCast(pos));
pos = string;
} else if (!(pos instanceof String)) {
throw error(RError.Message.GENERIC, "invalid index during foreign access");
Object pos = extractPosition(position);
Object value = r2Foreign.execute(writtenValue);
if (keyInfoNode == null) {
try {
ForeignAccess.sendWrite(foreignWrite, object, pos, value);
return;
} catch (InteropException e) {
CompilerDirectives.transferToInterpreterAndInvalidate();
keyInfoNode = insert(com.oracle.truffle.api.interop.Message.KEY_INFO.createNode());
}
}
int info = ForeignAccess.sendKeyInfo(keyInfoNode, object, pos);
if (KeyInfo.isWritable(info) || ForeignAccess.sendHasSize(hasSizeNode, object) ||
(pos instanceof String && !JavaInterop.isJavaObject(Object.class, object))) {
ForeignAccess.sendWrite(foreignWrite, object, pos, r2Foreign.execute(writtenValue));
if (KeyInfo.isWritable(info) || hasSize(object)) {
ForeignAccess.sendWrite(foreignWrite, object, pos, value);
return;
} else if (pos instanceof String && !KeyInfo.isExisting(info) && JavaInterop.isJavaObject(Object.class, object)) {
TruffleObject clazz = toJavaClass(object);
info = ForeignAccess.sendKeyInfo(keyInfoNode, clazz, pos);
if (KeyInfo.isWritable(info)) {
ForeignAccess.sendWrite(foreignWrite, clazz, pos, r2Foreign.execute(writtenValue));
return;
if (classForeignWrite == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
classForeignWrite = insert(com.oracle.truffle.api.interop.Message.WRITE.createNode());
}
ForeignAccess.sendWrite(classForeignWrite, toJavaClass(object), pos, value);
return;
}
CompilerDirectives.transferToInterpreter();
throw error(RError.Message.GENERIC, "invalid index/identifier during foreign access: " + pos);
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment