Skip to content
Snippets Groups Projects
Commit e36ea522 authored by stepan's avatar stepan
Browse files

TryRfEvalNode: support errorFlag also with NFI

parent b2a94f39
Branches
No related tags found
No related merge requests found
...@@ -22,35 +22,67 @@ ...@@ -22,35 +22,67 @@
*/ */
package com.oracle.truffle.r.ffi.impl.nodes; package com.oracle.truffle.r.ffi.impl.nodes;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.interop.ForeignAccess; import com.oracle.truffle.api.interop.ForeignAccess;
import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.api.interop.InteropException;
import com.oracle.truffle.api.interop.Message; import com.oracle.truffle.api.interop.Message;
import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.interop.TruffleObject;
import com.oracle.truffle.api.interop.UnsupportedMessageException;
import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.r.ffi.impl.interop.UnsafeAdapter;
import com.oracle.truffle.r.runtime.RErrorHandling; import com.oracle.truffle.r.runtime.RErrorHandling;
import com.oracle.truffle.r.runtime.RInternalError;
import com.oracle.truffle.r.runtime.data.RNull;
public final class TryRfEvalNode extends FFIUpCallNode.Arg4 { public final class TryRfEvalNode extends FFIUpCallNode.Arg4 {
@Child RfEvalNode rfEvalNode = RfEvalNode.create(); @Child private RfEvalNode rfEvalNode = RfEvalNode.create();
@Child Node writeErrorFlagNode = Message.WRITE.createNode(); @Child private Node isNullNode = Message.IS_NULL.createNode();
@Child private Node writeErrorFlagNode;
@Child private Node isPointerNode;
@Child private Node asPointerNode;
@Override @Override
public Object executeObject(Object expr, Object env, Object errorFlag, Object silent) { public Object executeObject(Object expr, Object env, Object errorFlag, Object silent) {
Object handlerStack = RErrorHandling.getHandlerStack(); Object handlerStack = RErrorHandling.getHandlerStack();
Object restartStack = RErrorHandling.getRestartStack(); Object restartStack = RErrorHandling.getRestartStack();
boolean ok = true;
Object result = RNull.instance;
try { try {
// TODO handle silent // TODO handle silent
RErrorHandling.resetStacks(); RErrorHandling.resetStacks();
return rfEvalNode.executeObject(expr, env); result = rfEvalNode.executeObject(expr, env);
} catch (Throwable t) { } catch (Throwable t) {
try { ok = false;
ForeignAccess.sendWrite(writeErrorFlagNode, (TruffleObject) errorFlag, 0, 1); result = RNull.instance;
} catch (InteropException e) {
// Ignore it, when using NFI, e.g., the errorFlag TO does not support the WRITE
// message
}
return null;
} finally { } finally {
RErrorHandling.restoreStacks(handlerStack, restartStack); RErrorHandling.restoreStacks(handlerStack, restartStack);
} }
TruffleObject errorFlagTO = (TruffleObject) errorFlag;
if (!ForeignAccess.sendIsNull(isNullNode, errorFlagTO)) {
if (isPointerNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
isPointerNode = insert(Message.IS_POINTER.createNode());
}
if (ForeignAccess.sendIsPointer(isPointerNode, errorFlagTO)) {
if (asPointerNode == null) {
CompilerDirectives.transferToInterpreterAndInvalidate();
asPointerNode = insert(Message.AS_POINTER.createNode());
}
long errorFlagPtr;
try {
errorFlagPtr = ForeignAccess.sendAsPointer(asPointerNode, errorFlagTO);
} catch (UnsupportedMessageException e) {
throw RInternalError.shouldNotReachHere("IS_POINTER message returned true, AS_POINTER should not fail");
}
UnsafeAdapter.UNSAFE.putInt(errorFlagPtr, ok ? 0 : 1);
} else {
try {
ForeignAccess.sendWrite(writeErrorFlagNode, errorFlagTO, 0, 1);
} catch (InteropException e) {
throw RInternalError.shouldNotReachHere("Rf_tryEval errorFlag should be either pointer or support WRITE message");
}
}
}
return result;
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment