Skip to content

Commit e119bc9

Browse files
committed
Make proper node out of 'checkFunctionResult'.
1 parent 538b167 commit e119bc9

File tree

2 files changed

+83
-17
lines changed

2 files changed

+83
-17
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
import com.oracle.graal.python.builtins.Builtin;
5555
import com.oracle.graal.python.builtins.CoreFunctions;
5656
import com.oracle.graal.python.builtins.PythonBuiltins;
57+
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltins.CheckFunctionResultNode;
5758
import com.oracle.graal.python.builtins.objects.PNone;
5859
import com.oracle.graal.python.builtins.objects.cext.CExtNodes.AsPythonObjectNode;
5960
import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes;
@@ -146,7 +147,7 @@ public abstract static class CreateDynamic extends PythonBuiltinNode {
146147
protected static final String IMPORT_NATIVE_MEMORYVIEW = "import_native_memoryview";
147148
private static final String LLVM_LANGUAGE = "llvm";
148149
@Child private SetItemNode setItemNode;
149-
@Child private Node isNullNode = Message.IS_NULL.createNode();
150+
@Child private CheckFunctionResultNode checkResultNode;
150151

151152
@Specialization
152153
@TruffleBoundary
@@ -198,7 +199,7 @@ private Object loadDynamicModuleWithSpec(String name, String path, Node readNode
198199
getContext().setCurrentException(null);
199200

200201
Object nativeResult = ForeignAccess.sendExecute(executeNode, pyinitFunc);
201-
TruffleCextBuiltins.checkFunctionResult(getContext(), isNullNode, "PyInit_" + basename, nativeResult);
202+
getCheckResultNode().execute("PyInit_" + basename, nativeResult);
202203

203204
// restore previous exception state
204205
getContext().setCurrentException(exceptionState);
@@ -260,6 +261,14 @@ private SetItemNode getSetItemNode() {
260261
return setItemNode;
261262
}
262263

264+
private CheckFunctionResultNode getCheckResultNode() {
265+
if (checkResultNode == null) {
266+
CompilerDirectives.transferToInterpreterAndInvalidate();
267+
checkResultNode = insert(CheckFunctionResultNode.create());
268+
}
269+
return checkResultNode;
270+
}
271+
263272
private PException reportImportError(RuntimeException e, String path) {
264273
StringBuilder sb = new StringBuilder();
265274
sb.append(e.getMessage());

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/TruffleCextBuiltins.java

Lines changed: 72 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@
5858
import com.oracle.graal.python.builtins.CoreFunctions;
5959
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
6060
import com.oracle.graal.python.builtins.PythonBuiltins;
61+
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltinsFactory.CheckFunctionResultNodeGen;
6162
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltinsFactory.GetByteArrayNodeGen;
6263
import com.oracle.graal.python.builtins.objects.PNone;
6364
import com.oracle.graal.python.builtins.objects.PythonAbstractObject;
@@ -150,6 +151,7 @@
150151
import com.oracle.truffle.api.nodes.Node;
151152
import com.oracle.truffle.api.nodes.RootNode;
152153
import com.oracle.truffle.api.profiles.BranchProfile;
154+
import com.oracle.truffle.api.profiles.ConditionProfile;
153155

154156
@CoreFunctions(defineModule = "python_cext")
155157
public class TruffleCextBuiltins extends PythonBuiltins {
@@ -502,21 +504,76 @@ private Object getLongItem(PDict nativeMembers, String key) {
502504
}
503505

504506
// roughly equivalent to _Py_CheckFunctionResult in Objects/call.c
505-
public static Object checkFunctionResult(PythonContext context, Node isNullNode, String name, Object result) {
506-
PException currentException = context.getCurrentException();
507-
// consume exception
508-
context.setCurrentException(null);
509-
boolean errOccurred = currentException != null;
510-
if (PGuards.isForeignObject(result) && ForeignAccess.sendIsNull(isNullNode, (TruffleObject) result) || result == PNone.NO_VALUE) {
511-
if (!errOccurred) {
512-
throw context.getCore().raise(PythonErrorType.SystemError, isNullNode, "%s returned NULL without setting an error", name);
513-
} else {
514-
throw currentException;
507+
@ImportStatic(PGuards.class)
508+
abstract static class CheckFunctionResultNode extends PBaseNode {
509+
510+
@Child private Node isNullNode;
511+
512+
public abstract Object execute(String name, Object result);
513+
514+
@Specialization
515+
Object doNativeWrapper(String name, PythonObjectNativeWrapper result,
516+
@Cached("create()") CheckFunctionResultNode recursive) {
517+
return recursive.execute(name, result.getDelegate());
518+
}
519+
520+
@Specialization(guards = "!isPythonObjectNativeWrapper(result)")
521+
Object doPrimitiveWrapper(String name, @SuppressWarnings("unused") PythonNativeWrapper result) {
522+
checkFunctionResult(name, false);
523+
return result;
524+
}
525+
526+
@Specialization(guards = "isNoValue(result)")
527+
Object doNoValue(String name, @SuppressWarnings("unused") PNone result) {
528+
checkFunctionResult(name, true);
529+
return PNone.NO_VALUE;
530+
}
531+
532+
@Specialization(guards = "!isNoValue(result)")
533+
Object doNativeWrapper(String name, @SuppressWarnings("unused") PythonAbstractObject result) {
534+
checkFunctionResult(name, false);
535+
return result;
536+
}
537+
538+
@Specialization(guards = "isForeignObject(result)")
539+
Object doForeign(String name, TruffleObject result,
540+
@Cached("createBinaryProfile()") ConditionProfile isNullProfile) {
541+
checkFunctionResult(name, isNullProfile.profile(isNull(result)));
542+
return result;
543+
}
544+
545+
private void checkFunctionResult(String name, boolean isNull) {
546+
PythonContext context = getContext();
547+
PException currentException = context.getCurrentException();
548+
// consume exception
549+
context.setCurrentException(null);
550+
boolean errOccurred = currentException != null;
551+
if (isNull) {
552+
if (!errOccurred) {
553+
throw context.getCore().raise(PythonErrorType.SystemError, isNullNode, "%s returned NULL without setting an error", name);
554+
} else {
555+
throw currentException;
556+
}
557+
} else if (errOccurred) {
558+
throw context.getCore().raise(PythonErrorType.SystemError, isNullNode, "%s returned a result with an error set", name);
515559
}
516-
} else if (errOccurred) {
517-
throw context.getCore().raise(PythonErrorType.SystemError, isNullNode, "%s returned a result with an error set", name);
518560
}
519-
return result;
561+
562+
private boolean isNull(TruffleObject result) {
563+
if (isNullNode == null) {
564+
CompilerDirectives.transferToInterpreterAndInvalidate();
565+
isNullNode = Message.IS_NULL.createNode();
566+
}
567+
return ForeignAccess.sendIsNull(isNullNode, result);
568+
}
569+
570+
protected static boolean isPythonObjectNativeWrapper(PythonNativeWrapper object) {
571+
return object instanceof PythonObjectNativeWrapper;
572+
}
573+
574+
public static CheckFunctionResultNode create() {
575+
return CheckFunctionResultNodeGen.create();
576+
}
520577
}
521578

522579
static class ExternalFunctionNode extends RootNode {
@@ -527,7 +584,7 @@ static class ExternalFunctionNode extends RootNode {
527584
@Child private Node executeNode;
528585
@Child CExtNodes.AllToSulongNode toSulongNode = CExtNodes.AllToSulongNode.create();
529586
@Child CExtNodes.AsPythonObjectNode asPythonObjectNode = CExtNodes.AsPythonObjectNode.create();
530-
@Child private Node isNullNode = Message.IS_NULL.createNode();
587+
@Child private CheckFunctionResultNode checkResultNode = CheckFunctionResultNode.create();
531588
@Child private PForeignToPTypeNode fromForeign = PForeignToPTypeNode.create();
532589

533590
public ExternalFunctionNode(PythonLanguage lang, String name, TruffleObject cwrapper, TruffleObject callable) {
@@ -564,7 +621,7 @@ public Object execute(VirtualFrame frame) {
564621
// clear current exception such that native code has clean environment
565622
getContext().setCurrentException(null);
566623

567-
Object result = fromNative(asPythonObjectNode.execute(checkFunctionResult(getContext(), isNullNode, name, ForeignAccess.sendExecute(executeNode, fun, arguments))));
624+
Object result = fromNative(asPythonObjectNode.execute(checkResultNode.execute(name, ForeignAccess.sendExecute(executeNode, fun, arguments))));
568625

569626
// restore previous exception state
570627
getContext().setCurrentException(exceptionState);

0 commit comments

Comments
 (0)