diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java index e8a5d6079d..77773c5ff6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ThreadModuleBuiltins.java @@ -208,10 +208,12 @@ long start(VirtualFrame frame, Object cls, Object callable, Object args, Object // TODO: python thread stack size != java thread stack size // ignore setting the stack size for the moment Thread thread = env.createThread(() -> { - Object[] arguments = getArgsNode.executeWith(frame, args); - PKeyword[] keywords = getKwArgsNode.execute(kwargs); - try (GilNode.UncachedAcquire gil = GilNode.uncachedAcquire()) { + // if args is an arbitrary iterable, converting it to an Object[] may run + // Python code + Object[] arguments = getArgsNode.executeWith(null, args); + PKeyword[] keywords = getKwArgsNode.execute(kwargs); + // the increment is protected by the gil DynamicObjectLibrary lib = DynamicObjectLibrary.getUncached(); int curCount = 0; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ManagedMethodWrappers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ManagedMethodWrappers.java index d213b13448..1862f28fd8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ManagedMethodWrappers.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/ManagedMethodWrappers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * The Universal Permissive License (UPL), Version 1.0 @@ -47,7 +47,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.ToPyObjectNode; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; -import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode; +import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; import com.oracle.graal.python.nodes.argument.positional.PositionalArgumentsNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.runtime.GilNode; @@ -128,7 +128,7 @@ public Object execute(Object[] arguments, @Exclusive @Cached ToJavaNode toJavaNode, @Exclusive @Cached CExtNodes.ToNewRefNode toSulongNode, @Exclusive @Cached CallNode callNode, - @Exclusive @Cached ExecutePositionalStarargsInteropNode posStarargsNode, + @Exclusive @Cached ExecutePositionalStarargsNode posStarargsNode, @Exclusive @Cached ExpandKeywordStarargsNode expandKwargsNode, @Exclusive @Cached GilNode gil) throws ArityException { boolean mustRelease = gil.acquire(); @@ -143,7 +143,7 @@ public Object execute(Object[] arguments, Object starArgs = toJavaNode.execute(arguments[1]); Object kwArgs = toJavaNode.execute(arguments[2]); - Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs); + Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray); PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java index 0d354c8bac..dbc37dd0de 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyDateTimeCAPIWrapper.java @@ -53,7 +53,6 @@ import static com.oracle.graal.python.util.PythonUtils.tsLiteral; import com.oracle.graal.python.builtins.PythonBuiltinClassType; -import com.oracle.graal.python.builtins.modules.cext.PythonCextAbstractBuiltins.PyMappingKeysNode; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AllToJavaNode; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.IsPointerNode; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.PCallCapiFunction; @@ -64,12 +63,11 @@ import com.oracle.graal.python.builtins.objects.cext.capi.DynamicObjectNativeWrapper.ToPyObjectNode; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.lib.PyObjectGetAttr; -import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSetAttr; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNodeGen; -import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNodeGen.ExecutePositionalStarargsInteropNodeGen; +import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNodeGen; import com.oracle.graal.python.nodes.call.special.CallVarargsMethodNode; import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.runtime.GilNode; @@ -547,18 +545,16 @@ protected Object execute(Object[] args, @Cached ToSulongNode toSulongNode, @Cached CallVarargsMethodNode callNode, @Cached AllToJavaNode allToJavaNode, - @Cached PyObjectGetItem getItemNode, - @Cached(allowUncached = true) PyMappingKeysNode keysNode, @Cached PyObjectLookupAttr lookupNode, @Cached CExtNodes.AddRefCntNode incRefNode, @Cached TransformExceptionToNativeNode transformExceptionToNativeNode, - @Exclusive @Cached GilNode gil) throws ArityException { + @Exclusive @Cached GilNode gil) { boolean mustRelease = gil.acquire(); try { Object[] convertedArgs = allToJavaNode.execute(args); Object type = convertedArgs[0]; - Object[] callArgs = ExecutePositionalStarargsInteropNodeGen.getUncached().executeWithGlobalState(convertedArgs[1]); + Object[] callArgs = ExecutePositionalStarargsNodeGen.getUncached().executeWith(null, convertedArgs[1]); PKeyword[] kwds; if (convertedArgs.length > 2) { kwds = ExpandKeywordStarargsNodeGen.getUncached().execute(convertedArgs[2]); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java index bd27ed8582..b1e12098a2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/PyProcsWrapper.java @@ -217,7 +217,7 @@ static class Execute { @Specialization(guards = "arguments.length == 3") static int init(InitWrapper self, Object[] arguments, @CachedLibrary("self") PythonNativeWrapperLibrary lib, - @Cached ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode posStarargsNode, + @Cached ExecutePositionalStarargsNode posStarargsNode, @Cached ExpandKeywordStarargsNode expandKwargsNode, @Cached CallVarargsMethodNode callNode, @Cached ToJavaNode toJavaNode, @@ -231,7 +231,7 @@ static int init(InitWrapper self, Object[] arguments, Object starArgs = toJavaNode.execute(arguments[1]); Object kwArgs = toJavaNode.execute(arguments[2]); - Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs); + Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray); PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs); callNode.execute(null, lib.getDelegate(self), pArgs, kwArgsArray); @@ -266,7 +266,7 @@ static class Execute { @Specialization(guards = "arguments.length == 3") static Object call(TernaryFunctionWrapper self, Object[] arguments, @CachedLibrary("self") PythonNativeWrapperLibrary lib, - @Cached ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode posStarargsNode, + @Cached ExecutePositionalStarargsNode posStarargsNode, @Cached ExpandKeywordStarargsNode expandKwargsNode, @Cached CallVarargsMethodNode callNode, @Cached ToJavaNode toJavaNode, @@ -281,7 +281,7 @@ static Object call(TernaryFunctionWrapper self, Object[] arguments, Object starArgs = toJavaNode.execute(arguments[1]); Object kwArgs = toJavaNode.execute(arguments[2]); - Object[] starArgsArray = posStarargsNode.executeWithGlobalState(starArgs); + Object[] starArgsArray = posStarargsNode.executeWith(null, starArgs); Object[] pArgs = PositionalArgumentsNode.prependArgument(receiver, starArgsArray); PKeyword[] kwArgsArray = expandKwargsNode.execute(kwArgs); Object result = callNode.execute(null, lib.getDelegate(self), pArgs, kwArgsArray); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java index b2262810a9..eb9350f6fe 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/hpy/GraalHPyContextFunctions.java @@ -179,7 +179,7 @@ import com.oracle.graal.python.nodes.SpecialMethodNames; import com.oracle.graal.python.nodes.WriteUnraisableNode; import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; -import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode.ExecutePositionalStarargsInteropNode; +import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; import com.oracle.graal.python.nodes.attributes.LookupCallableSlotInMRONode; import com.oracle.graal.python.nodes.attributes.LookupInheritedAttributeNode; import com.oracle.graal.python.nodes.attributes.ReadAttributeFromObjectNode; @@ -2736,7 +2736,7 @@ public static final class GraalHPyCallTupleDict extends GraalHPyContextFunction Object execute(Object[] arguments, @Cached HPyAsContextNode asContextNode, @Cached HPyAsPythonObjectNode asPythonObjectNode, - @Cached ExecutePositionalStarargsInteropNode expandArgsNode, + @Cached ExecutePositionalStarargsNode expandArgsNode, @Cached HashingCollectionNodes.LenNode lenNode, @Cached ExpandKeywordStarargsNode expandKwargsNode, @Cached HPyAsHandleNode asHandleNode, @@ -2764,14 +2764,14 @@ Object execute(Object[] arguments, } private static Object[] castArgs(Object args, - ExecutePositionalStarargsInteropNode expandArgsNode, + ExecutePositionalStarargsNode expandArgsNode, PRaiseNode raiseNode) { // this indicates that a NULL handle was passed (which is valid) if (args == PNone.NO_VALUE) { return PythonUtils.EMPTY_OBJECT_ARRAY; } if (PGuards.isPTuple(args)) { - return expandArgsNode.executeWithGlobalState(args); + return expandArgsNode.executeWith(null, args); } throw raiseNode.raise(TypeError, ErrorMessages.HPY_CALLTUPLEDICT_REQUIRES_ARGS_TUPLE_OR_NULL); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java index 3916f35672..7af62eb553 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/posix/DirEntryBuiltins.java @@ -78,10 +78,12 @@ import com.oracle.graal.python.runtime.PosixSupportLibrary; import com.oracle.graal.python.runtime.PosixSupportLibrary.PosixException; import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.profiles.ConditionProfile; @@ -237,7 +239,7 @@ static Object stat(VirtualFrame frame, PDirEntry self, boolean followSymlinks, } } - abstract static class StatHelperNode extends PythonBuiltinBaseNode { + abstract static class StatHelperSimpleNode extends PythonBuiltinBaseNode { abstract PTuple execute(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent); @@ -253,44 +255,60 @@ static PTuple cachedLStat(PDirEntry self, boolean followSymlinks, boolean catchN return self.lstatCache; } - @Specialization(guards = "self.getStatCache(followSymlinks) == null") - PTuple stat(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent, + @Specialization(guards = {"followSymlinks", "self.statCache == null", "isSymlink"}, limit = "1") + PTuple uncachedStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent, + @SuppressWarnings("unused") @Cached IsSymlinkNode isSymlinkNode, + @SuppressWarnings("unused") @Bind("isSymlinkNode.executeBoolean(frame, self)") boolean isSymlink, @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, - @Cached IsSymlinkNode isSymlinkNode, - @Cached StatHelperNode recursiveNode, - @Cached CachedPosixPathNode cachedPosixPathNode, - @Cached ConditionProfile positiveLongProfile, - @Cached ConditionProfile noSymlinkProfile) { - PTuple res; + @Shared("cachedPosixPathNode") @Cached CachedPosixPathNode cachedPosixPathNode, + @Shared("positiveLongProfile") @Cached ConditionProfile positiveLongProfile) { // There are two caches - one for `follow_symlinks=True` and the other for // 'follow_symlinks=False`. They are different only when the dir entry is a symlink. - // If it is not, they need to be the same, so we must make sure that fstatat() gets - // called only once. - if (noSymlinkProfile.profile(followSymlinks && !isSymlinkNode.execute(frame, self))) { - // The entry is not a symlink, so both stat caches need to have the - // same value. Also, the `follow_symlinks=False` cache might already be filled - // in. (In fact, the call to isSymlinkNode in the condition may fill it.) - // So we call ourselves recursively to either use or fill that cache first, and - // the `follow_symlinks=True` cache will be filled below. - res = recursiveNode.execute(frame, self, false, catchNoent); - } else { - int dirFd = self.scandirPath instanceof PosixFd ? ((PosixFd) self.scandirPath).fd : AT_FDCWD.value; - PosixPath posixPath = cachedPosixPathNode.execute(frame, self); - try { - long[] rawStat = posixLib.fstatat(getPosixSupport(), dirFd, posixPath.value, followSymlinks); - res = PosixModuleBuiltins.createStatResult(factory(), positiveLongProfile, rawStat); - } catch (PosixException e) { - if (catchNoent && e.getErrorCode() == OSErrorEnum.ENOENT.getNumber()) { - return null; - } - throw raiseOSErrorFromPosixException(frame, e, posixPath.originalObject); + return uncachedLStatWithSymlink(frame, self, followSymlinks, catchNoent, posixLib, cachedPosixPathNode, positiveLongProfile); + } + + @Specialization(guards = {"!followSymlinks", "self.lstatCache == null"}) + PTuple uncachedLStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent, + @CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib, + @Shared("cachedPosixPathNode") @Cached CachedPosixPathNode cachedPosixPathNode, + @Shared("positiveLongProfile") @Cached ConditionProfile positiveLongProfile) { + PTuple res; + int dirFd = self.scandirPath instanceof PosixFd ? ((PosixFd) self.scandirPath).fd : AT_FDCWD.value; + PosixPath posixPath = cachedPosixPathNode.execute(frame, self); + try { + long[] rawStat = posixLib.fstatat(getPosixSupport(), dirFd, posixPath.value, followSymlinks); + res = PosixModuleBuiltins.createStatResult(factory(), positiveLongProfile, rawStat); + } catch (PosixException e) { + if (catchNoent && e.getErrorCode() == OSErrorEnum.ENOENT.getNumber()) { + return null; } + throw raiseOSErrorFromPosixException(frame, e, posixPath.originalObject); } self.setStatCache(followSymlinks, res); return res; } } + abstract static class StatHelperNode extends StatHelperSimpleNode { + @Specialization(guards = {"followSymlinks", "self.statCache == null", "!isSymlink"}) + static PTuple uncachedStatWithSymlink(VirtualFrame frame, PDirEntry self, boolean followSymlinks, boolean catchNoent, + @SuppressWarnings("unused") @Cached IsSymlinkNode isSymlinkNode, + @SuppressWarnings("unused") @Bind("isSymlinkNode.executeBoolean(frame, self)") boolean isSymlink, + @Cached StatHelperSimpleNode recursiveNode) { + // There are two caches - one for `follow_symlinks=True` and the other for + // 'follow_symlinks=False`. They are different only when the dir entry is a symlink. + // If it is not, they need to be the same, so we must make sure that fstatat() gets + // called only once. The entry is not a symlink, so both stat caches need to have the + // same value. Also, the `follow_symlinks=False` cache might already be filled + // in. (In fact, the call to isSymlinkNode in the condition may fill it.) + // So we call ourselves recursively to either use or fill that cache first, and + // the `follow_symlinks=True` cache will be filled below. + PTuple res = recursiveNode.execute(frame, self, false, catchNoent); + self.setStatCache(followSymlinks, res); + return res; + } + } + abstract static class TestModeNode extends PythonBuiltinBaseNode { private final long expectedMode; @@ -355,7 +373,7 @@ static TestModeNode createDir() { @GenerateNodeFactory abstract static class IsSymlinkNode extends PythonUnaryBuiltinNode { - abstract boolean execute(VirtualFrame frame, PDirEntry self); + abstract boolean executeBoolean(VirtualFrame frame, PDirEntry self); @Specialization static boolean isSymlink(VirtualFrame frame, PDirEntry self, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java index ce64e35081..03e90d9b28 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringUtils.java @@ -248,6 +248,7 @@ public static Object[] toCharacterArray(TruffleString arg, TruffleString.CodePoi return values; } + @TruffleBoundary public static boolean isPrintable(int codepoint) { if (ImageInfo.inImageBuildtimeCode()) { // Executing ICU4J at image build time causes issues with runtime/build time diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java index 2e20ce28b2..4d39618ba6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/argument/positional/ExecutePositionalStarargsNode.java @@ -53,7 +53,6 @@ import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.control.GetNextNode; import com.oracle.graal.python.nodes.object.IsBuiltinClassProfile; @@ -165,66 +164,4 @@ public static ExecutePositionalStarargsNode create() { public static ExecutePositionalStarargsNode getUncached() { return ExecutePositionalStarargsNodeGen.getUncached(); } - - @GenerateUncached - @ImportStatic(PythonOptions.class) - public abstract static class ExecutePositionalStarargsInteropNode extends PNodeWithContext { - public abstract Object[] executeWithGlobalState(Object starargs); - - @Specialization - static Object[] starargs(Object[] starargs) { - return ExecutePositionalStarargsNode.doObjectArray(starargs); - } - - @Specialization - static Object[] doTuple(PTuple starargs, - @Exclusive @Cached SequenceStorageNodes.ToArrayNode toArray) { - return ExecutePositionalStarargsNode.doTuple(starargs, toArray); - } - - @Specialization - static Object[] doList(PList starargs, - @Exclusive @Cached SequenceStorageNodes.ToArrayNode toArray) { - return ExecutePositionalStarargsNode.doList(starargs, toArray); - } - - @Specialization - static Object[] doDict(PDict starargs, - @CachedLibrary(limit = "1") HashingStorageLibrary lib) { - return ExecutePositionalStarargsNode.doDict(starargs, lib); - } - - @Specialization - static Object[] doSet(PSet starargs, - @CachedLibrary(limit = "1") HashingStorageLibrary lib) { - return ExecutePositionalStarargsNode.doSet(starargs, lib); - } - - @Specialization - static Object[] starargs(PNone none, - @Cached PRaiseNode raise) { - return ExecutePositionalStarargsNode.doNone(none, raise); - } - - @Specialization - static Object[] starargs(Object object, - @Cached PRaiseNode raise, - @Cached PyObjectGetIter getIter, - @Cached GetNextNode nextNode, - @Cached IsBuiltinClassProfile errorProfile) { - Object iterator = getIter.execute(null, object); - if (iterator != PNone.NO_VALUE && iterator != PNone.NONE) { - ArrayList internalStorage = new ArrayList<>(); - while (true) { - try { - addToList(internalStorage, nextNode.execute(null, iterator)); - } catch (PException e) { - e.expectStopIteration(errorProfile); - return toArray(internalStorage); - } - } - } - throw raise.raise(PythonErrorType.TypeError, ErrorMessages.ARG_AFTER_MUST_BE_ITERABLE, object); - } - } }