|
71 | 71 | import com.oracle.graal.python.builtins.modules.BuiltinConstructors.IntNode;
|
72 | 72 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.AllocFuncRootNode;
|
73 | 73 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.GetAttrFuncRootNode;
|
| 74 | +import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.IterNextFuncRootNode; |
74 | 75 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.MethDirectRoot;
|
75 | 76 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.MethFastcallRoot;
|
76 | 77 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.MethFastcallWithKeywordsRoot;
|
|
85 | 86 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.RichCmpFuncRootNode;
|
86 | 87 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.SSizeObjArgProcRootNode;
|
87 | 88 | import com.oracle.graal.python.builtins.modules.ExternalFunctionNodes.SetAttrFuncRootNode;
|
| 89 | +import com.oracle.graal.python.builtins.modules.PythonCextBuiltinsFactory.CheckIterNextResultNodeGen; |
88 | 90 | import com.oracle.graal.python.builtins.modules.PythonCextBuiltinsFactory.DefaultCheckFunctionResultNodeGen;
|
89 | 91 | import com.oracle.graal.python.builtins.modules.PythonCextBuiltinsFactory.GetByteArrayNodeGen;
|
90 | 92 | import com.oracle.graal.python.builtins.objects.PNone;
|
@@ -827,7 +829,6 @@ abstract static class PyTruffleGetInheritedNativeSlots extends NativeBuiltin {
|
827 | 829 | * custom slots at a time where the C API is not yet loaded. So we need to check if any of
|
828 | 830 | * the base classes defines custom slots and adapt the basicsize to allocate space for the
|
829 | 831 | * slots and add the native member slot descriptors.
|
830 |
| - * |
831 | 832 | */
|
832 | 833 | @Specialization
|
833 | 834 | Object slots(Object module, Object pythonClass, String subKey,
|
@@ -990,6 +991,31 @@ protected static boolean isPythonObjectNativeWrapper(Object object) {
|
990 | 991 | }
|
991 | 992 | }
|
992 | 993 |
|
| 994 | + // equivalent to result processing done in 'wrap_next' in 'Objects/typeobject.c' |
| 995 | + abstract static class CheckIterNextResultNode extends CheckFunctionResultNode { |
| 996 | + |
| 997 | + @Specialization(limit = "3") |
| 998 | + static Object doGeneric(String name, Object result, |
| 999 | + @CachedLibrary("result") InteropLibrary lib, |
| 1000 | + @CachedContext(PythonLanguage.class) ContextReference<PythonContext> contextRef, |
| 1001 | + @Cached PRaiseNode raiseNode) { |
| 1002 | + if (lib.isNull(result)) { |
| 1003 | + PythonContext context = contextRef.get(); |
| 1004 | + PException currentException = context.getCurrentException(); |
| 1005 | + // if no exception occurred, the iterator is exhausted -> raise StopIteration |
| 1006 | + if (currentException == null) { |
| 1007 | + throw raiseNode.raise(PythonBuiltinClassType.StopIteration); |
| 1008 | + } else { |
| 1009 | + // consume exception |
| 1010 | + context.setCurrentException(null); |
| 1011 | + // re-raise exception |
| 1012 | + throw currentException.getExceptionForReraise(); |
| 1013 | + } |
| 1014 | + } |
| 1015 | + return result; |
| 1016 | + } |
| 1017 | + } |
| 1018 | + |
993 | 1019 | @Builtin(name = "Py_NoValue")
|
994 | 1020 | @GenerateNodeFactory
|
995 | 1021 | abstract static class Py_NoValue extends PythonBuiltinNode {
|
@@ -2062,6 +2088,28 @@ protected MethGeNode() {
|
2062 | 2088 | }
|
2063 | 2089 | }
|
2064 | 2090 |
|
| 2091 | + @Builtin(name = "METH_ITERNEXT") |
| 2092 | + @GenerateNodeFactory |
| 2093 | + public abstract static class MethIterNextNode extends PythonBuiltinNode { |
| 2094 | + private static final PExternalFunctionWrapper METH_ITERNEXT_CONVERTER = new PExternalFunctionWrapper(AllToSulongNode::create, CheckIterNextResultNodeGen::create) { |
| 2095 | + |
| 2096 | + @Override |
| 2097 | + @TruffleBoundary |
| 2098 | + protected RootCallTarget createCallTarget(PythonLanguage language, String name, Object callable, boolean doArgAndResultConversion) { |
| 2099 | + if (!doArgAndResultConversion) { |
| 2100 | + return createCallTarget(new IterNextFuncRootNode(language, name, callable)); |
| 2101 | + } else { |
| 2102 | + return createCallTarget(new IterNextFuncRootNode(language, name, callable, this)); |
| 2103 | + } |
| 2104 | + } |
| 2105 | + }; |
| 2106 | + |
| 2107 | + @Specialization |
| 2108 | + static PExternalFunctionWrapper call() { |
| 2109 | + return METH_ITERNEXT_CONVERTER; |
| 2110 | + } |
| 2111 | + } |
| 2112 | + |
2065 | 2113 | @Builtin(name = "PyTruffle_Bytes_EmptyWithCapacity", minNumOfPositionalArgs = 1)
|
2066 | 2114 | @GenerateNodeFactory
|
2067 | 2115 | abstract static class PyTruffle_Bytes_EmptyWithCapacity extends PythonUnaryBuiltinNode {
|
|
0 commit comments