diff --git a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_memoryview.py b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_memoryview.py index 200a1b92ee..89f59def6a 100644 --- a/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_memoryview.py +++ b/graalpython/com.oracle.graal.python.test/src/tests/cpyext/test_memoryview.py @@ -515,6 +515,13 @@ def test_memoryview_acquire_release(self): ) obj = TestType() assert obj.get_bufcount() == 0 + assert bytes(obj) == bytes([123, 124, 125, 126]) + assert obj.get_bufcount() == 0 + assert struct.unpack("4B", obj) == (123, 124, 125, 126) + assert obj.get_bufcount() == 0 + with self.assertRaises(struct.error): + struct.unpack("B", obj) + assert obj.get_bufcount() == 0 mv1 = memoryview(obj) assert mv1[3] == 126 assert obj.get_bufcount() == 1 diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java index 561fa5222b..014e71baa9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BinasciiModuleBuiltins.java @@ -62,9 +62,11 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.str.PString; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -75,8 +77,6 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -107,13 +107,11 @@ protected List> getNodeFa } abstract static class AsciiBufferConverter extends ArgumentCastNode { - @Specialization(guards = "acquireLib.hasBuffer(value)", limit = "getCallSiteInlineCacheMaxDepth()") + @Specialization(guards = "checkBufferNode.execute(value)", limit = "1") static Object doObject(VirtualFrame frame, Object value, - @Bind Node inliningTarget, - @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("value") PythonBufferAcquireLibrary acquireLib) { - return acquireLib.acquireReadonly(value, frame, context, context.getLanguage(inliningTarget), callData); + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer) { + return getBuffer.executeReadonly(frame, value); } @ExportLibrary(PythonBufferAccessLibrary.class) @@ -193,14 +191,14 @@ public static AsciiBufferConverter create() { abstract static class A2bBase64Node extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") PBytes doConvert(VirtualFrame frame, Object buffer, boolean strictMode, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Bind PythonLanguage language) { + @Bind PythonLanguage language, + @Cached PyBufferRelease releaseBuffer) { try { ByteSequenceStorage storage = b64decode(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), strictMode); return PFactory.createBytes(language, storage); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -278,14 +276,14 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class A2bHexNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") PBytes a2b(VirtualFrame frame, Object buffer, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Bind PythonLanguage language) { + @Bind PythonLanguage language, + @Cached PyBufferRelease releaseBuffer) { try { byte[] bytes = a2b(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer)); return PFactory.createBytes(language, bytes); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -342,13 +340,13 @@ private PBytes b2a(byte[] data, int lenght, boolean newline, PythonLanguage lang @Specialization(limit = "3") PBytes b2aBuffer(VirtualFrame frame, Object buffer, boolean newline, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Bind PythonLanguage language) { + @Bind PythonLanguage language, + @Cached PyBufferRelease releaseBuffer) { try { return b2a(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), newline, language); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -369,10 +367,10 @@ abstract static class B2aHexNode extends PythonTernaryClinicBuiltinNode { @Specialization(limit = "3") static PBytes b2a(VirtualFrame frame, Object buffer, Object sep, int bytesPerSep, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Bind PythonLanguage language, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { if (sep != PNone.NO_VALUE || bytesPerSep != 1) { // TODO implement sep and bytes_per_sep throw raiseNode.raise(inliningTarget, NotImplementedError); @@ -380,7 +378,7 @@ static PBytes b2a(VirtualFrame frame, Object buffer, Object sep, int bytesPerSep try { return b2a(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer), language); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -410,12 +408,12 @@ abstract static class Crc32Node extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") static long b2a(VirtualFrame frame, Object buffer, long crc, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) { + @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { try { return crc32(inliningTarget, (int) crc, bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -434,12 +432,12 @@ abstract static class CrcHqxNode extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") static long b2a(VirtualFrame frame, Object buffer, long crc, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) { + @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { try { return crcHqx(inliningTarget, (int) crc, bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java index 2eaeb899fc..7abf14f62a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/BuiltinFunctions.java @@ -128,7 +128,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.bytes.PBytes; @@ -171,6 +170,7 @@ import com.oracle.graal.python.compiler.ParserCallbacksImpl; import com.oracle.graal.python.compiler.bytecode_dsl.BytecodeDSLCompiler; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyEvalGetGlobals; @@ -192,6 +192,7 @@ import com.oracle.graal.python.lib.PyObjectFormat; import com.oracle.graal.python.lib.PyObjectGetAIter; import com.oracle.graal.python.lib.PyObjectGetAttrO; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectGetMethod; import com.oracle.graal.python.lib.PyObjectHashNode; @@ -269,7 +270,6 @@ import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.GilNode; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; @@ -1067,7 +1067,7 @@ Object compile(TruffleString expression, TruffleString filename, TruffleString m @Specialization(limit = "3") @SuppressWarnings("truffle-static-method") Object generic(VirtualFrame frame, Object wSource, Object wFilename, TruffleString mode, int flags, boolean dontInherit, int optimize, int featureVersion, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Bind PythonContext context, @Bind Node inliningTarget, @@ -1103,7 +1103,7 @@ Object generic(VirtualFrame frame, Object wSource, Object wFilename, TruffleStri RootCallTarget rootCallTarget = context.getLanguage(inliningTarget).compileModule(context, mod, source, false, optimize, null, null, flags); return wrapRootCallTarget(rootCallTarget, filename); } - TruffleString source = sourceAsString(frame, inliningTarget, wSource, filename, interopLib, acquireLib, bufferLib, switchEncodingNode, raiseNode); + TruffleString source = sourceAsString(frame, inliningTarget, wSource, filename, interopLib, getBuffer, bufferLib, switchEncodingNode, raiseNode); checkSource(source); return compile(source, filename, mode, flags, dontInherit, optimize, featureVersion); } finally { @@ -1167,7 +1167,7 @@ private InputType getParserInputType(TruffleString mode, int flags) { } // modeled after _Py_SourceAsString - TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object source, TruffleString filename, InteropLibrary interopLib, PythonBufferAcquireLibrary acquireLib, + TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object source, TruffleString filename, InteropLibrary interopLib, PyObjectGetBuffer getBuffer, PythonBufferAccessLibrary bufferLib, TruffleString.SwitchEncodingNode switchEncodingNode, PRaiseNode raiseNode) { if (interopLib.isString(source)) { try { @@ -1180,7 +1180,7 @@ TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object sou // buffers, since that's fast for us anyway Object buffer; try { - buffer = acquireLib.acquireReadonly(source, frame, InteropCallData.getUncached()); + buffer = getBuffer.executeReadonly(frame, source); } catch (PException e) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.ARG_D_MUST_BE_S, "compile()", 1, "string, bytes or AST object"); } @@ -1189,7 +1189,7 @@ TruffleString sourceAsString(VirtualFrame frame, Node inliningTarget, Object sou int bytesLen = bufferLib.getBufferLength(source); return doDecodeSource(getContext(), source, filename, bytes, bytesLen); } finally { - bufferLib.release(buffer, frame, InteropCallData.getUncached()); + PyBufferRelease.getUncached().execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java index 188e65f357..31e8006815 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/CodecsModuleBuiltins.java @@ -98,7 +98,6 @@ import com.oracle.graal.python.builtins.modules.codecs.ErrorHandlersFactory.CallDecodingErrorHandlerNodeGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.ByteArrayBuffer; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; @@ -106,7 +105,9 @@ import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalByteArrayNode; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyCallableCheckNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.lib.PyObjectTypeCheck; import com.oracle.graal.python.nodes.ErrorMessages; @@ -128,7 +129,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; @@ -241,7 +241,8 @@ byte[] encode(VirtualFrame frame, Object self, TruffleString encoding, TruffleSt @Cached TruffleString.ToJavaStringNode toJavaStringNode, @Cached TruffleString.EqualNode equalNode, @Cached ErrorHandlers.CallEncodingErrorHandlerNode errorHandler, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyBufferRelease releaseBuffer, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached CastToJavaStringNode castToJavaStringNode, @Cached PRaiseNode raiseNode, @@ -258,7 +259,8 @@ byte[] encode(VirtualFrame frame, Object self, TruffleString encoding, TruffleSt return ret; } } - return slowPath(frame, encoding, errors, inliningTarget, toJavaStringNode, equalNode, errorHandler, acquireLib, bufferLib, castToJavaStringNode, raiseNode, input, charsetWrapper); + return slowPath(frame, encoding, errors, inliningTarget, toJavaStringNode, equalNode, errorHandler, getBuffer, releaseBuffer, bufferLib, castToJavaStringNode, raiseNode, input, + charsetWrapper); } private static byte[] fastPath(TruffleString input, @@ -295,7 +297,8 @@ private byte[] slowPath(VirtualFrame frame, TruffleString encoding, TruffleStrin TruffleString.ToJavaStringNode toJavaStringNode, TruffleString.EqualNode equalNode, ErrorHandlers.CallEncodingErrorHandlerNode errorHandler, - PythonBufferAcquireLibrary acquireLib, + PyObjectGetBuffer getBuffer, + PyBufferRelease releaseBuffer, PythonBufferAccessLibrary bufferLib, CastToJavaStringNode castToJavaStringNode, PRaiseNode raiseNode, @@ -317,11 +320,11 @@ private byte[] slowPath(VirtualFrame frame, TruffleString encoding, TruffleStrin String replacementStr = castToJavaStringNode.execute(result.replacement); encoder.replace(replacementStr, charset); } else { - Object buffer = acquireLib.acquireReadonly(result.replacement); + Object buffer = getBuffer.executeReadonly(frame, result.replacement); try { encoder.replace(bufferLib.getInternalOrCopiedByteArray(buffer), 0, bufferLib.getBufferLength(buffer)); } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } } @@ -384,8 +387,7 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object decode(VirtualFrame frame, Object input, TruffleString encoding, TruffleString errors, boolean finalData, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached TruffleString.FromByteArrayNode fromByteArrayNode, @Cached TruffleString.IsValidNode isValidNode, @@ -393,8 +395,9 @@ static Object decode(VirtualFrame frame, Object input, TruffleString encoding, T @Cached InlinedConditionProfile fastPathProfile, @Cached(inline = true) CharsetLookupNode charsetLookupNode, @Cached("createFor($node)") BoundaryCallData boundaryCallData, - @Cached PRaiseNode raiseNode) { - Object buffer = acquireLib.acquireReadonly(input, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, input); try { int len = bufferLib.getBufferLength(buffer); byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); @@ -451,7 +454,7 @@ static Object decode(VirtualFrame frame, Object input, TruffleString encoding, T BoundaryCallContext.exit(frame, boundaryCallData, savedState); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -472,7 +475,7 @@ public static Object[] decodeSlowPath(Object input, TruffleString encoding, Truf ErrorHandlers.DecodingErrorHandlerResult result = CallDecodingErrorHandlerNodeGen.getUncached().execute(null, null, handlerCache, errors, encoding, input, pos, pos + decoder.getErrorLength(), decoder.getErrorReason()); if (result.newSrcObj != input) { - buffer = PythonBufferAcquireLibrary.getUncached().acquireReadonly(result.newSrcObj); + buffer = PyObjectGetBuffer.getUncached().executeReadonly(null, result.newSrcObj); releaseBuffer = true; bufferLib = PythonBufferAccessLibrary.getFactory().getUncached(buffer); decoder.setNewInput(bufferLib.getInternalOrCopiedByteArray(result.newSrcObj), 0, bufferLib.getBufferLength(result.newSrcObj), result.newPos); @@ -487,7 +490,7 @@ public static Object[] decodeSlowPath(Object input, TruffleString encoding, Truf return new Object[]{decoder.getString(), decoder.getInputPosition()}; } finally { if (releaseBuffer) { - bufferLib.release(buffer); + PyBufferRelease.getUncached().execute(null, buffer); } } } @@ -514,13 +517,13 @@ Object decodeByteArray(byte[] bytes, TruffleString errors, @Specialization(limit = "3") Object decode(VirtualFrame frame, Object buffer, TruffleString errors, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) { + @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); return decodeBytes(bufferLib.getInternalOrCopiedByteArray(buffer), len, errors, language); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -1316,20 +1319,20 @@ protected ArgumentClinicProvider getArgumentClinic() { return CodecsModuleBuiltinsClinicProviders.CharmapDecodeNodeClinicProviderGen.INSTANCE; } - @Specialization(limit = "3") + @Specialization Object doIt(VirtualFrame frame, Object data, TruffleString errors, Object mapping, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PyUnicodeDecodeCharmapNode pyUnicodeDecodeCharmapNode) { - Object dataBuffer = bufferAcquireLib.acquireReadonly(data, frame, context, context.getLanguage(inliningTarget), callData); + @Cached PyUnicodeDecodeCharmapNode pyUnicodeDecodeCharmapNode, + @Cached PyBufferRelease releaseBuffer) { + Object dataBuffer = getBuffer.executeReadonly(frame, data); int len; try { len = bufferLib.getBufferLength(dataBuffer); } finally { - bufferLib.release(dataBuffer, frame, callData); + releaseBuffer.execute(frame, dataBuffer); } TruffleString result = len == 0 ? T_EMPTY_STRING : pyUnicodeDecodeCharmapNode.execute(frame, data, errors, mapping); return PFactory.createTuple(context.getLanguage(inliningTarget), new Object[]{result, len}); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java index efd562580e..5aa3c42ac8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/FcntlModuleBuiltins.java @@ -64,9 +64,11 @@ import com.oracle.graal.python.builtins.modules.PosixModuleBuiltins.FileDescriptorConversionNode; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongAsLongNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; @@ -77,7 +79,6 @@ import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixConstants; import com.oracle.graal.python.runtime.PosixConstants.IntConstant; import com.oracle.graal.python.runtime.PosixSupport.PosixException; @@ -203,9 +204,9 @@ abstract static class IoctlNode extends PythonClinicBuiltinNode { Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutateArg, @Bind Node inliningTarget, @Bind PythonContext context, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached("createFor($node)") InteropCallData callData, @Cached PyLongAsIntNode asIntNode, @Cached CastToTruffleStringNode castToString, @Cached TruffleString.SwitchEncodingNode switchEncodingNode, @@ -213,21 +214,22 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat @Cached GilNode gilNode, @Cached PRaiseNode raiseNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached SysModuleBuiltins.AuditNode auditNode) { + @Cached SysModuleBuiltins.AuditNode auditNode, + @Cached PyBufferRelease releaseBuffer) { auditNode.audit(frame, inliningTarget, T_FCNT_IOCTL, fd, request, arg); int intArg = 0; if (arg != PNone.NO_VALUE) { Object buffer = null; // Buffer argument - if (acquireLib.hasBuffer(arg)) { + if (checkBufferNode.execute(arg)) { boolean writable = false; try { - buffer = acquireLib.acquireWritable(arg, frame, callData); + buffer = getBuffer.executeWritable(frame, arg); writable = true; } catch (PException e) { try { - buffer = acquireLib.acquireReadonly(arg, frame, callData); + buffer = getBuffer.executeReadonly(frame, arg); } catch (PException e1) { // ignore } @@ -270,7 +272,7 @@ Object ioctl(VirtualFrame frame, int fd, long request, Object arg, boolean mutat } } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java index d691dc79f4..6ce986ae58 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ImpModuleBuiltins.java @@ -93,6 +93,7 @@ import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.builtins.objects.str.StringNodes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyMemoryViewFromObject; import com.oracle.graal.python.lib.PyObjectGetAttr; import com.oracle.graal.python.lib.PyObjectLookupAttr; @@ -452,7 +453,8 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object run(TruffleString name, Object dataObj, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached PConstructAndRaiseNode.Lazy raiseNode) { + @Cached PConstructAndRaiseNode.Lazy raiseNode, + @Cached PyBufferRelease releaseBuffer) { FrozenInfo info; if (dataObj != PNone.NONE) { byte[] bytes; @@ -462,7 +464,7 @@ static Object run(TruffleString name, Object dataObj, bytes = bufferLib.getInternalOrCopiedByteArray(dataObj); size = bufferLib.getBufferLength(dataObj); } finally { - bufferLib.release(dataObj); + releaseBuffer.execute(null, dataObj); } if (size == 0) { /* Does not contain executable code. */ @@ -727,14 +729,15 @@ private static void raiseFrozenError(Node inliningTarget, PConstructAndRaiseNode @GenerateNodeFactory public abstract static class SourceHashNode extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "2") - static PBytes run(long magicNumber, Object sourceBuffer, + static PBytes run(VirtualFrame frame, long magicNumber, Object sourceBuffer, @CachedLibrary("sourceBuffer") PythonBufferAccessLibrary bufferLib, - @Bind PythonLanguage language) { + @Bind PythonLanguage language, + @Cached PyBufferRelease releaseBuffer) { try { byte[] hash = hashSource(magicNumber, bufferLib.getInternalOrCopiedByteArray(sourceBuffer), bufferLib.getBufferLength(sourceBuffer)); return PFactory.createBytes(language, hash); } finally { - bufferLib.release(sourceBuffer); + releaseBuffer.execute(frame, sourceBuffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java index ae410da54a..d9975c0a94 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/JavaModuleBuiltins.java @@ -56,11 +56,12 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; @@ -72,7 +73,6 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PythonErrorType; import com.oracle.graal.python.runtime.interop.InteropByteArray; @@ -285,16 +285,16 @@ static Object doBytesByteStorage(PBytesLike object) { return new PUnsignedBytesWrapper(object); } - @Specialization(guards = "!isBytes(object)", limit = "3") + @Specialization(guards = "!isBytes(object)") static Object doBuffer(VirtualFrame frame, Object object, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("object") PythonBufferAcquireLibrary acquireLib, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { - Object buffer = acquireLib.acquireReadonly(object, frame, callData); + @Cached PyObjectGetBuffer getBuffer, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, object); try { return new InteropByteArray(bufferLib.getCopiedByteArray(object)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java index 14b8795283..31b88126bd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/MarshalModuleBuiltins.java @@ -75,7 +75,6 @@ import com.oracle.graal.python.builtins.modules.MarshalModuleBuiltinsClinicProviders.DumpsNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.code.PCode; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; @@ -100,6 +99,7 @@ import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes.IsInternedStringNode; import com.oracle.graal.python.builtins.objects.type.TypeNodes.IsSameTypeNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyComplexCheckExactNode; import com.oracle.graal.python.lib.PyDictCheckExactNode; import com.oracle.graal.python.lib.PyFloatCheckExactNode; @@ -108,6 +108,8 @@ import com.oracle.graal.python.lib.PyLongCheckExactNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PySetCheckExactNode; import com.oracle.graal.python.lib.PyTupleCheckExactNode; import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; @@ -125,7 +127,6 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.object.PFactory; @@ -257,11 +258,11 @@ static Object doit(VirtualFrame frame, Object file, boolean allowCode, @Bind Node inliningTarget, @Bind PythonContext context, @Cached("createCallReadNode()") LookupAndCallBinaryNode callNode, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferLib, + @Cached PyObjectCheckBuffer checkBufferNode, @Cached PRaiseNode raiseNode) { PythonLanguage language = context.getLanguage(inliningTarget); Object buffer = callNode.executeObject(frame, file, 0); - if (!bufferLib.hasBuffer(buffer)) { + if (!checkBufferNode.execute(buffer)) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.READ_RETURNED_NOT_BYTES, buffer); } try { @@ -284,9 +285,9 @@ abstract static class LoadsNode extends PythonBinaryClinicBuiltinNode { static Object doit(VirtualFrame frame, Object buffer, boolean allowCode, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { PythonLanguage language = context.getLanguage(inliningTarget); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); @@ -301,7 +302,7 @@ static Object doit(VirtualFrame frame, Object buffer, boolean allowCode, } catch (Marshal.MarshalError me) { throw raiseNode.raise(inliningTarget, me.type, me.message, me.arguments); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -978,17 +979,16 @@ private void writeComplexObject(Object v, int flag) { writeByte(TYPE_DSL_SOURCE | flag); writeSource(s); } else { - PythonBufferAcquireLibrary acquireLib = PythonBufferAcquireLibrary.getFactory().getUncached(v); - if (acquireLib.hasBuffer(v)) { + if (PyObjectCheckBuffer.executeUncached(v)) { writeByte(TYPE_STRING | flag); - Object buf = acquireLib.acquireReadonly(v); + Object buf = PyObjectGetBuffer.getUncached().executeReadonly(null, v); PythonBufferAccessLibrary accessLib = PythonBufferAccessLibrary.getFactory().getUncached(buf); try { int len = accessLib.getBufferLength(buf); writeSize(len); out.write(accessLib.getInternalOrCopiedByteArray(buf), 0, len); } finally { - accessLib.release(buf); + PyBufferRelease.getUncached().execute(null, buf); } } else { writeByte(TYPE_UNKNOWN); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java index 935eaf2fa2..2ff09ca324 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/OperatorModuleBuiltins.java @@ -51,9 +51,9 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.iterator.IteratorNodes.GetLength; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyNumberAbsoluteNode; import com.oracle.graal.python.lib.PyNumberAddNode; import com.oracle.graal.python.lib.PyNumberAndNode; @@ -85,7 +85,9 @@ import com.oracle.graal.python.lib.PyNumberSubtractNode; import com.oracle.graal.python.lib.PyNumberTrueDivideNode; import com.oracle.graal.python.lib.PyNumberXorNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; import com.oracle.graal.python.lib.PyObjectDelItem; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectRichCompare; @@ -108,8 +110,6 @@ import com.oracle.graal.python.nodes.object.IsNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; -import com.oracle.graal.python.runtime.ExecutionContext.InteropCallContext; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -666,31 +666,30 @@ abstract static class CompareDigestNode extends PythonBinaryBuiltinNode { @Specialization static boolean compare(VirtualFrame frame, Object left, Object right, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @Cached CastToJavaStringNode cast, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { String leftString = cast.execute(left); String rightString = cast.execute(right); return tscmp(leftString, rightString); } catch (CannotCastException e) { - if (!bufferAcquireLib.hasBuffer(left) || !bufferAcquireLib.hasBuffer(right)) { + if (!checkBufferNode.execute(left) || !checkBufferNode.execute(right)) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, left, right); } - Object savedState = InteropCallContext.enter(frame, inliningTarget, callData); - Object leftBuffer = bufferAcquireLib.acquireReadonly(left); + Object leftBuffer = getBuffer.executeReadonly(frame, left); try { - Object rightBuffer = bufferAcquireLib.acquireReadonly(right); + Object rightBuffer = getBuffer.executeReadonly(frame, right); try { return tscmp(bufferLib.getCopiedByteArray(leftBuffer), bufferLib.getCopiedByteArray(rightBuffer)); } finally { - bufferLib.release(rightBuffer); + releaseBuffer.execute(frame, rightBuffer); } } finally { - bufferLib.release(leftBuffer); - InteropCallContext.exit(frame, inliningTarget, callData, savedState); + releaseBuffer.execute(frame, leftBuffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java index 844cd7cdd1..8b15d52df6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/PosixModuleBuiltins.java @@ -84,6 +84,7 @@ import com.oracle.graal.python.builtins.objects.posix.PScandirIterator; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.tuple.StructSequence; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongAsLongAndOverflowNode; @@ -122,7 +123,6 @@ import com.oracle.graal.python.nodes.util.PosixSupportNodes; import com.oracle.graal.python.nodes.util.PosixSupportNodes.DecodeFilesystemStringNode; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixConstants; import com.oracle.graal.python.runtime.PosixConstants.IntConstant; import com.oracle.graal.python.runtime.PosixSupport; @@ -1008,18 +1008,18 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(limit = "3") static long doWrite(VirtualFrame frame, int fd, Object dataBuffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("dataBuffer") PythonBufferAccessLibrary bufferLib, @Bind PythonContext context, @Cached InlinedBranchProfile errorProfile, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, + @Cached PyBufferRelease releaseBuffer) { try { return write(fd, bufferLib.getInternalOrCopiedByteArray(dataBuffer), bufferLib.getBufferLength(dataBuffer), inliningTarget, context.getPosixSupport(), errorProfile, gil); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { - bufferLib.release(dataBuffer, frame, callData); + releaseBuffer.execute(frame, dataBuffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java index 1d1c13f7fc..1a46b7f817 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/SocketModuleBuiltins.java @@ -77,7 +77,6 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; @@ -87,8 +86,10 @@ import com.oracle.graal.python.builtins.objects.socket.SocketNodes; import com.oracle.graal.python.builtins.objects.socket.SocketNodes.IdnaFromStringOrBytesConverterNode; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongAsLongNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyTupleCheckNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; @@ -107,7 +108,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.nodes.util.PosixSupportNodes; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixConstants; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupport.AddrInfoCursor; @@ -835,16 +835,16 @@ protected ArgumentClinicProvider getArgumentClinic() { @Builtin(name = "inet_ntoa", minNumOfPositionalArgs = 1) @GenerateNodeFactory abstract static class InetNtoANode extends PythonUnaryBuiltinNode { - @Specialization(limit = "3") + @Specialization static TruffleString doGeneric(VirtualFrame frame, Object addr, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("addr") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Bind PythonContext context, @Cached PosixSupportNodes.GetCStringAsStringNode getCStringAsStringNode, - @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireReadonly(addr, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, addr); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); @@ -855,7 +855,7 @@ static TruffleString doGeneric(VirtualFrame frame, Object addr, Object result = posixSupport.inet_ntoa(ByteArraySupport.bigEndian().getInt(bytes, 0)); return getCStringAsStringNode.execute(inliningTarget, posixSupport, result); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } @@ -893,17 +893,17 @@ protected ArgumentClinicProvider getArgumentClinic() { @ArgumentClinic(name = "family", conversion = ArgumentClinic.ClinicConversion.Int) @GenerateNodeFactory abstract static class InetNtoPNode extends PythonBinaryClinicBuiltinNode { - @Specialization(limit = "3") + @Specialization static TruffleString doGeneric(VirtualFrame frame, int family, Object obj, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("obj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Bind PythonContext context, @Cached PosixSupportNodes.GetCStringAsStringNode getCStringAsStringNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireReadonly(obj, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, obj); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); @@ -926,7 +926,7 @@ static TruffleString doGeneric(VirtualFrame frame, int family, Object obj, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java index ab1295864d..dd482bc39f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ast/Obj2SstBase.java @@ -59,7 +59,6 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.complex.PComplex; @@ -70,6 +69,7 @@ import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.type.PythonAbstractClass; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckExactNode; import com.oracle.graal.python.lib.PyComplexCheckExactNode; import com.oracle.graal.python.lib.PyEnterRecursiveCallNode; @@ -78,6 +78,7 @@ import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongCheckNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; @@ -94,8 +95,8 @@ import com.oracle.graal.python.runtime.PythonContext.PythonThreadState; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; -import com.oracle.truffle.api.nodes.Node; import com.oracle.graal.python.util.PythonUtils; +import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.strings.TruffleString; abstract class Obj2SstBase { @@ -230,13 +231,12 @@ Object obj2string(Object obj) { return null; } if (PyBytesCheckExactNode.executeUncached(obj)) { - PythonBufferAcquireLibrary acquireLib = PythonBufferAcquireLibrary.getUncached(); PythonBufferAccessLibrary accessLib = PythonBufferAccessLibrary.getUncached(); - Object buf = acquireLib.acquireReadonly(obj); + Object buf = PyObjectGetBuffer.getUncached().executeReadonly(null, obj); try { return accessLib.getCopiedByteArray(buf); } finally { - accessLib.release(buf); + PyBufferRelease.getUncached().execute(null, buf); } } if (PyUnicodeCheckExactNode.executeUncached(obj)) { @@ -301,12 +301,12 @@ ConstantValue obj2ConstantValue(Object obj) { return ConstantValue.ofCodePoints(PythonUtils.truffleStringToCodePoints(ps.getValueUncached())); } if (obj instanceof PBytes && PyBytesCheckExactNode.executeUncached(obj)) { - Object buf = PythonBufferAcquireLibrary.getUncached().acquireReadonly(obj); + Object buf = PyObjectGetBuffer.getUncached().executeReadonly(null, obj); PythonBufferAccessLibrary accessLib = PythonBufferAccessLibrary.getFactory().getUncached(buf); try { return ConstantValue.ofBytes(accessLib.getCopiedByteArray(buf)); } finally { - accessLib.release(buf); + PyBufferRelease.getUncached().execute(null, buf); } } boolean isTuple = PyTupleCheckExactNode.executeUncached(obj); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java index 584f6c5fb3..210d3d4efb 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/CharmapNodes.java @@ -64,14 +64,15 @@ import com.oracle.graal.python.builtins.modules.codecs.ErrorHandlers.RaiseEncodeException; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.common.HashingStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageSetItem; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyLongCheckNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyUnicodeCheckExactNode; import com.oracle.graal.python.lib.PyUnicodeCheckNode; @@ -80,8 +81,6 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.ByteArrayBuilder; @@ -362,31 +361,27 @@ public abstract static class PyUnicodeDecodeCharmapNode extends PNodeWithContext public abstract TruffleString execute(VirtualFrame frame, Object data, TruffleString errors, Object mapping); - @Specialization(limit = "3") + @Specialization static TruffleString decodeLatin1(VirtualFrame frame, Object data, @SuppressWarnings("unused") TruffleString errors, @SuppressWarnings("unused") PNone mapping, - @Bind Node inliningTarget, - @Bind PythonContext context, - @Shared @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib, + @Shared @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") @Shared PythonBufferAccessLibrary bufferLib, @Cached TruffleString.FromByteArrayWithCompactionUTF32Node fromByteArrayNode, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { + @Shared @Cached PyBufferRelease releaseBuffer) { // equivalent of PyUnicode_DecodeLatin1 - Object dataBuffer = bufferAcquireLib.acquireReadonly(data, frame, context, context.getLanguage(inliningTarget), callData); + Object dataBuffer = getBuffer.executeReadonly(frame, data); try { int len = bufferLib.getBufferLength(dataBuffer); byte[] src = bufferLib.getInternalOrCopiedByteArray(dataBuffer); return fromByteArrayNode.execute(src, 0, len, TruffleString.CompactionLevel.S1, true); } finally { - bufferLib.release(dataBuffer, frame, callData); + releaseBuffer.execute(frame, dataBuffer); } } @Specialization(limit = "3", guards = "isBuiltinString.execute(inliningTarget, mappingObj)") static TruffleString decodeStringMapping(VirtualFrame frame, Object data, TruffleString errors, Object mappingObj, @Bind Node inliningTarget, - @Shared @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib, + @Shared @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") @Shared PythonBufferAccessLibrary bufferLib, @SuppressWarnings("unused") @Cached @Exclusive PyUnicodeCheckExactNode isBuiltinString, @Cached @Exclusive CastToTruffleStringNode castToTruffleStringNode, @@ -395,10 +390,9 @@ static TruffleString decodeStringMapping(VirtualFrame frame, Object data, Truffl @Cached @Shared TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached @Shared TruffleStringBuilder.AppendStringNode appendStringNode, @Cached @Shared TruffleStringBuilder.ToStringNode toStringNode, - @Cached @Exclusive CallDecodingErrorHandlerNode callErrorHandlerNode) { + @Cached @Exclusive CallDecodingErrorHandlerNode callErrorHandlerNode, + @Shared @Cached PyBufferRelease releaseBuffer) { // equivalent of charmap_decode_string - PythonContext context = PythonContext.get(inliningTarget); - PythonLanguage language = context.getLanguage(inliningTarget); ErrorHandlerCache cache = new ErrorHandlerCache(); Object srcObj = data; @@ -409,7 +403,7 @@ static TruffleString decodeStringMapping(VirtualFrame frame, Object data, Truffl int errorStartPos; int srcLen; do { - Object srcBuf = bufferAcquireLib.acquireReadonly(srcObj, frame, context, language, callData); + Object srcBuf = getBuffer.executeReadonly(frame, srcObj); try { srcLen = bufferLib.getBufferLength(srcBuf); byte[] src = bufferLib.getInternalOrCopiedByteArray(srcBuf); @@ -428,7 +422,7 @@ static TruffleString decodeStringMapping(VirtualFrame frame, Object data, Truffl appendCodePointNode.execute(tsb, cp, 1, true); } } finally { - bufferLib.release(srcBuf, frame, context, language, callData); + releaseBuffer.execute(frame, srcBuf); } if (errorStartPos != -1) { DecodingErrorHandlerResult result = callErrorHandlerNode.execute(frame, inliningTarget, cache, errors, T_CHARMAP, srcObj, errorStartPos, errorStartPos + 1, @@ -444,8 +438,7 @@ static TruffleString decodeStringMapping(VirtualFrame frame, Object data, Truffl @Specialization(limit = "3", guards = {"!isBuiltinString.execute(inliningTarget, mappingObj)", "!isPNone(mappingObj)"}) static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, TruffleString errors, Object mappingObj, @Bind Node inliningTarget, - @Shared @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib, + @Shared @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") @Shared PythonBufferAccessLibrary bufferLib, @SuppressWarnings("unused") @Cached @Exclusive PyUnicodeCheckExactNode isBuiltinString, @Cached PyObjectGetItem pyObjectGetItemNode, @@ -463,10 +456,9 @@ static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, Truff @Cached InlinedConditionProfile longValuesProfile, @Cached InlinedConditionProfile strValuesProfile, @Cached InlinedConditionProfile errProfile, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Shared @Cached PyBufferRelease releaseBuffer) { // equivalent of charmap_decode_mapping - PythonContext context = PythonContext.get(inliningTarget); - PythonLanguage language = context.getLanguage(inliningTarget); ErrorHandlerCache cache = new ErrorHandlerCache(); Object srcObj = data; @@ -475,7 +467,7 @@ static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, Truff int errorStartPos; int srcLen; do { - Object srcBuf = bufferAcquireLib.acquireReadonly(srcObj, frame, context, language, callData); + Object srcBuf = getBuffer.executeReadonly(frame, srcObj); try { srcLen = bufferLib.getBufferLength(srcBuf); byte[] src = bufferLib.getInternalOrCopiedByteArray(srcBuf); @@ -522,7 +514,7 @@ static TruffleString decodeGenericMapping(VirtualFrame frame, Object data, Truff } } } finally { - bufferLib.release(srcBuf, frame, context, language, callData); + releaseBuffer.execute(frame, srcBuf); } if (errProfile.profile(inliningTarget, errorStartPos != -1)) { DecodingErrorHandlerResult result = callErrorHandlerNode.execute(frame, inliningTarget, cache, errors, T_CHARMAP, srcObj, errorStartPos, errorStartPos + 1, diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java index f8c85b8a89..386fc00565 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/codecs/ErrorHandlers.java @@ -66,7 +66,6 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.modules.codecs.CodecsRegistry.PyCodecLookupErrorNode; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesUtils; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.exception.PBaseException; @@ -81,8 +80,10 @@ import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetObjectNode; import com.oracle.graal.python.builtins.objects.exception.UnicodeEncodeErrorBuiltins.PyUnicodeEncodeOrTranslateErrorGetStartNode; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked0Node; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.lib.PyObjectTypeCheck; import com.oracle.graal.python.lib.PyTupleCheckNode; @@ -93,7 +94,6 @@ import com.oracle.graal.python.nodes.builtins.TupleNodes.GetTupleStorage; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; @@ -404,14 +404,14 @@ abstract static class BackslashReplaceErrorHandlerNode extends ErrorHandlerBaseN static Object doDecodeException(VirtualFrame frame, PBaseException exception, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @SuppressWarnings("unused") @Cached @Exclusive PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @Cached PyUnicodeDecodeErrorGetStartNode getStartNode, @Cached PyUnicodeDecodeErrorGetEndNode getEndNode, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, - @Cached @Shared TruffleString.FromByteArrayWithCompactionUTF32Node fromByteArrayNode) { + @Cached @Shared TruffleString.FromByteArrayWithCompactionUTF32Node fromByteArrayNode, + @Cached PyBufferRelease releaseBuffer) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); Object object = getObjectNode.execute(inliningTarget, exception); @@ -420,7 +420,7 @@ static Object doDecodeException(VirtualFrame frame, PBaseException exception, } byte[] replacement = new byte[4 * (end - start)]; int pos = 0; - Object srcBuf = acquireLib.acquireReadonly(object, frame, callData); + Object srcBuf = getBuffer.executeReadonly(frame, object); try { byte[] src = accessLib.getInternalOrCopiedByteArray(srcBuf); for (int i = start; i < end; i++) { @@ -428,7 +428,7 @@ static Object doDecodeException(VirtualFrame frame, PBaseException exception, } LoopNode.reportLoopCount(inliningTarget, (int) Math.min(Integer.MAX_VALUE, Math.max(0L, (long) end - start))); } finally { - accessLib.release(srcBuf, frame, callData); + releaseBuffer.execute(frame, srcBuf); } TruffleString resultAscii = fromByteArrayNode.execute(replacement, 0, replacement.length, TruffleString.CompactionLevel.S1, false); return PFactory.createTuple(language, new Object[]{resultAscii, end}); @@ -578,17 +578,17 @@ static Object doEncode(PBaseException exception, static Object doDecode(VirtualFrame frame, PBaseException exception, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @SuppressWarnings("unused") @Exclusive @Cached PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @Cached PyUnicodeDecodeErrorGetStartNode getStartNode, @Cached PyUnicodeDecodeErrorGetEndNode getEndNode, @Cached PyUnicodeDecodeErrorGetEncodingNode getEncodingNode, @Exclusive @Cached GetStandardEncodingNode getStandardEncodingNode, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached TruffleString.FromCodePointNode fromCodePointNode, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { int start = getStartNode.execute(inliningTarget, exception); getEndNode.execute(inliningTarget, exception); // called for side effects only Object object = getObjectNode.execute(inliningTarget, exception); @@ -597,7 +597,7 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, if (encoding == StandardEncoding.UNKNOWN) { throw raiseNode.raiseExceptionObject(inliningTarget, exception); } - Object srcBuf = acquireLib.acquireReadonly(object, frame, callData); + Object srcBuf = getBuffer.executeReadonly(frame, object); try { int cp = 0; int srcLen = accessLib.getBufferLength(srcBuf); @@ -609,7 +609,7 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, } return PFactory.createTuple(language, new Object[]{fromCodePointNode.execute(cp, TS_ENCODING, true), start + encoding.byteLength}); } finally { - accessLib.release(srcBuf, frame, callData); + releaseBuffer.execute(frame, srcBuf); } } @@ -707,20 +707,20 @@ static Object doEncode(PBaseException exception, static Object doDecode(VirtualFrame frame, PBaseException exception, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @SuppressWarnings("unused") @Exclusive @Cached PyObjectTypeCheck pyObjectTypeCheck, @Cached PyUnicodeDecodeErrorGetObjectNode getObjectNode, @Cached PyUnicodeDecodeErrorGetStartNode getStartNode, @Cached PyUnicodeDecodeErrorGetEndNode getEndNode, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached TruffleStringBuilder.AppendCodePointNode appendCodePointNode, @Cached TruffleStringBuilder.ToStringNode toStringNode, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { int start = getStartNode.execute(inliningTarget, exception); int end = getEndNode.execute(inliningTarget, exception); Object object = getObjectNode.execute(inliningTarget, exception); - Object srcBuf = acquireLib.acquireReadonly(object, frame, callData); + Object srcBuf = getBuffer.executeReadonly(frame, object); TruffleStringBuilderUTF32 tsb = TruffleStringBuilder.createUTF32(); try { byte[] src = accessLib.getInternalOrCopiedByteArray(srcBuf); @@ -738,7 +738,7 @@ static Object doDecode(VirtualFrame frame, PBaseException exception, } return PFactory.createTuple(language, new Object[]{toStringNode.execute(tsb), start + consumed}); } finally { - accessLib.release(srcBuf, frame, callData); + releaseBuffer.execute(frame, srcBuf); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java index e219178296..3235bb8bb4 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/DigestObjectBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2026, 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 @@ -53,13 +53,13 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -133,16 +133,16 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(limit = "3") static PNone update(VirtualFrame frame, DigestObject self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { if (self.wasReset()) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, ErrorMessages.UPDATING_FINALIZED_DIGEST_IS_NOT_SUPPORTED); } try { self.update(bufferLib.getInternalOrCopiedByteArray(buffer), bufferLib.getBufferLength(buffer)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } return PNone.NONE; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java index 9145cf4318..4179ab4043 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/hashlib/HashlibModuleBuiltins.java @@ -65,7 +65,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; - import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; @@ -80,11 +79,13 @@ import com.oracle.graal.python.builtins.modules.hashlib.HashlibModuleBuiltinsClinicProviders.Pbkdf2HmacNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.common.EconomicMapStorage; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsLongNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; @@ -98,7 +99,6 @@ import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.crypto.BouncyCastleSupportProvider; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -220,23 +220,24 @@ static Object cmpStrings(Object a, Object b, @Specialization(guards = {"!isString(a) || !isString(b)"}) static boolean cmpBuffers(VirtualFrame frame, Object a, Object b, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary accessLib, - @Exclusive @Cached PRaiseNode raiseNode) { - if (acquireLib.hasBuffer(a) && acquireLib.hasBuffer(b)) { - Object bufferA = acquireLib.acquireReadonly(a, frame, callData); + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + if (checkBufferNode.execute(a) && checkBufferNode.execute(b)) { + Object bufferA = getBuffer.executeReadonly(frame, a); try { - Object bufferB = acquireLib.acquireReadonly(b, frame, callData); + Object bufferB = getBuffer.executeReadonly(frame, b); try { byte[] bytesA = accessLib.getInternalOrCopiedByteArray(bufferA); byte[] bytesB = accessLib.getInternalOrCopiedByteArray(bufferB); return cmp(bytesA, bytesB); } finally { - accessLib.release(bufferB, frame, callData); + releaseBuffer.execute(frame, bufferB); } } finally { - accessLib.release(bufferA, frame, callData); + releaseBuffer.execute(frame, bufferA); } } else { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.UNSUPPORTED_OPERAND_TYPES_OR_COMBINATION_OF_TYPES, a, b); @@ -286,42 +287,46 @@ static Object hmacNewFromFunction(VirtualFrame frame, PythonModule self, Object @Exclusive @Cached CastToTruffleStringNode castStr, @Exclusive @Cached CastToJavaStringNode castJStr, @Shared("concatStr") @Cached TruffleString.ConcatNode concatStr, - @Shared("acquireLib") @CachedLibrary(limit = "2") PythonBufferAcquireLibrary acquireLib, + @Shared("checkBuffer") @Cached PyObjectCheckBuffer checkBufferNode, + @Shared("getBuffer") @Cached PyObjectGetBuffer getBuffer, @Shared("bufferLib") @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Shared @Cached PyBufferRelease releaseBuffer) { // cast guaranteed in our initialize EconomicMapStorage constructors = self.getModuleState(EconomicMapStorage.class); Object name = getItemNode.execute(frame, inliningTarget, constructors, digestmod); if (name != null) { assert name instanceof TruffleString; // guaranteed in our initialize - return hmacNew(self, key, msg, name, inliningTarget, castStr, castJStr, concatStr, acquireLib, bufferLib, raiseNode); + return hmacNew(frame, self, key, msg, name, inliningTarget, castStr, castJStr, concatStr, checkBufferNode, getBuffer, bufferLib, raiseNode, releaseBuffer); } else { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError); } } @Specialization(guards = "isString(digestmodObj)") - static Object hmacNew(@SuppressWarnings("unused") PythonModule self, Object keyObj, Object msgObj, Object digestmodObj, + static Object hmacNew(VirtualFrame frame, @SuppressWarnings("unused") PythonModule self, Object keyObj, Object msgObj, Object digestmodObj, @Bind Node inliningTarget, @Exclusive @Cached CastToTruffleStringNode castStr, @Exclusive @Cached CastToJavaStringNode castJStr, @Shared("concatStr") @Cached TruffleString.ConcatNode concatStr, - @Shared("acquireLib") @CachedLibrary(limit = "2") PythonBufferAcquireLibrary acquireLib, + @Shared("checkBuffer") @Cached PyObjectCheckBuffer checkBufferNode, + @Shared("getBuffer") @Cached PyObjectGetBuffer getBuffer, @Shared("bufferLib") @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Shared @Cached PyBufferRelease releaseBuffer) { TruffleString digestmod = castStr.execute(inliningTarget, digestmodObj); Object key; - if (!acquireLib.hasBuffer(keyObj)) { + if (!checkBufferNode.execute(keyObj)) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, keyObj); } else { - key = acquireLib.acquireReadonly(keyObj); + key = getBuffer.executeReadonly(frame, keyObj); } try { Object msg; if (msgObj instanceof PNone) { msg = null; - } else if (acquireLib.hasBuffer(msgObj)) { - msg = acquireLib.acquireReadonly(msgObj); + } else if (checkBufferNode.execute(msgObj)) { + msg = getBuffer.executeReadonly(frame, msgObj); } else { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, msgObj); } @@ -335,11 +340,11 @@ static Object hmacNew(@SuppressWarnings("unused") PythonModule self, Object keyO throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, e); } finally { if (msg != null) { - bufferLib.release(msg); + releaseBuffer.execute(frame, msg); } } } finally { - bufferLib.release(key); + releaseBuffer.execute(frame, key); } } } @@ -367,15 +372,16 @@ abstract static class CreateDigestNode extends Node { @Specialization static Object doIt(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassType type, String pythonName, String javaName, Object value, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "2") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raise) { + @Cached PRaiseNode raise, + @Cached PyBufferRelease releaseBuffer) { Object buffer; if (value == PNone.NO_VALUE) { buffer = null; - } else if (acquireLib.hasBuffer(value)) { - buffer = acquireLib.acquireReadonly(value, frame, callData); + } else if (checkBufferNode.execute(value)) { + buffer = getBuffer.executeReadonly(frame, value); } else { throw raise.raise(inliningTarget, PythonBuiltinClassType.TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, value); } @@ -391,7 +397,7 @@ static Object doIt(VirtualFrame frame, Node inliningTarget, PythonBuiltinClassTy return PFactory.createDigestObject(PythonLanguage.get(inliningTarget), type, pythonName, digest); } finally { if (buffer != null) { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } @@ -506,7 +512,8 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password @Cached PyLongAsLongNode asLongNode, @Cached InlinedConditionProfile noDklenProfile, @Cached TruffleString.ToJavaStringNode toJavaStringNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { String javaHashName = toJavaStringNode.execute(hashName); if (iterations < 1) { @@ -533,8 +540,8 @@ static Object pbkdf2(VirtualFrame frame, TruffleString hashName, Object password } catch (GeneralSecurityException e) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.UnsupportedDigestmodError, UNSUPPORTED_HASH_TYPE, hashName); } finally { - passwordLib.release(password); - saltLib.release(salt); + releaseBuffer.execute(frame, password); + releaseBuffer.execute(frame, salt); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java index 7bb34a012a..3cd0efd47c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedIOBaseBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -64,13 +64,13 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -148,12 +148,12 @@ protected TruffleString getMethodName() { @Specialization Object readinto(VirtualFrame frame, Object self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached PyObjectCallMethodObjArgs callMethod, @Cached InlinedConditionProfile isBytes, @Cached InlinedConditionProfile oversize, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); Object data = callMethod.execute(frame, inliningTarget, self, getMethodName(), len); @@ -169,7 +169,7 @@ Object readinto(VirtualFrame frame, Object self, Object buffer, bufferLib.readIntoBuffer(data, 0, buffer, 0, dataLen, bufferLib); return dataLen; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java index f32954f9e4..99013b35c3 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedReaderMixinBuiltins.java @@ -87,6 +87,7 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.nodes.ErrorMessages; @@ -97,7 +98,6 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; @@ -543,12 +543,12 @@ abstract static class ReadIntoNode extends PythonBinaryWithInitErrorClinicBuilti @SuppressWarnings("truffle-static-method") Object bufferedReadintoGeneric(VirtualFrame frame, PBuffered self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Cached EnterBufferedNode lock, @Cached FlushAndRewindUnlockedNode flushAndRewindUnlockedNode, @Cached RawReadNode rawReadNode, - @Cached FillBufferNode fillBufferNode) { + @Cached FillBufferNode fillBufferNode, + @Cached PyBufferRelease releaseBuffer) { checkIsClosedNode.execute(frame, self); try { lock.enter(inliningTarget, self); @@ -623,7 +623,7 @@ Object bufferedReadintoGeneric(VirtualFrame frame, PBuffered self, Object buffer return written; } finally { EnterBufferedNode.leave(self); - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterMixinBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterMixinBuiltins.java index bb06905c08..702ce29d3f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterMixinBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BufferedWriterMixinBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -56,11 +56,10 @@ import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.EnterBufferedNode; import com.oracle.graal.python.builtins.modules.io.BufferedIONodes.FlushAndRewindUnlockedNode; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.GenerateNodeFactory; @@ -68,7 +67,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = {PBufferedWriter, PBufferedRandom}) @@ -98,17 +96,16 @@ abstract static class WriteNode extends PythonBinaryWithInitErrorClinicBuiltinNo @Specialization(guards = "self.isOK()") static Object write(@SuppressWarnings("unused") VirtualFrame frame, PBuffered self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached EnterBufferedNode lock, @Cached("create(T_WRITE)") CheckIsClosedNode checkIsClosedNode, - @Cached BufferedWriterNodes.WriteNode writeNode) { + @Cached BufferedWriterNodes.WriteNode writeNode, + @Cached PyBufferRelease releaseBuffer) { try { lock.enter(inliningTarget, self); checkIsClosedNode.execute(frame, self); return writeNode.execute(frame, inliningTarget, self, buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); EnterBufferedNode.leave(self); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java index c8e2b30493..c193fe2403 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java @@ -90,7 +90,6 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.HashingStorageNodes.HashingStorageAddAllToOther; @@ -101,10 +100,12 @@ import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyMemoryViewFromObject; import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyTupleCheckNode; import com.oracle.graal.python.nodes.PGuards; @@ -118,7 +119,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.GetOrCreateDictNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.ArrayBuilder; @@ -386,8 +386,8 @@ abstract static class ReadIntoNode extends ClosedCheckPythonBinaryClinicBuiltinN @Specialization(guards = "self.hasBuf()") static Object readinto(VirtualFrame frame, PBytesIO self, Object buffer, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { try { /* adjust invalid sizes */ int len = bufferLib.getBufferLength(buffer); @@ -406,7 +406,7 @@ static Object readinto(VirtualFrame frame, PBytesIO self, Object buffer, return len; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -461,16 +461,16 @@ static Object truncate(VirtualFrame frame, PBytesIO self, Object size, @GenerateNodeFactory abstract static class WriteNode extends ClosedCheckPythonBinaryBuiltinNode { - @Specialization(guards = "self.hasBuf()", limit = "3") + @Specialization(guards = "self.hasBuf()") static Object doWrite(VirtualFrame frame, PBytesIO self, Object b, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("b") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { self.checkExports(inliningTarget, raiseNode); - Object buffer = acquireLib.acquireReadonly(b, frame, callData); + Object buffer = getBuffer.executeReadonly(frame, b); try { int len = bufferLib.getBufferLength(buffer); if (len == 0) { @@ -486,7 +486,7 @@ static Object doWrite(VirtualFrame frame, PBytesIO self, Object b, } return len; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java index 21fd8e5789..e0b8118db2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/FileIOBuiltins.java @@ -118,6 +118,7 @@ import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectIsTrueNode; @@ -136,12 +137,11 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; +import com.oracle.graal.python.nodes.util.PosixSupportNodes; import com.oracle.graal.python.runtime.AsyncHandler; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupport.PosixException; -import com.oracle.graal.python.nodes.util.PosixSupportNodes; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; @@ -659,12 +659,12 @@ abstract static class ReadintoNode extends PythonBinaryClinicBuiltinNode { @Specialization(guards = {"!self.isClosed()", "self.isReadable()"}) static Object readinto(VirtualFrame frame, PFileIO self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached InlinedBranchProfile readErrorProfile, @Bind PythonContext context, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, + @Cached PyBufferRelease releaseBuffer) { try { int size = bufferLib.getBufferLength(buffer); if (size == 0) { @@ -682,7 +682,7 @@ static Object readinto(VirtualFrame frame, PFileIO self, Object buffer, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -719,7 +719,8 @@ static Object write(VirtualFrame frame, PFileIO self, Object buffer, @Cached InlinedBranchProfile errorProfile, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (self.isClosed()) { throw raiseNode.raise(inliningTarget, ValueError, IO_CLOSED); @@ -737,7 +738,7 @@ static Object write(VirtualFrame frame, PFileIO self, Object buffer, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIOBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIOBuffer.java index 912eea153a..dd09c829a8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIOBuffer.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/PBytesIOBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -40,13 +40,10 @@ */ package com.oracle.graal.python.builtins.modules.io; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.object.Shape; -@ExportLibrary(value = PythonBufferAcquireLibrary.class, delegateTo = "delegate") public final class PBytesIOBuffer extends PythonBuiltinObject { private final PBytesIO source; @@ -58,6 +55,10 @@ public PBytesIOBuffer(Object cls, Shape instanceShape, PBytesIO source) { this.delegate = source.getBuf(); } + public PByteArray getDelegate() { + return delegate; + } + public PBytesIO getSource() { return source; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java index 30fa8ea2c5..a0bad65704 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java @@ -84,14 +84,15 @@ import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.str.StringNodes.CastToTruffleStringChecked1Node; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; import com.oracle.graal.python.lib.PyObjectGetAttr; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectRichCompareBool; @@ -99,7 +100,6 @@ 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.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; @@ -502,7 +502,6 @@ protected abstract static class ReadChunkNode extends Node { @Specialization(guards = "self.hasDecoder()") static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, int hint, - @Cached("createFor($node)") InteropCallData callData, @Cached SequenceNodes.GetObjectArrayNode getArray, @Cached(inline = false) DecodeNode decodeNode, @Cached PyObjectCallMethodObjArgs callMethodGetState, @@ -510,9 +509,10 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, @Cached PyNumberAsSizeNode asSizeNode, @Cached PyTupleCheckNode tupleCheckNode, @Cached TruffleString.CodePointLengthNode codePointLengthNode, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { /* * The return value is True unless EOF was reached. The decoded string is placed in * self._decoded_chars (replacing its previous value). The entire input chunk is sent to @@ -563,7 +563,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, Object inputChunkBuf; try { - inputChunkBuf = bufferAcquireLib.acquireReadonly(inputChunk, frame, callData); + inputChunkBuf = getBuffer.executeReadonly(frame, inputChunk); } catch (PException e) { throw raiseNode.raise(inliningTarget, TypeError, S_SHOULD_HAVE_RETURNED_A_BYTES_LIKE_OBJECT_NOT_P, (self.isHasRead1() ? T_READ1 : T_READ), inputChunk); } @@ -600,7 +600,7 @@ static boolean readChunk(VirtualFrame frame, Node inliningTarget, PTextIO self, return !eof; } finally { - bufferLib.release(inputChunkBuf, frame, callData); + releaseBuffer.execute(frame, inputChunkBuf); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/WindowsConsoleIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/WindowsConsoleIOBuiltins.java index dcd8cef20e..0e8ea79865 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/WindowsConsoleIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/WindowsConsoleIOBuiltins.java @@ -69,6 +69,7 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.attributes.WriteAttributeToObjectNode; @@ -178,7 +179,8 @@ static Object write(VirtualFrame frame, PFileIO self, Object buffer, @Bind PythonContext context, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Cached GilNode gil, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (self.isClosed()) { throw PRaiseNode.raiseStatic(inliningTarget, ValueError, IO_CLOSED); @@ -199,7 +201,7 @@ static Object write(VirtualFrame frame, PFileIO self, Object buffer, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java index 742883b050..625ca7376a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/multiprocessing/MultiprocessingModuleBuiltins.java @@ -51,17 +51,17 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.nodes.util.PosixSupportNodes; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupport.PosixException; -import com.oracle.graal.python.nodes.util.PosixSupportNodes; +import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -120,16 +120,16 @@ abstract static class Send extends PythonBinaryClinicBuiltinNode { static int doit(VirtualFrame frame, int handle, Object buffer, @Bind PythonContext context, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { + @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, + @Cached PyBufferRelease releaseBuffer) { try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); return context.getPosixSupport().send(handle, bytes, 0, bufferLib.getBufferLength(buffer), 0); } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java index 7a92f93473..8da898fffd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickleBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, 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 @@ -40,22 +40,10 @@ */ package com.oracle.graal.python.builtins.modules.pickle; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; - import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; -@ExportLibrary(PythonBufferAcquireLibrary.class) public final class PPickleBuffer extends PythonBuiltinObject { // Buffer object implementing PythonBufferAccessLibrary private Object view; @@ -74,25 +62,4 @@ public void release() { this.view = null; } - @ExportMessage - @SuppressWarnings("static-method") - boolean hasBuffer() { - return true; - } - - @ExportMessage - Object acquire(int flags, - @Bind Node inliningTarget, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, - @Cached PRaiseNode raise) { - Object owner = null; - if (view != null) { - owner = bufferLib.getOwner(view); - } - if (owner == null) { - throw raise.raise(inliningTarget, ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); - } - return acquireLib.acquire(owner, flags); - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java index 68d31392b7..4b8edf21b8 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PPickler.java @@ -74,7 +74,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesUtils; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.bytes.PBytes; @@ -100,9 +99,11 @@ import com.oracle.graal.python.builtins.objects.type.PythonManagedClass; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyObjectLookupAttr; @@ -622,7 +623,8 @@ public abstract static class SaveNode extends PicklerNodes.BasePickleNode { @Child private PyObjectStrAsObjectNode pyObjectStrAsObjectNode; @Child private PyObjectIsTrueNode isTrueNode; @Child private IsNode isNode; - @Child private PythonBufferAcquireLibrary bufferAcquireLibrary; + @Child private PyObjectGetBuffer getBufferNode; + @Child private PyBufferRelease releaseBufferNode; @Child private PythonBufferAccessLibrary bufferLibrary; @Child private PyCallableCheckNode callableCheckNode; @Child private PyObjectReprAsTruffleStringNode reprNode; @@ -1096,12 +1098,20 @@ private Object getIter(VirtualFrame frame, Object object) { return getIterNode.executeCached(frame, object); } - private PythonBufferAcquireLibrary getBufferAcquireLibrary() { - if (bufferAcquireLibrary == null) { + private PyBufferRelease getReleaseBufferNode() { + if (releaseBufferNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - bufferAcquireLibrary = insert(PythonBufferAcquireLibrary.getFactory().createDispatched(3)); + releaseBufferNode = insert(PyBufferRelease.create()); } - return bufferAcquireLibrary; + return releaseBufferNode; + } + + private PyObjectGetBuffer getBufferNode() { + if (getBufferNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + getBufferNode = insert(PyObjectGetBuffer.create()); + } + return getBufferNode; } private PythonBufferAccessLibrary getBufferLibrary() { @@ -1699,7 +1709,7 @@ private void saveFloat(PPickler pickler, int proto, double value) { } private void saveBytes(VirtualFrame frame, PythonContext ctx, PPickler pickler, int proto, boolean fastMode, PBytes obj) { - Object buffer = getBufferAcquireLibrary().acquireReadonly(obj); + Object buffer = getBufferNode().executeReadonly(frame, obj); PythonBufferAccessLibrary bufferLib = getBufferLibrary(); try { if (proto < 3) { @@ -1728,7 +1738,7 @@ private void saveBytes(VirtualFrame frame, PythonContext ctx, PPickler pickler, saveBytesData(frame, pickler, proto, fastMode, obj, buffer, bufferLib); } } finally { - bufferLib.release(buffer); + getReleaseBufferNode().execute(frame, buffer); } } @@ -2247,7 +2257,7 @@ private void saveBytearrayData(VirtualFrame frame, PPickler pickler, int proto, } private void saveBytearray(VirtualFrame frame, Node inliningTarget, PythonContext ctx, PPickler pickler, int proto, boolean fastMode, PByteArray obj) { - Object buffer = getBufferAcquireLibrary().acquireReadonly(obj); + Object buffer = getBufferNode().executeReadonly(frame, obj); PythonBufferAccessLibrary bufferLib = getBufferLibrary(); try { if (proto < 5) { @@ -2268,7 +2278,7 @@ private void saveBytearray(VirtualFrame frame, Node inliningTarget, PythonContex saveBytearrayData(frame, pickler, proto, fastMode, obj, buffer, bufferLib); } } finally { - bufferLib.release(buffer); + getReleaseBufferNode().execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java index b70dc9e32c..6e335f9119 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PUnpickler.java @@ -141,7 +141,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.EmptyStorage; import com.oracle.graal.python.builtins.objects.common.HashingCollectionNodes; @@ -168,8 +167,10 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlot; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotVarargs.CallSlotTpNewNode; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyMemoryViewFromObject; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectReprAsTruffleStringNode; @@ -182,7 +183,6 @@ import com.oracle.graal.python.nodes.argument.keywords.ExpandKeywordStarargsNode; import com.oracle.graal.python.nodes.argument.positional.ExecutePositionalStarargsNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; @@ -408,7 +408,8 @@ public abstract static class BasePickleReadNode extends PicklerNodes.BasePickleN @Child private PyObjectReprAsTruffleStringNode reprNode; @Child private PyMemoryViewFromObject memoryViewNode; @Child private MemoryViewBuiltins.ToReadonlyNode toReadonlyNode; - @Child private PythonBufferAcquireLibrary bufferAcquireLibrary; + @Child private PyObjectGetBuffer getBufferNode; + @Child private PyBufferRelease releaseBufferNode; @Child private PythonBufferAccessLibrary bufferAccessLibrary; @Child private TruffleString.ParseLongNode tsParseLongNode; @@ -417,10 +418,6 @@ public abstract static class BasePickleReadNode extends PicklerNodes.BasePickleN @CompilationFinal private boolean seenFileRead; - // we only need the reference, doesn't matter that the object may not yet be fully - // constructed - @SuppressWarnings("this-escape") private final InteropCallData interopCallData = InteropCallData.createFor(this); - protected TruffleString castToString(Object value) { if (castToTruffleStringNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); @@ -511,12 +508,20 @@ protected MemoryViewBuiltins.ToReadonlyNode getToReadonlyNode() { return toReadonlyNode; } - protected PythonBufferAcquireLibrary getBufferAcquireLibrary() { - if (bufferAcquireLibrary == null) { + private PyBufferRelease getReleaseBufferNode() { + if (releaseBufferNode == null) { + CompilerDirectives.transferToInterpreterAndInvalidate(); + releaseBufferNode = insert(PyBufferRelease.create()); + } + return releaseBufferNode; + } + + protected PyObjectGetBuffer getBufferNode() { + if (getBufferNode == null) { CompilerDirectives.transferToInterpreterAndInvalidate(); - bufferAcquireLibrary = insert(PythonBufferAcquireLibrary.getFactory().createDispatched(3)); + getBufferNode = insert(PyObjectGetBuffer.create()); } - return bufferAcquireLibrary; + return getBufferNode; } protected PythonBufferAccessLibrary getBufferAccessLibrary() { @@ -558,7 +563,7 @@ protected void skipConsumed(VirtualFrame frame, PUnpickler self) { } protected int setStringInput(PUnpickler self, VirtualFrame frame, Object input) { - Object buffer = getBufferAcquireLibrary().acquire(input, BufferFlags.PyBUF_CONTIG_RO, frame, interopCallData); + Object buffer = getBufferNode().execute(frame, input, BufferFlags.PyBUF_CONTIG_RO); try { self.inputBuffer = getBufferAccessLibrary().getCopiedByteArray(buffer); self.inputLen = getBufferAccessLibrary().getBufferLength(buffer); @@ -566,7 +571,7 @@ protected int setStringInput(PUnpickler self, VirtualFrame frame, Object input) self.prefetchedIdx = self.inputLen; return self.inputLen; } finally { - getBufferAccessLibrary().release(input, frame, interopCallData); + getReleaseBufferNode().execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java index 133f2d2c4b..12744d8fcc 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleBufferBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, 2026, 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 @@ -45,27 +45,26 @@ import java.util.List; import com.oracle.graal.python.PythonLanguage; +import com.oracle.graal.python.annotations.Builtin; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.annotations.Slot.SlotSignature; -import com.oracle.graal.python.annotations.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewNodes; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyMemoryViewFromObject; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.BufferFormat; import com.oracle.truffle.api.dsl.Bind; @@ -74,7 +73,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; @CoreFunctions(extendClasses = PythonBuiltinClassType.PickleBuffer) @@ -91,12 +89,11 @@ protected List> getNodeFa @SlotSignature(name = "PickleBuffer", minNumOfPositionalArgs = 2, parameterNames = {"$cls", "object"}) @GenerateNodeFactory abstract static class ConstructPickleBufferNode extends PythonBinaryBuiltinNode { - @Specialization(limit = "3") + @Specialization static PPickleBuffer construct(VirtualFrame frame, @SuppressWarnings("unused") Object cls, Object object, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("object") PythonBufferAcquireLibrary acquireLib) { - Object buffer = acquireLib.acquire(object, BufferFlags.PyBUF_FULL_RO, frame, callData); + @Cached PyObjectGetBuffer getBuffer) { + Object buffer = getBuffer.execute(frame, object, BufferFlags.PyBUF_FULL_RO); return PFactory.createPickleBuffer(language, buffer); } } @@ -138,11 +135,11 @@ Object raw(VirtualFrame frame, PPickleBuffer self, @GenerateNodeFactory public abstract static class PickleBufferReleaseNode extends PythonUnaryBuiltinNode { @Specialization - Object release(PPickleBuffer self, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { + Object release(VirtualFrame frame, PPickleBuffer self, + @Cached PyBufferRelease releaseBuffer) { Object view = self.getView(); if (view != null) { - bufferLib.release(view); + releaseBuffer.execute(frame, view); self.release(); } return PNone.NONE; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java index 539038ee45..39ac6f5ca5 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pickle/PickleModuleBuiltins.java @@ -54,6 +54,7 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.nodes.HiddenAttr; @@ -61,7 +62,6 @@ import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; @@ -252,9 +252,9 @@ static Object loads(VirtualFrame frame, @SuppressWarnings("unused") PythonModule @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @Cached PUnpickler.LoadNode loadNode, - @Cached PyObjectGetIter getIter) { + @Cached PyObjectGetIter getIter, + @Cached PyBufferRelease releaseBuffer) { try { PUnpickler unpickler = PFactory.createUnpickler(language); byte[] data = bufferLib.getInternalOrCopiedByteArray(buffer); @@ -264,7 +264,7 @@ static Object loads(VirtualFrame frame, @SuppressWarnings("unused") PythonModule unpickler.setFixImports(fixImports); return loadNode.execute(frame, unpickler); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pyexpat/XMLParserBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pyexpat/XMLParserBuiltins.java index 10d7290a37..107051a12d 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pyexpat/XMLParserBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/pyexpat/XMLParserBuiltins.java @@ -85,15 +85,16 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.dict.PDict; import com.oracle.graal.python.builtins.objects.exception.PBaseException; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyLongCheckNode; import com.oracle.graal.python.lib.PyNumberIndexNode; import com.oracle.graal.python.lib.PyObjectCallMethodObjArgs; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.lib.PyUnicodeCheckNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -937,7 +938,7 @@ private static byte[] asByteArray(Object data) { } return Arrays.copyOfRange(internalByteArray.getArray(), internalByteArray.getOffset(), internalByteArray.getOffset() + chunkLen); } - Object buffer = PythonBufferAcquireLibrary.getUncached().acquireReadonly(data); + Object buffer = PyObjectGetBuffer.getUncached().executeReadonly(null, data); try { PythonBufferAccessLibrary accessLib = PythonBufferAccessLibrary.getUncached(); int chunkLen = accessLib.getBufferLength(buffer); @@ -948,7 +949,7 @@ private static byte[] asByteArray(Object data) { accessLib.readIntoByteArray(buffer, 0, bytes, 0, chunkLen); return bytes; } finally { - PythonBufferAccessLibrary.getUncached().release(buffer); + PyBufferRelease.getUncached().execute(null, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/PatternNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/PatternNodes.java index 6b52d06a71..e07c6c502e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/PatternNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/PatternNodes.java @@ -50,12 +50,13 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.array.PArray; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.mmap.PMMap; import com.oracle.graal.python.builtins.objects.module.PythonModule; import com.oracle.graal.python.builtins.objects.tuple.PTuple; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectLookupAttr; import com.oracle.graal.python.lib.PyObjectSizeNode; import com.oracle.graal.python.lib.PyTupleGetItem; @@ -67,7 +68,6 @@ import com.oracle.graal.python.nodes.statement.AbstractImportNode; import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData; import com.oracle.truffle.api.CompilerDirectives; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -374,20 +374,19 @@ abstract static class BufferToTruffleStringNode extends PNodeWithContext { public abstract TruffleString execute(VirtualFrame frame, Object buffer); - @Specialization(limit = "3") + @Specialization static TruffleString convert(VirtualFrame frame, Object bytesLikeObject, @Bind Node inliningTarget, - @Shared @Cached("createFor($node)") IndirectCallData.InteropCallData callData, @Cached(inline = true) BufferToTruffleStringInnerNode innerNode, - @CachedLibrary("bytesLikeObject") PythonBufferAcquireLibrary bufferAcquireLib, - @CachedLibrary(limit = "1") @Shared PythonBufferAccessLibrary bufferLib) { + @Cached PyObjectGetBuffer getBuffer, + @Cached PyBufferRelease releaseBuffer) { Object buffer = null; try { - buffer = bufferAcquireLib.acquireReadonly(bytesLikeObject, frame, callData); + buffer = getBuffer.executeReadonly(frame, bytesLikeObject); return innerNode.execute(inliningTarget, buffer); } finally { if (buffer != null) { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/TRegexCache.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/TRegexCache.java index cdea7942e4..c8a567e38c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/TRegexCache.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/re/TRegexCache.java @@ -52,7 +52,8 @@ import org.graalvm.collections.EconomicMap; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.util.CannotCastException; @@ -112,7 +113,7 @@ public TRegexCache(Node node, Object pattern, int flags) { } catch (CannotCastException ce) { Object buffer; try { - buffer = PythonBufferAcquireLibrary.getUncached().acquireReadonly(pattern); + buffer = PyObjectGetBuffer.getUncached().executeReadonly(null, pattern); } catch (PException e) { throw PRaiseNode.raiseStatic(node, TypeError, ErrorMessages.EXPECTED_STR_OR_BYTESLIKE_OBJ); } @@ -122,7 +123,7 @@ public TRegexCache(Node node, Object pattern, int flags) { int bytesLen = bufferLib.getBufferLength(buffer); patternStr = new String(bytes, 0, bytesLen, StandardCharsets.ISO_8859_1); } finally { - bufferLib.release(buffer); + PyBufferRelease.getUncached().execute(null, buffer); } } validateFlags(node, binary, flags); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java index 8fd8860451..506ece9817 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZLibModuleBuiltins.java @@ -73,6 +73,7 @@ import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.module.PythonModule; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; @@ -82,7 +83,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentCastNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.NativeZlibSupport; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; @@ -484,15 +484,15 @@ static PBytes compress(VirtualFrame frame, Object buffer, int level, int wbits, @Bind Node inliningTarget, @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached("createFor($node)") InteropCallData callData, - @Cached CompressInnerNode innerNode) { + @Cached CompressInnerNode innerNode, + @Cached PyBufferRelease releaseBuffer) { try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); byte[] resultArray = innerNode.execute(inliningTarget, bytes, len, level, wbits); return PFactory.createBytes(language, resultArray); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -548,9 +548,9 @@ static PBytes decompress(VirtualFrame frame, Object buffer, int wbits, int bufsi @Bind Node inliningTarget, @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached("createFor($node)") InteropCallData callData, @Cached DecompressInnerNode innerNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (bufsize < 0) { throw raiseNode.raise(inliningTarget, ZLibError, ErrorMessages.MUST_BE_NON_NEGATIVE, "bufsize"); @@ -560,7 +560,7 @@ static PBytes decompress(VirtualFrame frame, Object buffer, int wbits, int bufsi byte[] resultArray = innerNode.execute(inliningTarget, bytes, len, wbits, bufsize); return PFactory.createBytes(language, resultArray); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java index cea367d152..a1e79439ff 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibCompressBuiltins.java @@ -62,6 +62,7 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; @@ -70,7 +71,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.NativeZlibSupport; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; @@ -104,9 +104,9 @@ static PBytes compress(VirtualFrame frame, ZLibCompObject self, Object buffer, @Bind Node inliningTarget, @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached("createFor($node)") InteropCallData callData, @Cached CompressInnerNode innerNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (!self.isInitialized()) { throw raiseNode.raise(inliningTarget, ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while compressing data", "inconsistent stream state"); @@ -115,7 +115,7 @@ static PBytes compress(VirtualFrame frame, ZLibCompObject self, Object buffer, int len = bufferLib.getBufferLength(buffer); return PFactory.createBytes(language, innerNode.execute(inliningTarget, self, bytes, len)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java index 9b8311f4df..d427e5d36e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressBuiltins.java @@ -64,6 +64,7 @@ import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -72,7 +73,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.NativeZlibSupport; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; @@ -112,9 +112,9 @@ static PBytes decompress(VirtualFrame frame, ZLibCompObject self, Object buffer, @Bind Node inliningTarget, @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached("createFor($node)") InteropCallData callData, @Cached DecompressInnerNode innerNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (!self.isInitialized()) { throw raiseNode.raise(inliningTarget, ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while decompressing data", "inconsistent stream state"); @@ -126,7 +126,7 @@ static PBytes decompress(VirtualFrame frame, ZLibCompObject self, Object buffer, int len = bufferLib.getBufferLength(buffer); return PFactory.createBytes(language, innerNode.execute(frame, inliningTarget, self, bytes, len, maxLength)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressorBuiltins.java index d3204ca6f7..255e92cfb9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/zlib/ZlibDecompressorBuiltins.java @@ -52,10 +52,10 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Builtin; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.annotations.Slot.SlotSignature; -import com.oracle.graal.python.annotations.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.modules.zlib.ZLibModuleBuiltins.ExpectByteLikeNode; @@ -63,13 +63,13 @@ import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.NativeZlibSupport; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; @@ -169,9 +169,9 @@ static PBytes decompress(VirtualFrame frame, ZlibDecompressorObject self, Object @Bind Node inliningTarget, @Bind PythonLanguage language, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached("createFor($node)") InteropCallData callData, @Cached DecompressBufInnerNode innerNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (!self.isInitialized()) { throw raiseNode.raise(inliningTarget, ZLibError, ERROR_D_S_S, Z_STREAM_ERROR, "while decompressing data", "inconsistent stream state"); @@ -192,7 +192,7 @@ static PBytes decompress(VirtualFrame frame, ZlibDecompressorObject self, Object return PFactory.createBytes(language, innerNode.execute(frame, inliningTarget, self, bytes, len, maxLength)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java index 977d5b6d08..14b2fc7b4e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java @@ -99,6 +99,7 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; @@ -127,7 +128,6 @@ import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinClassExactProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; @@ -1244,11 +1244,11 @@ public abstract static class FromBytesNode extends PythonBinaryClinicBuiltinNode @Specialization static Object frombytes(VirtualFrame frame, PArray self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached ArrayNodes.EnsureCapacityNode ensureCapacityNode, @Cached ArrayNodes.SetLengthNode setLengthNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { int itemShift = self.getItemSizeShift(); int oldSize = self.getLength(); @@ -1268,7 +1268,7 @@ static Object frombytes(VirtualFrame frame, PArray self, Object buffer, } return PNone.NONE; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java index bd86f9ad46..cc977dcb87 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/PArray.java @@ -34,7 +34,6 @@ import java.util.concurrent.atomic.AtomicLong; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.ints.PInt; @@ -66,7 +65,6 @@ import com.oracle.truffle.api.object.Shape; import com.oracle.truffle.api.strings.TruffleString; -@ExportLibrary(PythonBufferAcquireLibrary.class) @ExportLibrary(PythonBufferAccessLibrary.class) @ExportLibrary(InteropLibrary.class) public final class PArray extends PythonBuiltinObject { @@ -217,12 +215,6 @@ public static MachineFormat fromCode(int code) { } } - @ExportMessage - @SuppressWarnings("static-method") - boolean hasBuffer() { - return true; - } - @ExportMessage @SuppressWarnings("static-method") boolean isBuffer() { @@ -234,11 +226,6 @@ int getBufferLength() { return storage.length(); } - @ExportMessage - Object acquire(@SuppressWarnings("unused") int flags) { - return this; - } - @ExportMessage @SuppressWarnings("static-method") boolean isReadonly() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/BufferFlags.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/BufferFlags.java index b1dbe6587f..c2238f328e 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/BufferFlags.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/BufferFlags.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -40,8 +40,10 @@ */ package com.oracle.graal.python.builtins.objects.buffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; + /** - * Flags for getting buffers. Extracted from CPython. Used by {@link PythonBufferAcquireLibrary}. + * Flags for getting buffers. Extracted from CPython. Used by {@link PyObjectGetBuffer}. */ public abstract class BufferFlags { public static final int PyBUF_SIMPLE = 0; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/ForeignBufferAcquireExports.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/ForeignBufferAcquireExports.java deleted file mode 100644 index ba8768cbf5..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/ForeignBufferAcquireExports.java +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2026, 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 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.buffer; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BufferError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.IndexError; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; - -import java.nio.ByteOrder; - -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; -import com.oracle.graal.python.util.BufferFormat; -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.interop.InteropLibrary; -import com.oracle.truffle.api.interop.InvalidBufferOffsetException; -import com.oracle.truffle.api.interop.UnsupportedMessageException; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.library.ExportLibrary; -import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.LoopNode; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.strings.TruffleString; - -@ExportLibrary(value = PythonBufferAcquireLibrary.class, receiverType = Object.class) -final class ForeignBufferAcquireExports { - - @ExportMessage - static boolean hasBuffer(Object receiver, - @CachedLibrary("receiver") InteropLibrary interop) { - return interop.hasBufferElements(receiver); - } - - @ExportMessage - static Object acquire(Object receiver, int flags, - @Bind Node inliningTarget, - @Cached CastToJavaIntExactNode castInt, - @CachedLibrary("receiver") InteropLibrary interop) { - if (!interop.hasBufferElements(receiver)) { - throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, receiver); - } - - long bufferSize; - try { - bufferSize = interop.getBufferSize(receiver); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - - boolean readonly; - try { - readonly = !interop.isBufferWritable(receiver); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - if (BufferFlags.requestsWritable(flags) && readonly) { - throw PRaiseNode.raiseStatic(inliningTarget, BufferError, ErrorMessages.OBJ_IS_NOT_WRITABLE); - } - return new ForeignBufferAdapter(receiver, castInt.execute(inliningTarget, bufferSize), readonly); - } - - @ExportLibrary(PythonBufferAccessLibrary.class) - static final class ForeignBufferAdapter { - final Object foreignBuffer; - final int len; - final boolean readonly; - - ForeignBufferAdapter(Object foreignBuffer, int len, boolean readonly) { - this.foreignBuffer = foreignBuffer; - this.len = len; - this.readonly = readonly; - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean isBuffer() { - return true; - } - - @ExportMessage - boolean isReadonly() { - return readonly; - } - - @ExportMessage - int getBufferLength() { - return len; - } - - @ExportMessage - Object getOwner() { - return foreignBuffer; - } - - @ExportMessage - byte readByte(int byteOffset, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - return interop.readBufferByte(foreignBuffer, byteOffset); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void writeByte(int byteOffset, byte value, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - assert !readonly; - try { - interop.writeBufferByte(foreignBuffer, byteOffset, value); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void readIntoByteArray(int srcOffset, byte[] dest, int destOffset, int length, - @Bind Node inliningTarget, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - interop.readBuffer(foreignBuffer, srcOffset, dest, destOffset, length); - } catch (InvalidBufferOffsetException e) { - throw PRaiseNode.raiseStatic(inliningTarget, IndexError, ErrorMessages.STRUCT_OFFSET_OUT_OF_RANGE, e.getByteOffset(), len); - } catch (UnsupportedMessageException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void readIntoBuffer(int srcOffset, Object dest, int destOffset, int length, PythonBufferAccessLibrary otherLib, - @Bind Node inliningTarget, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - if (otherLib.hasInternalByteArray(dest)) { - readIntoByteArray(srcOffset, otherLib.getInternalByteArray(dest), destOffset, length, inliningTarget, interop); - } else { - for (int i = 0; i < length; i++) { - otherLib.writeByte(dest, destOffset + i, readByte(srcOffset + i, interop)); - } - LoopNode.reportLoopCount(inliningTarget, Math.max(0, length)); - } - } - - @ExportMessage - short readShortByteOrder(int byteOffset, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - return interop.readBufferShort(foreignBuffer, byteOrder, byteOffset); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - int readIntByteOrder(int byteOffset, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - return interop.readBufferInt(foreignBuffer, byteOrder, byteOffset); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - long readLongByteOrder(int byteOffset, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - return interop.readBufferLong(foreignBuffer, byteOrder, byteOffset); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - float readFloatByteOrder(int byteOffset, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - return interop.readBufferFloat(foreignBuffer, byteOrder, byteOffset); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - double readDoubleByteOrder(int byteOffset, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - try { - return interop.readBufferDouble(foreignBuffer, byteOrder, byteOffset); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void writeShortByteOrder(int byteOffset, short value, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - assert !readonly; - try { - interop.writeBufferShort(foreignBuffer, byteOrder, byteOffset, value); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void writeIntByteOrder(int byteOffset, int value, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - assert !readonly; - try { - interop.writeBufferInt(foreignBuffer, byteOrder, byteOffset, value); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void writeLongByteOrder(int byteOffset, long value, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - assert !readonly; - try { - interop.writeBufferLong(foreignBuffer, byteOrder, byteOffset, value); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void writeFloatByteOrder(int byteOffset, float value, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - assert !readonly; - try { - interop.writeBufferFloat(foreignBuffer, byteOrder, byteOffset, value); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - void writeDoubleByteOrder(int byteOffset, double value, ByteOrder byteOrder, - @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { - assert !readonly; - try { - interop.writeBufferDouble(foreignBuffer, byteOrder, byteOffset, value); - } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { - throw CompilerDirectives.shouldNotReachHere(e); - } - } - - @ExportMessage - @SuppressWarnings("static-method") - int getItemSize() { - return 1; - } - - @ExportMessage - @SuppressWarnings("static-method") - TruffleString getFormatString() { - return BufferFormat.T_UINT_8_TYPE_CODE; - } - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/ForeignBufferAdapter.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/ForeignBufferAdapter.java new file mode 100644 index 0000000000..43c8af9e42 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/ForeignBufferAdapter.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2026, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.builtins.objects.buffer; + +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.IndexError; + +import java.nio.ByteOrder; + +import com.oracle.graal.python.nodes.ErrorMessages; +import com.oracle.graal.python.nodes.PRaiseNode; +import com.oracle.graal.python.util.BufferFormat; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.InvalidBufferOffsetException; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.library.ExportLibrary; +import com.oracle.truffle.api.library.ExportMessage; +import com.oracle.truffle.api.nodes.LoopNode; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.strings.TruffleString; + +@ExportLibrary(PythonBufferAccessLibrary.class) +public final class ForeignBufferAdapter { + final Object foreignBuffer; + final int len; + final boolean readonly; + + public ForeignBufferAdapter(Object foreignBuffer, int len, boolean readonly) { + this.foreignBuffer = foreignBuffer; + this.len = len; + this.readonly = readonly; + } + + @ExportMessage + @SuppressWarnings("static-method") + boolean isBuffer() { + return true; + } + + @ExportMessage + boolean isReadonly() { + return readonly; + } + + @ExportMessage + int getBufferLength() { + return len; + } + + @ExportMessage + Object getOwner() { + return foreignBuffer; + } + + @ExportMessage + byte readByte(int byteOffset, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + return interop.readBufferByte(foreignBuffer, byteOffset); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void writeByte(int byteOffset, byte value, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + assert !readonly; + try { + interop.writeBufferByte(foreignBuffer, byteOffset, value); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void readIntoByteArray(int srcOffset, byte[] dest, int destOffset, int length, + @Bind Node inliningTarget, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + interop.readBuffer(foreignBuffer, srcOffset, dest, destOffset, length); + } catch (InvalidBufferOffsetException e) { + throw PRaiseNode.raiseStatic(inliningTarget, IndexError, ErrorMessages.STRUCT_OFFSET_OUT_OF_RANGE, e.getByteOffset(), len); + } catch (UnsupportedMessageException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void readIntoBuffer(int srcOffset, Object dest, int destOffset, int length, PythonBufferAccessLibrary otherLib, + @Bind Node inliningTarget, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + if (otherLib.hasInternalByteArray(dest)) { + readIntoByteArray(srcOffset, otherLib.getInternalByteArray(dest), destOffset, length, inliningTarget, interop); + } else { + for (int i = 0; i < length; i++) { + otherLib.writeByte(dest, destOffset + i, readByte(srcOffset + i, interop)); + } + LoopNode.reportLoopCount(inliningTarget, Math.max(0, length)); + } + } + + @ExportMessage + short readShortByteOrder(int byteOffset, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + return interop.readBufferShort(foreignBuffer, byteOrder, byteOffset); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + int readIntByteOrder(int byteOffset, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + return interop.readBufferInt(foreignBuffer, byteOrder, byteOffset); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + long readLongByteOrder(int byteOffset, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + return interop.readBufferLong(foreignBuffer, byteOrder, byteOffset); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + float readFloatByteOrder(int byteOffset, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + return interop.readBufferFloat(foreignBuffer, byteOrder, byteOffset); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + double readDoubleByteOrder(int byteOffset, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + try { + return interop.readBufferDouble(foreignBuffer, byteOrder, byteOffset); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void writeShortByteOrder(int byteOffset, short value, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + assert !readonly; + try { + interop.writeBufferShort(foreignBuffer, byteOrder, byteOffset, value); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void writeIntByteOrder(int byteOffset, int value, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + assert !readonly; + try { + interop.writeBufferInt(foreignBuffer, byteOrder, byteOffset, value); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void writeLongByteOrder(int byteOffset, long value, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + assert !readonly; + try { + interop.writeBufferLong(foreignBuffer, byteOrder, byteOffset, value); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void writeFloatByteOrder(int byteOffset, float value, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + assert !readonly; + try { + interop.writeBufferFloat(foreignBuffer, byteOrder, byteOffset, value); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + void writeDoubleByteOrder(int byteOffset, double value, ByteOrder byteOrder, + @CachedLibrary("this.foreignBuffer") InteropLibrary interop) { + assert !readonly; + try { + interop.writeBufferDouble(foreignBuffer, byteOrder, byteOffset, value); + } catch (UnsupportedMessageException | InvalidBufferOffsetException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + + @ExportMessage + @SuppressWarnings("static-method") + int getItemSize() { + return 1; + } + + @ExportMessage + @SuppressWarnings("static-method") + TruffleString getFormatString() { + return BufferFormat.T_UINT_8_TYPE_CODE; + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java index 4ecfe395e3..6cbec8ad24 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAccessLibrary.java @@ -45,24 +45,21 @@ import java.nio.ByteOrder; -import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; -import com.oracle.graal.python.runtime.ExecutionContext.InteropCallContext; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.util.PythonUtils; -import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.CompilerDirectives; -import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.library.GenerateLibrary; import com.oracle.truffle.api.library.GenerateLibrary.Abstract; import com.oracle.truffle.api.library.Library; import com.oracle.truffle.api.library.LibraryFactory; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.strings.TruffleString; /** - * A library for accessing buffers obtained using {@link PythonBufferAcquireLibrary}. The buffer - * should always be released using {@link #release} after the access is finished. It is also + * A library for accessing buffers obtained using {@link PyObjectGetBuffer}. The buffer + * should always be released using {@link PyBufferRelease} after the access is finished. It is also * permissible to use this library to access the underlying memory of {@link PBytesLike} objects * that implement the API directly (i.e. as an equivalent of {@code PyBytes_AsStringAndSize}) - in * that case, the buffer doesn't need to be acquired or released. @@ -88,7 +85,7 @@ public abstract class PythonBufferAccessLibrary extends Library { * Whether this object responds to this buffer API.
* Use this method with caution and only when absolutely needed. Code using * buffers must know whether it works with a buffer object or not. Therefore, buffers - * should be acquired first using {@link PythonBufferAcquireLibrary}. Use + * should be acquired first using {@link PyObjectGetBuffer}. Use * {@link #assertIsBuffer(Object)} for assertions. */ @Abstract @@ -103,43 +100,6 @@ public static void assertIsBuffer(Object receiver) { assert PythonBufferAccessLibrary.getUncached().isBuffer(receiver); } - /** - * Release the buffer. Equivalent of CPython's {@code PyBuffer_Release}, but must not be called - * multiple times on the same buffer. If the caller has access to a VirtualFrame - * {@link #release(Object, VirtualFrame, InteropCallData)} or - * {@link #release(Object, VirtualFrame, PythonContext, PythonLanguage, InteropCallData)} should - * be used. If the caller doesn't have access to a VirtualFrame it must be ensured that an - * IndirectCallContext was already created in the call path. - */ - public void release(@SuppressWarnings("unused") Object receiver) { - } - - /** - * Release the buffer. Equivalent of CPython's {@code PyBuffer_Release}, but must not be called - * multiple times on the same buffer. - */ - public final void release(Object receiver, VirtualFrame frame, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, this, callData); - try { - release(receiver); - } finally { - InteropCallContext.exit(frame, this, callData, savedState); - } - } - - /** - * Release the buffer. Equivalent of CPython's {@code PyBuffer_Release}, but must not be called - * multiple times on the same buffer. - */ - public final void release(Object receiver, VirtualFrame frame, PythonContext context, PythonLanguage language, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, language, context, callData); - try { - release(receiver); - } finally { - InteropCallContext.exit(frame, language, context, savedState); - } - } - /** * Return the buffer length in bytes. Equivalent of CPython's {@code Py_buffer.len}. */ diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java deleted file mode 100644 index 973485799e..0000000000 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2021, 2026, 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 - * - * Subject to the condition set forth below, permission is hereby granted to any - * person obtaining a copy of this software, associated documentation and/or - * data (collectively the "Software"), free of charge and under any and all - * copyright rights in the Software, and any and all patent rights owned or - * freely licensable by each licensor hereunder covering either (i) the - * unmodified Software as contributed to or provided by such licensor, or (ii) - * the Larger Works (as defined below), to deal in both - * - * (a) the Software, and - * - * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if - * one is included with the Software each a "Larger Work" to which the Software - * is contributed by such licensors), - * - * without restriction, including without limitation the rights to copy, create - * derivative works of, display, perform, and distribute the Software and make, - * use, sell, offer for sale, import, export, have made, and have sold the - * Software and the Larger Work(s), and to sublicense the foregoing rights on - * either these or other terms. - * - * This license is subject to the following condition: - * - * The above copyright notice and either this complete permission notice or at a - * minimum a reference to the UPL must be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ -package com.oracle.graal.python.builtins.objects.buffer; - -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; - -import com.oracle.graal.python.PythonLanguage; -import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; -import com.oracle.graal.python.runtime.ExecutionContext.InteropCallContext; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.graal.python.runtime.exception.PException; -import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.interop.InteropLibrary; -import com.oracle.truffle.api.library.GenerateLibrary; -import com.oracle.truffle.api.library.GenerateLibrary.DefaultExport; -import com.oracle.truffle.api.library.GenerateLibrary.Abstract; -import com.oracle.truffle.api.library.Library; -import com.oracle.truffle.api.library.LibraryFactory; - -/** - * Provide a way to acquire and release underlying byte buffer of objects that support it. Roughly - * corresponds to CPython's internal buffer API, with the primary difference that we don't always - * have direct access to the underlying array. Objects implementing this API are: - * - * The acquired buffer object should be accessed using {@link PythonBufferAccessLibrary} and needs - * to be released using {@link PythonBufferAccessLibrary#release(Object)} method when done. - */ -@GenerateLibrary(assertions = PythonBufferAcquireLibrary.Assertions.class) -@DefaultExport(ForeignBufferAcquireExports.class) -public abstract class PythonBufferAcquireLibrary extends Library { - /** - * Return whether it is possible to acquire a read-only buffer for this object. The actual - * acquisition may still raise an exception. Equivalent of CPython's - * {@code PyObject_CheckBuffer}. - */ - @Abstract - public boolean hasBuffer(@SuppressWarnings("unused") Object receiver) { - return false; - } - - /** - * Acquire a buffer object meant for reading. Equivalent of CPython's; - * - * Will raise exception if the acquisition fails. Must call - * {@link PythonBufferAccessLibrary#release(Object)} on the returned object after the access is - * finished. When intrinsifying CPython {PyObject_GetBuffer} calls, pay attention to what it - * does to the exception. Sometimes it replaces the exception raised here with another one. - *

- * IMPORTANT: This method may only be used in the context of an indirect interop call - * (see {@link InteropCallContext}) or indirect boundary call {@link BoundaryCallContext}. If a - * frame is available, prefer using convenience methods - * {@link #acquireReadonly(Object, VirtualFrame, InteropCallData)} or - * {@link #acquireReadonly(Object, VirtualFrame, PythonContext, PythonLanguage, InteropCallData)} - * . - *

- */ - public final Object acquireReadonly(Object receiver) { - return acquire(receiver, BufferFlags.PyBUF_SIMPLE); - } - - /** - * Convenience method that sets up an indirect call and then uses - * {@link #acquireReadonly(Object)}. NOTE: the provided indirectCallData must belong to a - * node which is an ancestor of the library. - */ - public final Object acquireReadonly(Object receiver, VirtualFrame frame, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, this, callData); - try { - return acquire(receiver, BufferFlags.PyBUF_SIMPLE); - } finally { - InteropCallContext.exit(frame, this, callData, savedState); - } - } - - /** - * Convenience method that sets up an indirect call and then uses - * {@link #acquireReadonly(Object)}. NOTE: the provided indirectCallData must belong to a - * node which is an ancestor of the library. - */ - public final Object acquireReadonly(Object receiver, VirtualFrame frame, PythonContext context, PythonLanguage language, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, language, context, callData); - try { - return acquire(receiver, BufferFlags.PyBUF_SIMPLE); - } finally { - InteropCallContext.exit(frame, language, context, savedState); - } - } - - /** - * Acquire a buffer object meant for writing. Equivalent of CPython's {@code PyObject_GetBuffer} - * with flag {@code PyBUF_WRITABLE}. For equivalents of clinic and {@code PyArg_Parse*} - * converters, see - * {@link #acquireWritableWithTypeError(Object, String, VirtualFrame, InteropCallData)} . Will - * raise exception if the acquisition fails. Must call - * {@link PythonBufferAccessLibrary#release(Object)} on the returned object after the access is - * finished. When intrinsifying CPython {PyObject_GetBuffer} calls, pay attention to what it - * does to the exception. More often than not, it replaces the exception raised here with - * another one. - *

- * IMPORTANT: This method may only be used in the context of an indirect interop call - * (see {@link InteropCallContext}) or indirect boundary call {@link BoundaryCallContext}. If a - * frame is available, prefer using convenience methods - * {@link #acquireWritable(Object, VirtualFrame, InteropCallData)} or - * {@link #acquireWritable(Object, VirtualFrame, PythonContext, PythonLanguage, InteropCallData)} - * . - *

- */ - public final Object acquireWritable(Object receiver) { - return acquire(receiver, BufferFlags.PyBUF_WRITABLE); - } - - /** - * Convenience method that sets up an indirect call and then uses - * {@link #acquireWritable(Object)}. NOTE: the provided indirectCallData must belong to a - * node which is an ancestor of the library. - */ - public final Object acquireWritable(Object receiver, VirtualFrame frame, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, this, callData); - try { - return acquire(receiver, BufferFlags.PyBUF_WRITABLE); - } finally { - InteropCallContext.exit(frame, this, callData, savedState); - } - } - - /** - * Convenience method that sets up an indirect call and then uses - * {@link #acquireWritable(Object)}. NOTE: the provided indirectCallData must belong to a - * node which is an ancestor of the library. - */ - public final Object acquireWritable(Object receiver, VirtualFrame frame, PythonContext context, PythonLanguage language, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, language, context, callData); - try { - return acquire(receiver, BufferFlags.PyBUF_WRITABLE); - } finally { - InteropCallContext.exit(frame, language, context, savedState); - } - } - - /** - * Acquire a buffer object meant for writing. Equivalent of CPython's: - * - * Will raise a {@code TypeError} if the acquisition fails, regardless of what exception the - * acquisition produced. - */ - public final Object acquireWritableWithTypeError(Object receiver, String callerName, VirtualFrame frame, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, this, callData); - try { - return acquireWritable(receiver); - } catch (PException e) { - throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, callerName, receiver); - } finally { - InteropCallContext.exit(frame, this, callData, savedState); - } - } - - /** - * Acquire a buffer with given flags. Equivalent of CPython's {@code PyObject_GetBuffer}. Note - * that the API is currently not expressive enough to deal with the more complex types. Make - * sure you know what the flags mean and that you can handle the result properly. - *

- * IMPORTANT: This method may only be used in the context of an indirect interop call - * (see {@link InteropCallContext}) or indirect boundary call {@link BoundaryCallContext}. If a - * frame is available, prefer using convenience methods - * {@link #acquire(Object, int, VirtualFrame, InteropCallData)}}. - *

- * - * @param flags combined constants from {@link BufferFlags}. Unlike CPython, our buffer objects - * typically return themselves for performance reasons and thus cannot remove the - * format/shape/strides when the flags request them to do so. Be prepared to ignore - * those elements in such case. - */ - @Abstract - public Object acquire(Object receiver, int flags) { - throw PRaiseNode.raiseStatic(this, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, receiver); - } - - /** - * Convenience method that sets up an indirect call and then uses {@link #acquire(Object, int)}. - * NOTE: the provided indirectCallData must belong to a node which is an ancestor of the - * library. - */ - public final Object acquire(Object receiver, int flags, VirtualFrame frame, InteropCallData callData) { - Object savedState = InteropCallContext.enter(frame, this, callData); - try { - return acquire(receiver, flags); - } finally { - InteropCallContext.exit(frame, this, callData, savedState); - } - } - - static class Assertions extends PythonBufferAcquireLibrary { - @Child PythonBufferAcquireLibrary delegate; - - public Assertions(PythonBufferAcquireLibrary delegate) { - this.delegate = delegate; - } - - @Override - public boolean accepts(Object receiver) { - return delegate.accepts(receiver); - } - - @Override - public boolean hasBuffer(Object receiver) { - return delegate.hasBuffer(receiver); - } - - @Override - public Object acquire(Object receiver, int flags) { - Object buffer = delegate.acquire(receiver, flags); - assert delegate.hasBuffer(receiver); - assert PythonBufferAccessLibrary.getUncached().isBuffer(buffer); - return buffer; - } - } - - static final LibraryFactory FACTORY = LibraryFactory.resolve(PythonBufferAcquireLibrary.class); - - public static LibraryFactory getFactory() { - return FACTORY; - } - - public static PythonBufferAcquireLibrary getUncached() { - return FACTORY.getUncached(); - } -} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java index 794ef94f73..3f2e0fa66a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java @@ -52,7 +52,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.FindNode; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.GetBytesStorage; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.HexStringToBytesNode; @@ -76,9 +75,12 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyByteArrayCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetStateNode; import com.oracle.graal.python.lib.PySliceNew; import com.oracle.graal.python.lib.PyUnicodeCheckNode; @@ -98,7 +100,6 @@ import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToByteNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.PSequence; @@ -281,12 +282,12 @@ static void doSliceSequence(VirtualFrame frame, PByteArray self, PSlice slice, P setItemSliceNode.execute(frame, inliningTarget, storage, info, value, false); } - @Specialization(guards = {"!isNoValue(value)", "bufferAcquireLib.hasBuffer(value)"}, limit = "3") + @Specialization(guards = {"!isNoValue(value)", "checkBufferNode.execute(value)"}, limit = "1") static void doSliceBuffer(VirtualFrame frame, PByteArray self, PSlice slice, Object value, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("value") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached @Shared InlinedConditionProfile differentLenProfile, @Cached @Shared SequenceNodes.GetSequenceStorageNode getSequenceStorageNode, @@ -294,14 +295,15 @@ static void doSliceBuffer(VirtualFrame frame, PByteArray self, PSlice slice, Obj @Cached @Shared SliceNodes.CoerceToIntSlice sliceCast, @Cached @Shared SliceNodes.SliceUnpack unpack, @Cached @Shared SliceNodes.AdjustIndices adjustIndices, - @Shared @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireReadonly(value, frame, callData); + @Shared @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, value); try { // TODO avoid copying if possible. Note that it is possible that value is self PBytes bytes = PFactory.createBytes(language, bufferLib.getCopiedByteArray(value)); doSliceSequence(frame, self, slice, bytes, inliningTarget, differentLenProfile, getSequenceStorageNode, setItemSliceNode, sliceCast, unpack, adjustIndices, raiseNode); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -422,24 +424,24 @@ static PByteArray add(PByteArray self, PBytesLike other, return extendWithBuffer(self, other, inliningTarget, ensureCapacityNode, bufferLib, raiseNode); } - @Specialization(guards = "!isBytes(other)", limit = "3") + @Specialization(guards = "!isBytes(other)") static PByteArray add(VirtualFrame frame, PByteArray self, Object other, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("other") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @Shared @Cached SequenceStorageNodes.EnsureCapacityNode ensureCapacityNode, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Shared @Cached PRaiseNode raiseNode) { + @Shared @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { Object otherBuffer; try { - otherBuffer = bufferAcquireLib.acquireReadonly(other, frame, callData); + otherBuffer = getBuffer.executeReadonly(frame, other); } catch (PException e) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_CONCAT_P_TO_S, other, "bytearray"); } try { return extendWithBuffer(self, otherBuffer, inliningTarget, ensureCapacityNode, bufferLib, raiseNode); } finally { - bufferLib.release(otherBuffer, frame, callData); + releaseBuffer.execute(frame, otherBuffer); } } @@ -602,28 +604,29 @@ static PNone doBytes(VirtualFrame frame, PByteArray self, PBytesLike source, return PNone.NONE; } - @Specialization(guards = "!isBytes(source)", limit = "3") + @Specialization(guards = "!isBytes(source)") static PNone doGeneric(VirtualFrame frame, PByteArray self, Object source, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("source") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached InlinedConditionProfile bufferProfile, @Cached BytesNodes.IterableToByteNode iterableToByteNode, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached IsBuiltinObjectProfile errorProfile, @Cached("createExtend()") @Shared SequenceStorageNodes.ExtendNode extendNode, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { self.checkCanResize(inliningTarget, raiseNode); byte[] b; - if (bufferProfile.profile(inliningTarget, bufferAcquireLib.hasBuffer(source))) { - Object buffer = bufferAcquireLib.acquireReadonly(source, frame, callData); + if (bufferProfile.profile(inliningTarget, checkBufferNode.execute(source))) { + Object buffer = getBuffer.executeReadonly(frame, source); try { // TODO avoid copying b = bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } else { try { @@ -836,32 +839,33 @@ static boolean cmp(PByteArray self, PBytesLike other, RichCmpOp op, return compareByteArrays(op, getArray.execute(inliningTarget, selfStorage), selfStorage.length(), getArray.execute(inliningTarget, otherStorage), otherStorage.length()); } - @Specialization(guards = {"check.execute(inliningTarget, self)", "acquireLib.hasBuffer(other)"}, limit = "3") + @Specialization(guards = {"check.execute(inliningTarget, self)", "checkBufferNode.execute(other)"}, limit = "1") @InliningCutoff static Object cmp(VirtualFrame frame, Object self, Object other, RichCmpOp op, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @SuppressWarnings("unused") @Exclusive @Cached PyByteArrayCheckNode check, @Cached GetBytesStorage getBytesStorage, @Exclusive @Cached GetInternalByteArrayNode getArray, - @CachedLibrary("other") PythonBufferAcquireLibrary acquireLib, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { + @Exclusive @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { SequenceStorage selfStorage = getBytesStorage.execute(inliningTarget, self); - Object otherBuffer = acquireLib.acquireReadonly(other, frame, callData); + Object otherBuffer = getBuffer.executeReadonly(frame, other); try { return compareByteArrays(op, getArray.execute(inliningTarget, selfStorage), selfStorage.length(), bufferLib.getInternalOrCopiedByteArray(otherBuffer), bufferLib.getBufferLength(otherBuffer)); } finally { - bufferLib.release(otherBuffer); + releaseBuffer.execute(frame, otherBuffer); } } - @Specialization(guards = {"check.execute(inliningTarget, self)", "!acquireLib.hasBuffer(other)"}) + @Specialization(guards = {"check.execute(inliningTarget, self)", "!checkBufferNode.execute(other)"}, limit = "1") @SuppressWarnings("unused") static Object cmp(VirtualFrame frame, Object self, Object other, RichCmpOp op, @Bind Node inliningTarget, @Shared @Cached PyByteArrayCheckNode check, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib) { + @Exclusive @Cached PyObjectCheckBuffer checkBufferNode) { return PNotImplemented.NOT_IMPLEMENTED; } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java index 60f3a9bf04..218e6b8a56 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesBuiltins.java @@ -46,8 +46,6 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesBuiltinsClinicProviders.BytesNewNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes.AsCharPointerNode; @@ -64,9 +62,11 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckExactNode; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.RichCmpOp; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PNodeWithContext; @@ -82,7 +82,6 @@ import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.nativeaccess.NativeMemory; @@ -102,7 +101,6 @@ import com.oracle.truffle.api.dsl.NodeFactory; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.profiles.InlinedBranchProfile; import com.oracle.truffle.api.profiles.InlinedConditionProfile; @@ -236,18 +234,17 @@ static Object byteDone(VirtualFrame frame, Object self, Object[] arguments, PKey @Slot(value = SlotKind.tp_hash, isComplex = true) @GenerateNodeFactory abstract static class HashNode extends HashBuiltinNode { - @Specialization(limit = "3") + @Specialization static long hash(VirtualFrame frame, Object self, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("self") PythonBufferAcquireLibrary acquireLib, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached BytesNodes.HashBufferNode hashBufferNode) { - Object buffer = acquireLib.acquireReadonly(self, frame, callData); + @Cached PyObjectGetBuffer getBuffer, + @Cached BytesNodes.HashBufferNode hashBufferNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, self); try { return hashBufferNode.execute(inliningTarget, buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java index 5920ee72a9..a2d6d0f889 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesCommonBuiltins.java @@ -69,7 +69,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesCommonBuiltinsFactory.LStripNodeFactory; import com.oracle.graal.python.builtins.objects.bytes.BytesCommonBuiltinsFactory.RStripNodeFactory; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.BytesLikeCheck; @@ -89,8 +88,11 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotLen.LenBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyTupleCheckNode; import com.oracle.graal.python.lib.PyUnicodeCheckNode; import com.oracle.graal.python.nodes.ErrorMessages; @@ -113,7 +115,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; @@ -264,18 +265,18 @@ static PBytesLike add(PBytesLike self, PBytesLike other, } // @Exclusive for truffle-interpreted-performance - @Specialization(limit = "3") + @Specialization static PBytesLike add(VirtualFrame frame, Object self, Object other, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @Cached GetBytesStorage getBytesStorage, - @CachedLibrary("other") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Exclusive @Cached BytesNodes.CreateBytesNode create, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { Object otherBuffer; try { - otherBuffer = bufferAcquireLib.acquireReadonly(other, frame, callData); + otherBuffer = getBuffer.executeReadonly(frame, other); } catch (PException e) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.CANT_CONCAT_P_TO_P, other, self); } @@ -283,7 +284,7 @@ static PBytesLike add(VirtualFrame frame, Object self, Object other, SequenceStorage selfBuffer = getBytesStorage.execute(inliningTarget, self); return concatBuffers(self, selfBuffer, otherBuffer, inliningTarget, bufferLib, create, raiseNode); } finally { - bufferLib.release(otherBuffer, frame, callData); + releaseBuffer.execute(frame, otherBuffer); } } @@ -325,12 +326,12 @@ abstract static class ModNode extends BinaryOpBuiltinNode { static Object mod(VirtualFrame frame, Object self, Object right, @Bind Node inliningTarget, @SuppressWarnings("unused") @Cached BytesLikeCheck check, - @Cached("createFor($node)") InteropCallData interopCallData, @Cached("createFor($node)") BoundaryCallData boundaryCallData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached BytesNodes.CreateBytesNode create) { - Object buffer = acquireLib.acquireReadonly(self, frame, interopCallData); + @Cached BytesNodes.CreateBytesNode create, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, self); try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int bytesLen = bufferLib.getBufferLength(buffer); @@ -343,7 +344,7 @@ static Object mod(VirtualFrame frame, Object self, Object right, BoundaryCallContext.exit(frame, boundaryCallData, savedState); } } finally { - bufferLib.release(buffer, frame, interopCallData); + releaseBuffer.execute(frame, buffer); } } @@ -583,23 +584,23 @@ static int indexWithStartEnd(VirtualFrame frame, Object self, Object arg, int st @GenerateCached(false) public abstract static class PartitionAbstractNode extends PythonBinaryBuiltinNode { - @Specialization(limit = "3") + @Specialization @SuppressWarnings("truffle-static-method") // TODO: inh PTuple partition(VirtualFrame frame, Object self, Object sep, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("sep") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached GetBytesStorage getBytesStorage, @Cached InlinedConditionProfile notFound, @Cached BytesNodes.ToBytesNode toBytesNode, @Cached BytesNodes.CreateBytesNode createBytesNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); int len = storage.length(); byte[] bytes = toBytesNode.execute(frame, self); - Object sepBuffer = acquireLib.acquireReadonly(sep, frame, callData); + Object sepBuffer = getBuffer.executeReadonly(frame, sep); try { int lenSep = bufferLib.getBufferLength(sepBuffer); if (lenSep == 0) { @@ -632,7 +633,7 @@ PTuple partition(VirtualFrame frame, Object self, Object sep, } return PFactory.createTuple(language, new Object[]{first, second, third}); } finally { - bufferLib.release(sepBuffer, frame, callData); + releaseBuffer.execute(frame, sepBuffer); } } @@ -785,16 +786,16 @@ static byte pstring(Object strObj, return (byte) cp; } - @Specialization(guards = "bufferAcquireLib.hasBuffer(object)", limit = "3") + @Specialization(guards = "checkBufferNode.execute(object)", limit = "1") static byte doBuffer(VirtualFrame frame, Object object, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached PRaiseNode raiseNode) { - PythonContext context = PythonContext.get(inliningTarget); - PythonLanguage language = context.getLanguage(inliningTarget); - Object buffer = bufferAcquireLib.acquireReadonly(object, frame, context, language, callData); + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + + Object buffer = getBuffer.executeReadonly(frame, object); try { if (bufferLib.getBufferLength(buffer) != 1) { throw raiseNode.raise(inliningTarget, ValueError, SEP_MUST_BE_LENGTH_1); @@ -805,7 +806,7 @@ static byte doBuffer(VirtualFrame frame, Object object, } return b; } finally { - bufferLib.release(buffer, frame, context, language, callData); + releaseBuffer.execute(frame, buffer); } } @@ -876,10 +877,11 @@ static TruffleString err(Object self, Object sep, Object bytesPerSepGroup, abstract static class IsASCIINode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -895,7 +897,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return true; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -911,10 +913,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsAlnumNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -930,7 +933,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return true; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -946,10 +949,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsAlphaNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -965,7 +969,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return true; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -981,10 +985,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsDigitNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -1000,7 +1005,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return true; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -1016,10 +1021,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsLowerNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -1041,7 +1047,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return uncased == 0 || len > uncased; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -1057,10 +1063,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsUpperNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -1082,7 +1089,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return uncased == 0 || len > uncased; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -1098,10 +1105,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsSpaceNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -1117,7 +1125,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return true; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -1133,10 +1141,11 @@ protected ArgumentClinicProvider getArgumentClinic() { abstract static class IsTitleNode extends PythonUnaryClinicBuiltinNode { @Specialization(limit = "3") - static boolean check(Object buffer, + static boolean check(VirtualFrame frame, Object buffer, @Bind Node inliningTarget, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached InlinedConditionProfile earlyExit) { + @Cached InlinedConditionProfile earlyExit, + @Cached PyBufferRelease releaseBuffer) { try { int len = bufferLib.getBufferLength(buffer); if (earlyExit.profile(inliningTarget, len == 0)) { @@ -1167,7 +1176,7 @@ static boolean check(Object buffer, LoopNode.reportLoopCount(inliningTarget, len); return cased; } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } @@ -1311,7 +1320,7 @@ protected ArgumentClinicProvider getArgumentClinic() { } @Specialization - static PBytesLike replace(Object self, Object substrBuffer, Object replacementBuffer, int count, + static PBytesLike replace(VirtualFrame frame, Object self, Object substrBuffer, Object replacementBuffer, int count, @Bind Node inliningTarget, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached GetBytesStorage getBytesStorage, @@ -1319,7 +1328,8 @@ static PBytesLike replace(Object self, Object substrBuffer, Object replacementBu @Cached InlinedConditionProfile selfSubAreEmpty, @Cached InlinedConditionProfile selfIsEmpty, @Cached InlinedConditionProfile subIsEmpty, - @Cached BytesNodes.CreateBytesNode create) { + @Cached BytesNodes.CreateBytesNode create, + @Cached PyBufferRelease releaseBuffer) { try { SequenceStorage storage = getBytesStorage.execute(inliningTarget, self); int len = storage.length(); @@ -1339,8 +1349,8 @@ static PBytesLike replace(Object self, Object substrBuffer, Object replacementBu byte[] newBytes = replace(bytes, len, subBytes, replacementBytes, maxcount); return create.execute(inliningTarget, self, newBytes); } finally { - bufferLib.release(substrBuffer); - bufferLib.release(replacementBuffer); + releaseBuffer.execute(frame, substrBuffer); + releaseBuffer.execute(frame, replacementBuffer); } } @@ -1522,20 +1532,18 @@ byte[] handleNone(@SuppressWarnings("unused") PNone none) { return defaultValue; } - @Specialization(guards = {"!isPNone(object)"}, limit = "3") + @Specialization(guards = {"!isPNone(object)"}) static byte[] doBuffer(VirtualFrame frame, Object object, - @Bind Node inliningTarget, - @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) { - PythonLanguage language = context.getLanguage(inliningTarget); - Object buffer = bufferAcquireLib.acquireReadonly(object, frame, context, language, callData); + @Cached PyObjectGetBuffer getBuffer, + @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { + + Object buffer = getBuffer.executeReadonly(frame, object); try { // TODO avoid copying return bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer, frame, context, language, callData); + releaseBuffer.execute(frame, buffer); } } @@ -1900,19 +1908,19 @@ PBytesLike strip(VirtualFrame frame, Object self, @SuppressWarnings("unused") PN @Specialization(guards = "!isPNone(object)") PBytesLike strip(VirtualFrame frame, Object self, Object object, @Bind Node node, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Shared("createByte") @Cached BytesNodes.CreateBytesNode create, - @Shared("toByteSelf") @Cached BytesNodes.ToBytesNode selfToBytesNode) { - Object buffer = bufferAcquireLib.acquireReadonly(object, frame, callData); + @Shared("toByteSelf") @Cached BytesNodes.ToBytesNode selfToBytesNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, object); try { byte[] stripBs = bufferLib.getInternalOrCopiedByteArray(buffer); int stripBsLen = bufferLib.getBufferLength(buffer); byte[] bs = selfToBytesNode.execute(frame, self); return create.execute(node, self, getResultBytes(bs, findIndex(bs, stripBs, stripBsLen))); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -2328,14 +2336,14 @@ abstract static class RemovePrefixNode extends PythonBinaryBuiltinNode { @Specialization static PBytesLike remove(VirtualFrame frame, Object self, Object prefix, @Bind Node node, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "1") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.CreateBytesNode create, - @Cached InlinedConditionProfile profile) { + @Cached InlinedConditionProfile profile, + @Cached PyBufferRelease releaseBuffer) { - Object selfBuffer = bufferAcquireLib.acquireReadonly(self, frame, callData); - Object prefixBuffer = bufferAcquireLib.acquireReadonly(prefix, frame, callData); + Object selfBuffer = getBuffer.executeReadonly(frame, self); + Object prefixBuffer = getBuffer.executeReadonly(frame, prefix); try { int selfBsLen = bufferLib.getBufferLength(selfBuffer); int prefixBsLen = bufferLib.getBufferLength(prefixBuffer); @@ -2360,8 +2368,8 @@ static PBytesLike remove(VirtualFrame frame, Object self, Object prefix, } return create.execute(node, self, PythonUtils.arrayCopyOf(selfBs, selfBsLen)); } finally { - bufferLib.release(selfBuffer, frame, callData); - bufferLib.release(prefixBuffer, frame, callData); + releaseBuffer.execute(frame, selfBuffer); + releaseBuffer.execute(frame, prefixBuffer); } } } @@ -2372,13 +2380,13 @@ abstract static class RemoveSuffixNode extends PythonBinaryBuiltinNode { @Specialization static PBytesLike remove(VirtualFrame frame, Object self, Object suffix, @Bind Node node, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "1") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.CreateBytesNode create, - @Cached InlinedConditionProfile profile) { - Object selfBuffer = bufferAcquireLib.acquireReadonly(self, frame, callData); - Object suffixBuffer = bufferAcquireLib.acquireReadonly(suffix, frame, callData); + @Cached InlinedConditionProfile profile, + @Cached PyBufferRelease releaseBuffer) { + Object selfBuffer = getBuffer.executeReadonly(frame, self); + Object suffixBuffer = getBuffer.executeReadonly(frame, suffix); try { int selfBsLen = bufferLib.getBufferLength(selfBuffer); int suffixBsLen = bufferLib.getBufferLength(suffixBuffer); @@ -2403,8 +2411,8 @@ static PBytesLike remove(VirtualFrame frame, Object self, Object suffix, } return create.execute(node, self, PythonUtils.arrayCopyOf(selfBs, selfBsLen)); } finally { - bufferLib.release(selfBuffer, frame, callData); - bufferLib.release(suffixBuffer, frame, callData); + releaseBuffer.execute(frame, selfBuffer); + releaseBuffer.execute(frame, suffixBuffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java index e9b7eae418..23fcc2aaf6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/BytesNodes.java @@ -68,9 +68,7 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodesFactory.ToBytesNodeGen; -import com.oracle.graal.python.builtins.objects.bytes.BytesNodesFactory.ToBytesWithoutFrameNodeGen; import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.GetInternalByteArrayNode; @@ -78,12 +76,15 @@ import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.builtins.objects.str.StringNodes; import com.oracle.graal.python.lib.IteratorExhausted; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyByteArrayCheckNode; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyIterNextNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyOSFSPathNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyUnicodeCheckNode; import com.oracle.graal.python.lib.RichCmpOp; @@ -99,7 +100,6 @@ import com.oracle.graal.python.nodes.object.GetClassNode; import com.oracle.graal.python.nodes.util.CastToByteNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonOptions; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.exception.PythonErrorType; @@ -251,24 +251,24 @@ byte[] doBytes(PBytesLike bytes, return bufferLib.getCopiedByteArray(bytes); } - @Specialization(limit = "3") + @Specialization @SuppressWarnings("truffle-static-method") // TODO: arg byte[] doBuffer(VirtualFrame frame, Object object, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { Object buffer; try { - buffer = bufferAcquireLib.acquireReadonly(object, frame, callData); + buffer = getBuffer.executeReadonly(frame, object); } catch (PException e) { throw raiseNode.raise(inliningTarget, errorType, errorMessageFormat, object); } try { return bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -282,36 +282,6 @@ public static ToBytesNode create(PythonBuiltinClassType errorType, TruffleString } } - @GenerateUncached - @GenerateInline - @GenerateCached(false) - public abstract static class ToBytesWithoutFrameNode extends Node { - - public abstract byte[] execute(Node inliningTarget, Object object); - - public static byte[] executeUncached(Object object) { - return ToBytesWithoutFrameNodeGen.getUncached().execute(null, object); - } - - @Specialization(limit = "3") - static byte[] doBuffer(Node inliningTarget, Object object, - @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, - @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { - Object buffer; - try { - buffer = bufferAcquireLib.acquireReadonly(object); - } catch (PException e) { - throw raiseNode.raise(inliningTarget, TypeError, EXPECTED_BYTESLIKE_GOT_P, object); - } - try { - return bufferLib.getCopiedByteArray(buffer); - } finally { - bufferLib.release(buffer); - } - } - } - @GenerateInline @GenerateCached(false) public abstract static class NeedleToBytesNode extends PNodeWithContext { @@ -324,16 +294,17 @@ static byte[] number(VirtualFrame frame, Node inliningTarget, Object needle, return new byte[]{castToByteNode.execute(frame, needle)}; } - @Specialization(guards = "!indexCheck.execute(inliningTarget, needle)", limit = "3") - static byte[] bytesLike(Node inliningTarget, Object needle, + @Specialization(guards = "!indexCheck.execute(inliningTarget, needle)") + static byte[] bytesLike(VirtualFrame frame, Node inliningTarget, Object needle, @SuppressWarnings("unused") @Shared @Cached PyIndexCheckNode indexCheck, - @CachedLibrary("needle") PythonBufferAcquireLibrary acquireLib, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { - Object buffer = acquireLib.acquireReadonly(needle); + @Cached PyObjectGetBuffer getBuffer, + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(null, needle); try { return bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } } @@ -565,20 +536,21 @@ public abstract static class BytesFromObject extends Node { @Specialization static byte[] doGeneric(VirtualFrame frame, Object object, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached BytesNodes.IterableToByteNode iterableToByteNode, @Cached IsBuiltinObjectProfile errorProfile, @Cached PyUnicodeCheckNode unicodeCheckNode, - @Cached PRaiseNode raiseNode) { - if (bufferAcquireLib.hasBuffer(object)) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + if (checkBufferNode.execute(object)) { // TODO PyBUF_FULL_RO - Object buffer = bufferAcquireLib.acquire(object, BufferFlags.PyBUF_ND, frame, callData); + Object buffer = getBuffer.execute(frame, object, BufferFlags.PyBUF_ND); try { return bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } if (!unicodeCheckNode.execute(inliningTarget, object)) { @@ -607,16 +579,17 @@ public abstract static class BytesRangeFromObject extends Node { @Specialization static byte[] doGeneric(VirtualFrame frame, Object object, int from, int to, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { - if (bufferAcquireLib.hasBuffer(object)) { - Object buffer = bufferAcquireLib.acquire(object, BufferFlags.PyBUF_ND, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + if (checkBufferNode.execute(object)) { + Object buffer = getBuffer.execute(frame, object, BufferFlags.PyBUF_ND); try { return bufferLib.getCopyOfRange(buffer, from, to); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -852,16 +825,17 @@ public abstract static class DecodeUTF8FSPathNode extends Node { @Specialization static TruffleString doit(VirtualFrame frame, Object value, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached CastToTruffleStringNode toString, @Cached PyOSFSPathNode fsPath, @Cached TruffleString.FromByteArrayNode fromByteArrayNode, - @Cached TruffleString.SwitchEncodingNode switchEncodingNode) { + @Cached TruffleString.SwitchEncodingNode switchEncodingNode, + @Cached PyBufferRelease releaseBuffer) { Object path = fsPath.execute(frame, inliningTarget, value); - if (bufferAcquireLib.hasBuffer(path)) { - Object buffer = bufferAcquireLib.acquireReadonly(path, frame, callData); + if (checkBufferNode.execute(path)) { + Object buffer = getBuffer.executeReadonly(frame, path); try { /*- * This should be equivalent to PyUnicode_EncodeFSDefault @@ -871,7 +845,7 @@ static TruffleString doit(VirtualFrame frame, Object value, TruffleString utf8 = fromByteArrayNode.execute(bufferLib.getCopiedByteArray(path), Encoding.UTF_8, false); return switchEncodingNode.execute(utf8, TS_ENCODING); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } return toString.execute(inliningTarget, path); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java index 64ed9117de..9cc311be5a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2025, Oracle and/or its affiliates. + * Copyright (c) 2017, 2026, Oracle and/or its affiliates. * Copyright (c) 2014, Regents of the University of California * * All rights reserved. @@ -25,29 +25,20 @@ */ package com.oracle.graal.python.builtins.objects.bytes; -import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BufferError; import static com.oracle.graal.python.util.PythonUtils.builtinClassToType; -import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; -import com.oracle.graal.python.nodes.ErrorMessages; -import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.truffle.api.CompilerAsserts; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.InvalidArrayIndexException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.library.ExportLibrary; import com.oracle.truffle.api.library.ExportMessage; -import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; @SuppressWarnings("truffle-abstract-export") @ExportLibrary(InteropLibrary.class) -@ExportLibrary(PythonBufferAcquireLibrary.class) public final class PBytes extends PBytesLike { public PBytes(Object cls, Shape instanceShape, byte[] bytes) { @@ -99,13 +90,4 @@ public static void removeArrayElement(PBytes self, long key) throws UnsupportedM throw UnsupportedMessageException.create(); } - @ExportMessage - Object acquire(int flags, - @Bind Node inliningTarget, - @Cached PRaiseNode raiseNode) { - if ((flags & BufferFlags.PyBUF_WRITABLE) != 0) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.OBJ_IS_NOT_WRITABLE); - } - return this; - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java index 89a05af434..cf600edf41 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/PBytesLike.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, 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 @@ -43,7 +43,6 @@ import java.nio.ByteOrder; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.cext.capi.PySequenceArrayWrapper; import com.oracle.graal.python.runtime.sequence.PSequence; import com.oracle.graal.python.runtime.sequence.storage.ByteSequenceStorage; @@ -59,7 +58,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; -@ExportLibrary(PythonBufferAcquireLibrary.class) @ExportLibrary(PythonBufferAccessLibrary.class) public abstract class PBytesLike extends PSequence { @@ -87,17 +85,6 @@ public void setSequenceStorage(SequenceStorage store) { this.store = store; } - @ExportMessage - @SuppressWarnings("static-method") - boolean hasBuffer() { - return true; - } - - @ExportMessage - Object acquire(@SuppressWarnings("unused") int flags) { - return this; - } - @ExportMessage @SuppressWarnings("static-method") boolean isBuffer() { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java index b79b75fab8..9a7268a2d2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/PythonAbstractNativeObject.java @@ -43,11 +43,8 @@ import static com.oracle.graal.python.builtins.objects.cext.structs.CFields.PyTypeObject__tp_name; import com.oracle.graal.python.builtins.objects.PythonAbstractObject; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; -import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTransitions.NativeObjectReference; import com.oracle.graal.python.builtins.objects.cext.structs.CStructAccess; -import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; @@ -79,7 +76,6 @@ * A simple wrapper around objects created through the Python C API that can be cast to PyObject*. */ @ExportLibrary(InteropLibrary.class) -@ExportLibrary(PythonBufferAcquireLibrary.class) public final class PythonAbstractNativeObject extends PythonAbstractObject implements PythonNativeObject, PythonNativeClass { /** @@ -278,19 +274,4 @@ String getMetaQualifiedName( } } - @ExportMessage - boolean hasBuffer( - @Bind Node inliningTarget, - @Cached CExtNodes.HasNativeBufferNode hasNativeBuffer) { - return hasNativeBuffer.execute(inliningTarget, this); - } - - @ExportMessage - Object acquire(int flags, - @Bind Node inliningTarget, - @Cached CExtNodes.CreateMemoryViewFromNativeNode createMemoryView) { - PMemoryView mv = createMemoryView.execute(inliningTarget, this, flags); - mv.setShouldReleaseImmediately(true); - return mv; - } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java index 646e55a2ea..2b1dea273a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CExtNodes.java @@ -1377,10 +1377,11 @@ static boolean readTpAsBuffer(PythonAbstractNativeObject object) { public abstract static class CreateMemoryViewFromNativeNode extends PNodeWithContext { private static final CApiTiming C_API_TIMING = CApiTiming.create(true, FUN_GRAALPY_MEMORYVIEW_FROM_OBJECT); - public abstract PMemoryView execute(Node inliningTarget, PythonNativeObject object, int flags); + public abstract PMemoryView execute(VirtualFrame frame, Node inliningTarget, PythonNativeObject object, int flags); @Specialization - static PMemoryView fromNative(Node inliningTarget, PythonNativeObject buf, int flags, + static PMemoryView fromNative(VirtualFrame frame, Node inliningTarget, PythonNativeObject buf, int flags, + @Cached("createFor($node)") BoundaryCallData callData, @Cached PythonToNativeInternalNode toNativeNode, @Cached NativeToPythonInternalNode asPythonObjectNode, @Cached(inline = false) PyObjectCheckFunctionResultNode checkFunctionResultNode) { @@ -1388,7 +1389,7 @@ static PMemoryView fromNative(Node inliningTarget, PythonNativeObject buf, int f try { PythonContext context = PythonContext.get(inliningTarget); var callable = CApiContext.getNativeSymbol(inliningTarget, FUN_GRAALPY_MEMORYVIEW_FROM_OBJECT); - long result = ExternalFunctionInvoker.invokeGRAALPY_MEMORYVIEW_FROM_OBJECT(null, C_API_TIMING, context.ensureNativeContext(), BoundaryCallData.getUncached(), + long result = ExternalFunctionInvoker.invokeGRAALPY_MEMORYVIEW_FROM_OBJECT(frame, C_API_TIMING, context.ensureNativeContext(), callData, context.getThreadState(PythonLanguage.get(inliningTarget)), callable, bufPointer, flags); return (PMemoryView) checkFunctionResultNode.execute(context, FUN_GRAALPY_MEMORYVIEW_FROM_OBJECT.getTsName(), asPythonObjectNode.executeTransfer(inliningTarget, result)); } finally { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java index 52fa99d8bf..fc443384e2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/code/CodeBuiltins.java @@ -57,6 +57,7 @@ import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotHashFun.HashBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotRichCompare.RichCmpBuiltinNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyObjectGetIter; import com.oracle.graal.python.lib.PyObjectHashNode; @@ -73,7 +74,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -648,10 +648,10 @@ static PCode create(VirtualFrame frame, PCode self, int coArgcount, TruffleString coName, TruffleString coQualname, Object coLnotab, @SuppressWarnings("unused") Object coExceptiontable, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @Cached CodeNodes.CreateCodeNode createCodeNode, @Cached CastToTruffleStringNode castToTruffleStringNode, - @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib) { + @CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { try { return createCodeNode.execute(frame, coArgcount == -1 ? self.co_argcount() : coArgcount, @@ -673,10 +673,10 @@ static PCode create(VirtualFrame frame, PCode self, int coArgcount, PGuards.isNone(coLnotab) ? self.getLinetable() : bufferLib.getInternalOrCopiedByteArray(coLnotab)); } finally { if (!PGuards.isNone(coCode)) { - bufferLib.release(coCode, frame, callData); + releaseBuffer.execute(frame, coCode); } if (!PGuards.isNone(coLnotab)) { - bufferLib.release(coLnotab, frame, callData); + releaseBuffer.execute(frame, coLnotab); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java index 9948488e2a..10338e9bd9 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/exception/UnicodeErrorBuiltins.java @@ -51,9 +51,10 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.ints.PInt; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; @@ -62,7 +63,6 @@ import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; import com.oracle.graal.python.nodes.util.CastToJavaLongExactNode; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Bind; @@ -138,17 +138,17 @@ static PBytes doBytes(PBytes value) { return value; } - @Specialization(guards = {"!isPBytes(value)", "!isString(value)"}, limit = "3") + @Specialization(guards = {"!isPBytes(value)", "!isString(value)"}) static PBytes doOther(VirtualFrame frame, Object value, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("value") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "getCallSiteInlineCacheMaxDepth()") PythonBufferAccessLibrary bufferLib, - @Bind PythonLanguage language) { - Object buffer = acquireLib.acquireReadonly(value, frame, callData); + @Bind PythonLanguage language, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, value); try { return PFactory.createBytes(language, bufferLib.getCopiedByteArray(buffer)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java index d259aca3b5..d0fd7fa738 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/MemoryViewNodes.java @@ -50,6 +50,7 @@ import com.oracle.graal.python.builtins.objects.cext.capi.CApiContext; import com.oracle.graal.python.builtins.objects.cext.capi.ExternalFunctionInvoker; import com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol; +import com.oracle.graal.python.builtins.objects.cext.capi.transitions.CApiTiming; import com.oracle.graal.python.builtins.objects.common.BufferStorageNodes; import com.oracle.graal.python.builtins.objects.common.SequenceNodes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; @@ -58,7 +59,6 @@ import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyTupleCheckNode; -import com.oracle.graal.python.runtime.nativeaccess.NativeMemory; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PGuards; import com.oracle.graal.python.nodes.PRaiseNode; @@ -66,10 +66,11 @@ import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.BuiltinClassProfiles.IsBuiltinObjectProfile; import com.oracle.graal.python.nodes.util.CastToByteNode; -import com.oracle.graal.python.runtime.ExecutionContext.InteropCallContext; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; +import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; +import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; +import com.oracle.graal.python.runtime.nativeaccess.NativeMemory; import com.oracle.graal.python.runtime.sequence.storage.NativeByteSequenceStorage; import com.oracle.graal.python.runtime.sequence.storage.SequenceStorage; import com.oracle.graal.python.util.BufferFormat; @@ -570,6 +571,7 @@ public static ToJavaBytesFortranOrderNode create() { } } + @GenerateUncached @GenerateInline(false) // footprint reduction 36 -> 17 public abstract static class ReleaseNode extends Node { @@ -590,12 +592,11 @@ static void releaseSimple(PMemoryView self, @Specialization(guards = {"self.getReference() != null"}) static void releaseNative(VirtualFrame frame, PMemoryView self, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @Cached ReleaseBufferNode releaseNode, @Exclusive @Cached PRaiseNode raiseNode) { self.checkExports(inliningTarget, raiseNode); if (self.checkShouldReleaseBuffer()) { - releaseNode.execute(frame, inliningTarget, callData, self.getLifecycleManager()); + releaseNode.execute(frame, inliningTarget, self.getLifecycleManager()); } self.setReleased(); } @@ -606,36 +607,31 @@ static void releaseNative(VirtualFrame frame, PMemoryView self, @GenerateCached(false) public abstract static class ReleaseBufferNode extends Node { - public abstract void execute(Node inliningTarget, BufferLifecycleManager buffer); + private static final CApiTiming C_API_TIMING = CApiTiming.create(true, NativeCAPISymbol.FUN_GRAALPY_RELEASE_BUFFER); - public static void executeUncached(BufferLifecycleManager buffer) { - MemoryViewNodesFactory.ReleaseBufferNodeGen.getUncached().execute(null, buffer); - } + public abstract void execute(VirtualFrame frame, Node inliningTarget, BufferLifecycleManager buffer); - public final void execute(VirtualFrame frame, Node inliningTarget, InteropCallData callData, BufferLifecycleManager buffer) { - Object state = InteropCallContext.enter(frame, inliningTarget, callData); - try { - execute(inliningTarget, buffer); - } finally { - InteropCallContext.exit(frame, inliningTarget, callData, state); - } + public static void executeUncached(BufferLifecycleManager buffer) { + MemoryViewNodesFactory.ReleaseBufferNodeGen.getUncached().execute(null, null, buffer); } @Specialization - static void doCApiCached(NativeBufferLifecycleManager.NativeBufferLifecycleManagerFromType buffer, - @Bind Node inliningTarget) { + static void doCApiCached(VirtualFrame frame, NativeBufferLifecycleManager.NativeBufferLifecycleManagerFromType buffer, + @Bind Node inliningTarget, + @Cached("createFor($node)") BoundaryCallData callData) { + Object savedState = BoundaryCallContext.enter(frame, callData); try { - ExternalFunctionInvoker.invokeGRAALPY_RELEASE_BUFFER(CApiContext.getNativeSymbol(inliningTarget, NativeCAPISymbol.FUN_GRAALPY_RELEASE_BUFFER).getAddress(), - buffer.bufferStructPointer); - } catch (Throwable t) { - throw CompilerDirectives.shouldNotReachHere(t); + var callable = CApiContext.getNativeSymbol(inliningTarget, NativeCAPISymbol.FUN_GRAALPY_RELEASE_BUFFER); + ExternalFunctionInvoker.invokeGRAALPY_RELEASE_BUFFER(C_API_TIMING, callable, buffer.bufferStructPointer); + } finally { + BoundaryCallContext.exit(frame, callData, savedState); } } @Specialization - static void doCExtBuffer(NativeBufferLifecycleManagerFromSlot buffer, + static void doCExtBuffer(VirtualFrame frame, NativeBufferLifecycleManagerFromSlot buffer, @Cached(inline = false) CallNode callNode) { - callNode.executeWithoutFrame(buffer.releaseFunction, buffer.self, buffer.buffer); + callNode.execute(frame, buffer.releaseFunction, buffer.self, buffer.buffer); } @Fallback diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java index 6fb2524ae9..1d285c8fee 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/memoryview/PMemoryView.java @@ -47,17 +47,12 @@ import java.nio.ByteOrder; import java.util.concurrent.atomic.AtomicLong; -import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; -import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewNodes.ReleaseBufferNode; import com.oracle.graal.python.builtins.objects.object.PythonBuiltinObject; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.util.BufferFormat; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.Cached.Shared; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.library.ExportLibrary; @@ -68,7 +63,6 @@ import com.oracle.truffle.api.strings.TruffleString; // TODO interop library -@ExportLibrary(PythonBufferAcquireLibrary.class) @ExportLibrary(PythonBufferAccessLibrary.class) public final class PMemoryView extends PythonBuiltinObject { public static final int MAX_DIM = 64; @@ -276,68 +270,13 @@ boolean isBuffer() { return true; } - @ExportMessage - @SuppressWarnings("static-method") - boolean hasBuffer() { - return true; - } - @ExportMessage int getBufferLength() { return getLength(); } - @ExportMessage - Object acquire(int requestedFlags, - @Bind Node inliningTarget, - @Cached PRaiseNode raiseNode) { - checkReleased(inliningTarget, raiseNode); - if (BufferFlags.requestsWritable(requestedFlags) && readonly) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_WRITABLE); - } - if (BufferFlags.requestsCContiguous(requestedFlags) && !isCContiguous()) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS); - } - if (BufferFlags.requestsFContiguous(requestedFlags) && !isFortranContiguous()) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_FORTRAN_CONTIGUOUS); - } - if (BufferFlags.requestsAnyContiguous(requestedFlags) && !isAnyContiguous()) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_CONTIGUOUS); - } - if (!BufferFlags.requestsIndirect(requestedFlags) && (flags & FLAG_PIL) != 0) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_REQUIRES_SUBOFFSETS); - } - if (!BufferFlags.requestsStrides(requestedFlags) && !isCContiguous()) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS); - } - // TODO should reflect the cast to unsigned bytes if necessary - if (!BufferFlags.requestsShape(requestedFlags) && BufferFlags.requestsFormat(requestedFlags)) { - throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_CANNOT_CAST_UNSIGNED_BYTES_IF_FMT_FLAG); - } - exports.incrementAndGet(); - return this; - } - - @ExportMessage - void release( - @Bind Node inliningTarget, - @Cached PRaiseNode raiseNode, - @Cached ReleaseBufferNode releaseNode) { - /* - * This is a bit hacky - the shouldReleaseImmediately marker is used when this is a helper - * memoryview that was created to hold a buffer for native object. In the future there - * should be no such helper memoryviews, the C buffer should have a separate implementation. - */ - if (shouldReleaseImmediately) { - checkExports(inliningTarget, raiseNode); - if (checkShouldReleaseBuffer()) { - releaseNode.execute(inliningTarget, getLifecycleManager()); - } - setReleased(); - } else { - long l = exports.decrementAndGet(); - assert l >= 0; - } + public boolean shouldReleaseImmediately() { + return shouldReleaseImmediately; } @ExportMessage diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java index 86fbf6dfb0..042d63b393 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/MMapBuiltins.java @@ -86,7 +86,6 @@ import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes; @@ -109,11 +108,13 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotMpAssSubscript.MpAssSubscriptBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqAssItem.SqAssItemBuiltinNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckNode; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyLongAsIntNode; import com.oracle.graal.python.lib.PyLongAsLongNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectIsTrueNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; @@ -132,7 +133,6 @@ import com.oracle.graal.python.nodes.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.AsyncHandler; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupport.PosixException; import com.oracle.graal.python.runtime.PythonContext; @@ -527,13 +527,14 @@ static void doSingle(VirtualFrame frame, PMMap self, Object idxObj, Object value static void doSlice(VirtualFrame frame, PMMap self, PSlice slice, Object valueObj, @Bind Node inliningTarget, @Bind PythonContext context, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached SliceNodes.SliceUnpack sliceUnpack, @Cached SliceNodes.AdjustIndices adjustIndices, @Cached InlinedConditionProfile step1Profile, @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { if (self.isClosed()) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.ValueError, MMAP_CLOSED_OR_INVALID); } @@ -550,7 +551,7 @@ static void doSlice(VirtualFrame frame, PMMap self, PSlice slice, Object valueOb if (valueObj == PNone.NO_VALUE) { throw raiseNode.raise(inliningTarget, PythonBuiltinClassType.TypeError, MMAP_OBJECT_DOESNT_SUPPORT_SLICE_DELETION); } - Object buffer = acquireLib.acquireReadonly(valueObj); + Object buffer = getBuffer.executeReadonly(frame, valueObj); try { int bufferLen = bufferLib.getBufferLength(buffer); if (info.sliceLength != bufferLen) { @@ -572,7 +573,7 @@ static void doSlice(VirtualFrame frame, PMMap self, PSlice slice, Object valueOb } } } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } } @@ -807,10 +808,10 @@ protected ArgumentClinicProvider getArgumentClinic() { static int doIt(VirtualFrame frame, PMMap self, Object dataBuffer, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("dataBuffer") PythonBufferAccessLibrary bufferLib, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (!self.isWriteable()) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.MMAP_CANNOT_MODIFY_READONLY_MEMORY); @@ -826,7 +827,7 @@ static int doIt(VirtualFrame frame, PMMap self, Object dataBuffer, } catch (PosixException e) { throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } finally { - bufferLib.release(dataBuffer, frame, callData); + releaseBuffer.execute(frame, dataBuffer); } } } @@ -893,12 +894,12 @@ protected ArgumentClinicProvider getArgumentClinic() { static long find(VirtualFrame frame, PMMap self, Object subBuffer, Object startIn, Object endIn, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("subBuffer") PythonBufferAccessLibrary bufferLib, @Cached LongIndexConverterNode startConverter, @Cached LongIndexConverterNode endConverter, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { long start = normalizeIndex(frame, startConverter, startIn, self.getLength(), self.getPos()); long end = normalizeIndex(frame, endConverter, endIn, self.getLength(), self.getLength()); @@ -952,7 +953,7 @@ static long find(VirtualFrame frame, PMMap self, Object subBuffer, Object startI } return -1; } finally { - bufferLib.release(subBuffer, frame, callData); + releaseBuffer.execute(frame, subBuffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/PMMap.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/PMMap.java index fa45827226..276c7571f2 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/PMMap.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/mmap/PMMap.java @@ -43,7 +43,6 @@ import static com.oracle.graal.python.runtime.nativeaccess.NativeMemory.NULLPTR; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.object.PythonObject; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; @@ -61,7 +60,6 @@ import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.object.Shape; -@ExportLibrary(PythonBufferAcquireLibrary.class) @ExportLibrary(PythonBufferAccessLibrary.class) public final class PMMap extends PythonObject { public static final int ACCESS_DEFAULT = 0; @@ -164,17 +162,6 @@ void writeByte(int byteOffset, byte value, } } - @ExportMessage - Object acquire(@SuppressWarnings("unused") int flags) { - return this; - } - - @ExportMessage - @SuppressWarnings("static-method") - boolean hasBuffer() { - return true; - } - static class MMapRef extends AsyncHandler.SharedFinalizer.FinalizableReference { final int fd; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java index 30a2474890..ef72bda48f 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketBuiltins.java @@ -72,14 +72,15 @@ import com.oracle.graal.python.builtins.modules.SysModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.exception.OSErrorEnum; import com.oracle.graal.python.builtins.objects.socket.SocketUtils.TimeoutHelper; import com.oracle.graal.python.builtins.objects.str.StringUtils.SimpleTruffleStringFormatNode; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsIntNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; @@ -94,7 +95,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixConstants; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupport.PosixErrnoException; @@ -701,17 +701,17 @@ protected ArgumentClinicProvider getArgumentClinic() { @ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") @GenerateNodeFactory abstract static class RecvIntoNode extends PythonQuaternaryClinicBuiltinNode { - @Specialization(limit = "3") + @Specialization static Object recvInto(VirtualFrame frame, PSocket socket, Object bufferObj, int recvlenIn, int flags, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireWritable(bufferObj, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeWritable(frame, bufferObj); try { if (recvlenIn < 0) { throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECV_INTO); @@ -752,7 +752,7 @@ static Object recvInto(VirtualFrame frame, PSocket socket, Object bufferObj, int throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(bufferObj, frame, callData); + releaseBuffer.execute(frame, bufferObj); } } @@ -768,18 +768,18 @@ protected ArgumentClinicProvider getArgumentClinic() { @ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") @GenerateNodeFactory abstract static class RecvFromIntoNode extends PythonQuaternaryClinicBuiltinNode { - @Specialization(limit = "3") + @Specialization static Object recvFromInto(VirtualFrame frame, PSocket socket, Object bufferObj, int recvlenIn, int flags, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached GilNode gil, @Cached SocketNodes.MakeSockAddrNode makeSockAddrNode, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireWritable(bufferObj, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeWritable(frame, bufferObj); try { if (recvlenIn < 0) { throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.NEG_BUFF_SIZE_IN_RECVFROM_INTO); @@ -819,7 +819,7 @@ static Object recvFromInto(VirtualFrame frame, PSocket socket, Object bufferObj, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -834,17 +834,17 @@ protected ArgumentClinicProvider getArgumentClinic() { @ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") @GenerateNodeFactory abstract static class SendNode extends PythonTernaryClinicBuiltinNode { - @Specialization(limit = "3") + @Specialization static int send(VirtualFrame frame, PSocket socket, Object bufferObj, int flags, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireReadonly(bufferObj, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, bufferObj); try { checkSelectable(inliningTarget, raiseNode, socket); @@ -859,7 +859,7 @@ static int send(VirtualFrame frame, PSocket socket, Object bufferObj, int flags, throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -874,17 +874,17 @@ protected ArgumentClinicProvider getArgumentClinic() { @ArgumentClinic(name = "flags", conversion = ArgumentClinic.ClinicConversion.Int, defaultValue = "0") @GenerateNodeFactory abstract static class SendAllNode extends PythonTernaryClinicBuiltinNode { - @Specialization(limit = "3") + @Specialization static Object sendAll(VirtualFrame frame, PSocket socket, Object bufferObj, int flags, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireReadonly(bufferObj, frame, callData); + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, bufferObj); try { checkSelectable(inliningTarget, raiseNode, socket); @@ -917,7 +917,7 @@ static Object sendAll(VirtualFrame frame, PSocket socket, Object bufferObj, int } } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -932,12 +932,11 @@ protected ArgumentClinicProvider getArgumentClinic() { @Builtin(name = "sendto", minNumOfPositionalArgs = 3, maxNumOfPositionalArgs = 4) @GenerateNodeFactory abstract static class SendToNode extends PythonBuiltinNode { - @Specialization(limit = "3") + @Specialization static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Object flagsOrAddress, Object maybeAddress, @Bind Node inliningTarget, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Cached InlinedConditionProfile hasFlagsProfile, @Cached PyLongAsIntNode asIntNode, @@ -945,7 +944,8 @@ static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Objec @Cached SysModuleBuiltins.AuditNode auditNode, @Cached GilNode gil, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { int flags; Object address; if (hasFlagsProfile.profile(inliningTarget, maybeAddress == PNone.NO_VALUE)) { @@ -956,7 +956,7 @@ static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Objec flags = asIntNode.execute(frame, inliningTarget, flagsOrAddress); } - Object buffer = bufferAcquireLib.acquireReadonly(bufferObj, frame, callData); + Object buffer = getBuffer.executeReadonly(frame, bufferObj); try { checkSelectable(inliningTarget, raiseNode, socket); @@ -974,7 +974,7 @@ static Object sendTo(VirtualFrame frame, PSocket socket, Object bufferObj, Objec throw constructAndRaiseNode.get(inliningTarget).raiseOSErrorFromPosixException(frame, e); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } @@ -1108,12 +1108,12 @@ abstract static class SetSockOptNode extends PythonClinicBuiltinNode { @Specialization(guards = "isNoValue(none)") static Object setInt(VirtualFrame frame, PSocket socket, int level, int option, Object value, @SuppressWarnings("unused") PNone none, @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Bind Node inliningTarget, @Exclusive @Cached PyLongAsIntNode asIntNode, - @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode) { + @Exclusive @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, + @Cached PyBufferRelease releaseBuffer) { byte[] bytes; int len; try { @@ -1122,12 +1122,12 @@ static Object setInt(VirtualFrame frame, PSocket socket, int level, int option, len = bytes.length; PythonUtils.ARRAY_ACCESSOR.putInt(bytes, 0, flag); } catch (PException e) { - Object buffer = bufferAcquireLib.acquireReadonly(value, frame, callData); + Object buffer = getBuffer.executeReadonly(frame, value); try { len = bufferLib.getBufferLength(buffer); bytes = bufferLib.getInternalOrCopiedByteArray(buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java index 6656fab1cd..a7d0b0a2e6 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/socket/SocketNodes.java @@ -66,9 +66,10 @@ import com.oracle.graal.python.builtins.modules.CodecsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesNodes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyLongAsIntNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyTimeFromObjectNode; import com.oracle.graal.python.lib.PyTimeFromObjectNode.RoundType; import com.oracle.graal.python.lib.PyTupleCheckNode; @@ -84,7 +85,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.nodes.util.PosixSupportNodes; import com.oracle.graal.python.runtime.GilNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PosixConstants; import com.oracle.graal.python.runtime.PosixSupport; import com.oracle.graal.python.runtime.PosixSupport.AddrInfoCursor; @@ -190,22 +190,22 @@ static UniversalSockAddr doInet6(VirtualFrame frame, @SuppressWarnings("unused") @Specialization(guards = "isUnix(socket)") static UniversalSockAddr doUnix(VirtualFrame frame, @SuppressWarnings("unused") PSocket socket, Object address, String caller, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @Cached PyUnicodeCheckNode unicodeCheckNode, @Cached CastToTruffleStringNode toTruffleStringNode, @Cached PyUnicodeEncodeFSDefaultNode encodeFSDefaultNode, - @CachedLibrary(limit = "1") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { byte[] path; if (unicodeCheckNode.execute(inliningTarget, address)) { path = encodeFSDefaultNode.execute(frame, inliningTarget, toTruffleStringNode.execute(inliningTarget, address)); } else { - Object buffer = bufferAcquireLib.acquireReadonly(address, frame, callData); + Object buffer = getBuffer.executeReadonly(frame, address); try { path = bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } if (!PosixConstants.IS_LINUX || (path.length > 0 && path[0] != 0)) { diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java index 5709aee7cc..bc4884742c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/MemoryBIOBuiltins.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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,10 +47,10 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.annotations.ArgumentClinic; +import com.oracle.graal.python.annotations.Builtin; import com.oracle.graal.python.annotations.Slot; import com.oracle.graal.python.annotations.Slot.SlotKind; import com.oracle.graal.python.annotations.Slot.SlotSignature; -import com.oracle.graal.python.annotations.Builtin; import com.oracle.graal.python.builtins.CoreFunctions; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; @@ -59,13 +59,13 @@ import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.builtins.PythonBinaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.OverflowException; import com.oracle.truffle.api.dsl.Bind; @@ -140,10 +140,10 @@ abstract static class WriteNode extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") static int write(VirtualFrame frame, PMemoryBIO self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @Cached PConstructAndRaiseNode.Lazy constructAndRaiseNode, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (self.didWriteEOF()) { throw constructAndRaiseNode.get(inliningTarget).raiseSSLError(frame, SSL_CANNOT_WRITE_AFTER_EOF); @@ -157,7 +157,7 @@ static int write(VirtualFrame frame, PMemoryBIO self, Object buffer, throw raiseNode.raise(inliningTarget, MemoryError); } } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java index a865e532db..28757502e1 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLContextBuiltins.java @@ -103,6 +103,7 @@ import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.lib.OsEnvironGetNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyCallableCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyNumberIndexNode; @@ -126,7 +127,6 @@ import com.oracle.graal.python.nodes.util.CastToJavaStringNode; import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; @@ -1043,15 +1043,15 @@ static PNone load(VirtualFrame frame, PSSLContext self, Object pathObject, abstract static class SetAlpnProtocols extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") static Object setFromBuffer(VirtualFrame frame, PSSLContext self, Object buffer, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib) { + @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int len = bufferLib.getBufferLength(buffer); self.setAlpnProtocols(parseProtocols(bytes, len)); return PNone.NONE; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java index 1f54876ad6..702da1d250 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/ssl/SSLSocketBuiltins.java @@ -41,6 +41,7 @@ package com.oracle.graal.python.builtins.objects.ssl; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.NotImplementedError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import static com.oracle.graal.python.util.PythonUtils.TS_ENCODING; import static com.oracle.graal.python.util.PythonUtils.toTruffleStringUncached; @@ -52,7 +53,6 @@ import java.security.cert.CertificateParsingException; import java.security.cert.X509Certificate; import java.util.List; - import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLPeerUnverifiedException; import javax.net.ssl.SSLSession; @@ -64,8 +64,10 @@ import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; +import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PRaiseNode; @@ -75,7 +77,7 @@ import com.oracle.graal.python.nodes.function.builtins.PythonTernaryClinicBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; +import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -118,16 +120,21 @@ static Object read(VirtualFrame frame, PSSLSocket self, int len, @SuppressWarnin return PFactory.createBytes(language, PythonUtils.getBufferArray(output), PythonUtils.getBufferLimit(output)); } - @Specialization(guards = "!isNoValue(bufferObj)", limit = "3") + @Specialization(guards = "!isNoValue(bufferObj)") static Object readInto(VirtualFrame frame, PSSLSocket self, int len, Object bufferObj, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("bufferObj") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Shared @Cached SSLOperationNode sslOperationNode, // unused node to avoid mixing shared and non-shared inlined nodes - @SuppressWarnings("unused") @Shared @Cached PRaiseNode raiseNode) { - Object buffer = bufferAcquireLib.acquireWritableWithTypeError(bufferObj, "read", frame, callData); + @SuppressWarnings("unused") @Shared @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { + Object buffer; + try { + buffer = getBuffer.execute(frame, bufferObj, BufferFlags.PyBUF_WRITABLE); + } catch (PException e) { + throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, "read", bufferObj); + } try { int bufferLen = bufferLib.getBufferLength(buffer); int toReadLen = len; @@ -153,7 +160,7 @@ static Object readInto(VirtualFrame frame, PSSLSocket self, int len, Object buff } return readBytes; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -170,9 +177,9 @@ abstract static class WriteNode extends PythonBinaryClinicBuiltinNode { @Specialization(limit = "3") static Object write(VirtualFrame frame, PSSLSocket self, Object buffer, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached SSLOperationNode sslOperationNode) { + @Cached SSLOperationNode sslOperationNode, + @Cached PyBufferRelease releaseBuffer) { try { byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); int length = bufferLib.getBufferLength(buffer); @@ -180,7 +187,7 @@ static Object write(VirtualFrame frame, PSSLSocket self, Object buffer, sslOperationNode.write(frame, inliningTarget, self, input); return length; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java index 396bf4aa4c..3c02720c37 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/str/StringBuiltins.java @@ -79,7 +79,6 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.PNotImplemented; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.BytesCommonBuiltins; import com.oracle.graal.python.builtins.objects.bytes.PByteArray; import com.oracle.graal.python.builtins.objects.bytes.PBytes; @@ -130,9 +129,11 @@ import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqItemBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSizeArgFun.SqRepeatBuiltinNode; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotSqContains.SqContainsBuiltinNode; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyIndexCheckNode; import com.oracle.graal.python.lib.PyNumberAsSizeNode; import com.oracle.graal.python.lib.PyObjectFormat; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyObjectGetItem; import com.oracle.graal.python.lib.PyObjectHashNode; import com.oracle.graal.python.lib.PyObjectStrAsObjectNode; @@ -162,7 +163,6 @@ import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; import com.oracle.graal.python.runtime.ExecutionContext.BoundaryCallContext; import com.oracle.graal.python.runtime.IndirectCallData.BoundaryCallData; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.graal.python.runtime.formatting.InternalFormat; @@ -275,24 +275,24 @@ static Object strOneArg(VirtualFrame frame, Object cls, Object obj, @SuppressWar } } - @Specialization(guards = {"!needsNativeAllocationNode.execute(inliningTarget, cls)", "!isNoValue(encoding) || !isNoValue(errors)"}, limit = "3") + @Specialization(guards = {"!needsNativeAllocationNode.execute(inliningTarget, cls)", "!isNoValue(encoding) || !isNoValue(errors)"}, limit = "1") static Object doBuffer(VirtualFrame frame, Object cls, Object obj, Object encoding, Object errors, @Bind Node inliningTarget, - @Exclusive @Cached("createFor($node)") InteropCallData callData, @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, @Exclusive @Cached IsBuiltinClassExactProfile isPrimitiveProfile, @Exclusive @Cached InlinedConditionProfile isStringProfile, @Exclusive @Cached InlinedConditionProfile isPStringProfile, - @Exclusive @CachedLibrary("obj") PythonBufferAcquireLibrary acquireLib, + @Exclusive @Cached PyObjectGetBuffer getBuffer, @Exclusive @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Exclusive @Cached BytesCommonBuiltins.DecodeNode decodeNode, @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, @Exclusive @Cached PyUnicodeCheckNode stringCheckNode, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Shared("releaseBuffer") @Cached PyBufferRelease releaseBuffer) { checkEncodingAndErrors(inliningTarget, encoding, errors, stringCheckNode, raiseNode); Object buffer; try { - buffer = acquireLib.acquireReadonly(obj, frame, callData); + buffer = getBuffer.executeReadonly(frame, obj); } catch (PException e) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.NEED_BYTELIKE_OBJ, obj); } @@ -309,7 +309,7 @@ static Object doBuffer(VirtualFrame frame, Object cls, Object obj, Object encodi } throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.P_S_RETURNED_NON_STRING, bytesObj, "decode", result); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -338,23 +338,23 @@ static Object doNativeSubclass(VirtualFrame frame, Object cls, Object obj, @Supp "!isNoValue(encoding) || !isNoValue(errors)"}, limit = "1") static Object doNativeSubclassEncodeErr(VirtualFrame frame, Object cls, Object obj, Object encoding, Object errors, @SuppressWarnings("unused") @Bind Node inliningTarget, - @Exclusive @Cached("createFor($node)") InteropCallData callData, @SuppressWarnings("unused") @Exclusive @Cached TypeNodes.NeedsNativeAllocationNode needsNativeAllocationNode, @Exclusive @Cached @SuppressWarnings("unused") IsSubtypeNode isSubtype, @Exclusive @Cached IsBuiltinClassExactProfile isPrimitiveProfile, @Exclusive @Cached InlinedConditionProfile isStringProfile, @Exclusive @Cached InlinedConditionProfile isPStringProfile, - @Exclusive @CachedLibrary("obj") PythonBufferAcquireLibrary acquireLib, + @Exclusive @Cached PyObjectGetBuffer getBuffer, @Exclusive @CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib, @Exclusive @Cached BytesCommonBuiltins.DecodeNode decodeNode, @Exclusive @Cached CExtNodes.StringSubtypeNew subtypeNew, @Exclusive @Cached TypeNodes.GetInstanceShape getInstanceShape, @Exclusive @Cached PyUnicodeCheckNode stringCheckNode, - @Exclusive @Cached PRaiseNode raiseNode) { + @Exclusive @Cached PRaiseNode raiseNode, + @Shared @Cached PyBufferRelease releaseBuffer) { checkEncodingAndErrors(inliningTarget, encoding, errors, stringCheckNode, raiseNode); Object buffer; try { - buffer = acquireLib.acquireReadonly(obj, frame, callData); + buffer = getBuffer.executeReadonly(frame, obj); } catch (PException e) { throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.NEED_BYTELIKE_OBJ, obj); } @@ -369,7 +369,7 @@ static Object doNativeSubclassEncodeErr(VirtualFrame frame, Object cls, Object o } throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.P_S_RETURNED_NON_STRING, bytesObj, "decode", result); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java index 14f4fd1aa0..82e4a48539 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructBuiltins.java @@ -86,6 +86,7 @@ import com.oracle.graal.python.builtins.objects.function.PKeyword; import com.oracle.graal.python.builtins.objects.iterator.PStructUnpackIterator; import com.oracle.graal.python.builtins.objects.type.TpSlots; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PConstructAndRaiseNode; import com.oracle.graal.python.nodes.PGuards; @@ -100,7 +101,6 @@ import com.oracle.graal.python.nodes.function.builtins.PythonVarargsBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.clinic.ArgumentClinicProvider; import com.oracle.graal.python.nodes.util.CastToTruffleStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.util.PythonUtils; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; @@ -501,10 +501,10 @@ protected ArgumentClinicProvider getArgumentClinic() { @Specialization(limit = "3") static Object packInto(VirtualFrame frame, PStruct self, Object buffer, int offset, Object[] args, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Cached StructNodes.PackValueNode packValueNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { final long size = self.getUnsignedSize(); if (args.length != self.getLen()) { @@ -550,7 +550,7 @@ static Object packInto(VirtualFrame frame, PStruct self, Object buffer, int offs } return PNone.NONE; } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } @@ -575,10 +575,10 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object unpack(VirtualFrame frame, PStruct self, Object buffer, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Cached StructNodes.UnpackValueNode unpackValueNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { int bytesLen = bufferLib.getBufferLength(buffer); byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer); @@ -587,7 +587,7 @@ static Object unpack(VirtualFrame frame, PStruct self, Object buffer, } return PFactory.createTuple(language, unpackInternal(self, unpackValueNode, bytes, 0)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } @@ -607,9 +607,9 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object iterUnpack(VirtualFrame frame, PStruct self, Object buffer, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { if (self.getSize() == 0) { throw raiseNode.raise(inliningTarget, StructError, STRUCT_ITER_CANNOT_UNPACK_FROM_STRUCT_OF_SIZE_0); @@ -619,7 +619,7 @@ static Object iterUnpack(VirtualFrame frame, PStruct self, Object buffer, throw raiseNode.raise(inliningTarget, StructError, STRUCT_ITER_UNPACK_REQ_A_BUFFER_OF_A_MUL_OF_BYTES, self.getSize()); } } catch (Exception e) { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); throw e; } // The buffer ownership is transferred to the iterator @@ -646,10 +646,10 @@ protected ArgumentClinicProvider getArgumentClinic() { static Object unpackFrom(VirtualFrame frame, PStruct self, Object buffer, int offset, @Bind Node inliningTarget, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData callData, @CachedLibrary("buffer") PythonBufferAccessLibrary bufferLib, @Cached StructNodes.UnpackValueNode unpackValueNode, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { try { int bufferOffset = offset; int bytesLen = bufferLib.getBufferLength(buffer); @@ -673,7 +673,7 @@ static Object unpackFrom(VirtualFrame frame, PStruct self, Object buffer, int of return PFactory.createTuple(language, unpackInternal(self, unpackValueNode, bytes, bufferOffset)); } finally { - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java index 20b65fdb5e..b5bc85726c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/struct/StructUnpackIteratorBuiltins.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2020, 2025, Oracle and/or its affiliates. +/* Copyright (c) 2020, 2026, Oracle and/or its affiliates. * Copyright (C) 1996-2020 Python Software Foundation * * Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 @@ -24,11 +24,11 @@ import com.oracle.graal.python.builtins.objects.iterator.PStructUnpackIterator; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; import com.oracle.graal.python.nodes.function.PythonBuiltinNode; import com.oracle.graal.python.nodes.function.builtins.PythonUnaryBuiltinNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -93,17 +93,17 @@ static Object nextExhausted(@SuppressWarnings("unused") PStructUnpackIterator se @Specialization(guards = "!self.isExhausted()", limit = "3") static Object next(VirtualFrame frame, PStructUnpackIterator self, - @Cached("createFor($node)") InteropCallData callData, @Cached StructNodes.UnpackValueNode unpackValueNode, @CachedLibrary("self.getBuffer()") PythonBufferAccessLibrary bufferLib, - @Bind PythonLanguage language) { + @Bind PythonLanguage language, + @Cached PyBufferRelease releaseBuffer) { final PStruct struct = self.getStruct(); final Object buffer = self.getBuffer(); final int bufferLen = bufferLib.getBufferLength(buffer); if (struct == null || self.index >= bufferLen) { self.setExhausted(); - bufferLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); throw iteratorExhausted(); } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java index 44a6e171fa..eda2fb76d0 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/tokenize/TokenizerIterBuiltins.java @@ -63,13 +63,14 @@ import com.oracle.graal.python.builtins.PythonBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.tokenize.TokenizerIterBuiltinsClinicProviders.TokenizerIterNodeClinicProviderGen; import com.oracle.graal.python.builtins.objects.tuple.PTuple; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TypeNodes; import com.oracle.graal.python.builtins.objects.type.slots.TpSlotIterNext.TpIterNextBuiltin; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyBytesCheckNode; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode; @@ -147,7 +148,8 @@ static PTokenizerIter tokenizerIterStr(Object cls, Object readline, boolean extr static PTokenizerIter tokenizerIterBytes(Object cls, Object readline, boolean extraTokens, TruffleString encoding, @Bind Node inliningTarget, @Shared @Cached TypeNodes.GetInstanceShape getInstanceShape, - @Cached PRaiseNode raiseNode) { + @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { Charset charset; try { charset = getCharset(Tokenizer.getNormalName(encoding.toJavaStringUncached())); @@ -169,7 +171,7 @@ static PTokenizerIter tokenizerIterBytes(Object cls, Object readline, boolean ex Object buffer; try { - buffer = PythonBufferAcquireLibrary.getUncached().acquireReadonly(o); + buffer = PyObjectGetBuffer.getUncached().executeReadonly(null, o); } catch (PException e) { throw PRaiseNode.raiseStatic(null, TypeError, EXPECTED_BYTESLIKE_GOT_P, o); } @@ -180,7 +182,7 @@ static PTokenizerIter tokenizerIterBytes(Object cls, Object readline, boolean ex bytes = bufferLib.getInternalOrCopiedByteArray(buffer); len = bufferLib.getBufferLength(buffer); } finally { - bufferLib.release(buffer); + releaseBuffer.execute(null, buffer); } String line = charset.decode(ByteBuffer.wrap(bytes, 0, len)).toString(); return getCodePoints(TruffleString.fromJavaStringUncached(line, TS_ENCODING)); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyBufferRelease.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyBufferRelease.java new file mode 100644 index 0000000000..22d3ff67b3 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyBufferRelease.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2021, 2026, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.objects.memoryview.MemoryViewNodes.ReleaseNode; +import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; + +/** + * Equivalent of CPython's {@code PyBuffer_Release}, but must not be called multiple times on the + * same buffer. + */ +@GenerateUncached +@GenerateInline(false) +public abstract class PyBufferRelease extends PNodeWithContext { + public abstract void execute(VirtualFrame frame, Object buffer); + + @Specialization + static void doMemoryView(VirtualFrame frame, PMemoryView buffer, + @Cached ReleaseNode releaseNode) { + /* + * Helper memoryviews created to hold native buffers must release their buffer immediately. + */ + if (buffer.shouldReleaseImmediately()) { + releaseNode.execute(frame, buffer); + } else { + long exports = buffer.getExports().decrementAndGet(); + assert exports >= 0; + } + } + + @Fallback + static void doOther(@SuppressWarnings("unused") Object buffer) { + // Other buffers do not need releasing. + } + + @NeverDefault + public static PyBufferRelease create() { + return PyBufferReleaseNodeGen.create(); + } + + public static PyBufferRelease getUncached() { + return PyBufferReleaseNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java index d600813abc..2eccdbfc9a 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyFloatFromString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -44,14 +44,12 @@ import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.floats.FloatUtils; 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.util.CannotCastException; import com.oracle.graal.python.nodes.util.CastToJavaStringNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.dsl.Cached; @@ -88,19 +86,19 @@ static double doString(VirtualFrame frame, Node inliningTarget, TruffleString ob @Specialization static double doGeneric(VirtualFrame frame, Node inliningTarget, Object object, - @Cached(value = "createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, + @Cached PyObjectGetBuffer getBuffer, @CachedLibrary(limit = "3") PythonBufferAccessLibrary accessLib, @Cached(inline = false) CastToJavaStringNode cast, @Shared @Cached PyObjectReprAsTruffleStringNode reprNode, - @Shared @Cached PRaiseNode raiseNode) { + @Shared @Cached PRaiseNode raiseNode, + @Cached PyBufferRelease releaseBuffer) { String string = null; try { string = cast.execute(object); } catch (CannotCastException e) { Object buffer = null; try { - buffer = acquireLib.acquireReadonly(object, frame, callData); + buffer = getBuffer.executeReadonly(frame, object); } catch (PException e1) { // fallthrough } @@ -110,7 +108,7 @@ static double doGeneric(VirtualFrame frame, Node inliningTarget, Object object, int len = accessLib.getBufferLength(buffer); string = newString(bytes, 0, len); } finally { - accessLib.release(buffer, frame, callData); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java index 3a6856f470..411cff1d6c 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyMemoryViewFromObject.java @@ -48,7 +48,6 @@ import com.oracle.graal.python.builtins.objects.PythonAbstractObject; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.cext.PythonNativeObject; import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; import com.oracle.graal.python.builtins.objects.memoryview.BufferLifecycleManager; @@ -62,7 +61,6 @@ import com.oracle.graal.python.nodes.PRaiseNode; import com.oracle.graal.python.nodes.call.CallNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.graal.python.runtime.sequence.storage.NativeByteSequenceStorage; @@ -101,10 +99,10 @@ static PMemoryView fromMemoryView(PMemoryView object, } @Specialization - static PMemoryView fromNative(PythonNativeObject object, + static PMemoryView fromNative(VirtualFrame frame, PythonNativeObject object, @Bind Node inliningTarget, @Cached CExtNodes.CreateMemoryViewFromNativeNode fromNativeNode) { - return fromNativeNode.execute(inliningTarget, object, BufferFlags.PyBUF_FULL_RO); + return fromNativeNode.execute(frame, inliningTarget, object, BufferFlags.PyBUF_FULL_RO); } @Specialization @@ -130,8 +128,8 @@ static PMemoryView fromPickleBuffer(VirtualFrame frame, PPickleBuffer object, @Fallback static PMemoryView fromManaged(VirtualFrame frame, Object object, @Bind Node inliningTarget, - @Cached("createFor($node)") InteropCallData interopCallData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectCheckBuffer checkBufferNode, + @Cached PyObjectGetBuffer getBuffer, @Shared @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, @Cached InlinedConditionProfile hasSlotProfile, @Cached InlinedConditionProfile isBuiltinClassTypeProfile, @@ -185,9 +183,9 @@ static PMemoryView fromManaged(VirtualFrame frame, Object object, cBuffer.getItemSize(), BufferFormat.forMemoryView(format, lengthNode, atIndexNode), format, cBuffer.getDims(), cBuffer.getBuf(), 0, shape, strides, suboffsets, flags); - } else if (bufferAcquireLib.hasBuffer(object)) { - // Managed object that implements PythonBufferAcquireLibrary - Object buffer = bufferAcquireLib.acquire(object, BufferFlags.PyBUF_FULL_RO, frame, interopCallData); + } else if (checkBufferNode.execute(object)) { + // Managed object supporting the buffer protocol + Object buffer = getBuffer.execute(frame, object, BufferFlags.PyBUF_FULL_RO); return PFactory.createMemoryViewForManagedObject(context.getLanguage(inliningTarget), buffer, bufferLib.getOwner(buffer), bufferLib.getItemSize(buffer), bufferLib.getBufferLength(buffer), bufferLib.isReadonly(buffer), bufferLib.getFormatString(buffer), lengthNode, atIndexNode); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java index fe4e005d79..23af3ebd65 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyNumberLongNode.java @@ -49,7 +49,6 @@ import com.oracle.graal.python.builtins.modules.WarningsModuleBuiltins; import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.type.TpSlots; import com.oracle.graal.python.builtins.objects.type.TpSlots.GetCachedTpSlotsNode; @@ -62,7 +61,6 @@ import com.oracle.graal.python.nodes.call.special.MaybeBindDescriptorNode; import com.oracle.graal.python.nodes.classes.IsSubtypeNode; import com.oracle.graal.python.nodes.object.GetClassNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; import com.oracle.truffle.api.HostCompilerDirectives.InliningCutoff; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -242,12 +240,12 @@ static Object doGeneric(VirtualFrame frame, Object object, int base, @Bind Node inliningTarget, @Cached TruffleString.FromByteArrayWithCompactionUTF32Node fromByteArrayNode, @Cached PyLongFromUnicodeObject fromString, - @Cached(value = "createFor($node)") InteropCallData callData, - @CachedLibrary(limit = "3") PythonBufferAcquireLibrary acquireLib, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { + @Cached PyObjectGetBuffer getBuffer, + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { Object buffer; try { - buffer = acquireLib.acquireReadonly(object, frame, callData); + buffer = getBuffer.executeReadonly(frame, object); } catch (AbstractTruffleException e) { return null; } @@ -257,7 +255,7 @@ static Object doGeneric(VirtualFrame frame, Object object, int base, TruffleString string = fromByteArrayNode.execute(bytes, 0, len, TruffleString.CompactionLevel.S1, false); return fromString.execute(inliningTarget, string, base, bytes, len); } finally { - bufferLib.release(buffer); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCheckBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCheckBuffer.java new file mode 100644 index 0000000000..f44fe86785 --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectCheckBuffer.java @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2021, 2026, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import com.oracle.graal.python.builtins.modules.io.PBytesIOBuffer; +import com.oracle.graal.python.builtins.modules.pickle.PPickleBuffer; +import com.oracle.graal.python.builtins.objects.array.PArray; +import com.oracle.graal.python.builtins.objects.bytes.PByteArray; +import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; +import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; +import com.oracle.graal.python.builtins.objects.mmap.PMMap; +import com.oracle.graal.python.nodes.PNodeWithContext; +import com.oracle.graal.python.nodes.object.IsForeignObjectNode; +import com.oracle.graal.python.nodes.util.LazyInteropLibrary; +import com.oracle.truffle.api.dsl.Bind; +import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; + +/** + * Equivalent of CPython's {@code PyObject_CheckBuffer}. Acquisition may still raise an exception. + */ +@GenerateUncached +@GenerateInline(false) +public abstract class PyObjectCheckBuffer extends PNodeWithContext { + public abstract boolean execute(Object object); + + public static boolean executeUncached(Object object) { + return PyObjectCheckBufferNodeGen.getUncached().execute(object); + } + + @Specialization + static boolean doPBytes(@SuppressWarnings("unused") PBytes object) { + return true; + } + + @Specialization + static boolean doPByteArray(@SuppressWarnings("unused") PByteArray object) { + return true; + } + + @Specialization + static boolean doPArray(@SuppressWarnings("unused") PArray object) { + return true; + } + + @Specialization + static boolean doPMemoryView(@SuppressWarnings("unused") PMemoryView object) { + return true; + } + + @Specialization + static boolean doPMMap(@SuppressWarnings("unused") PMMap object) { + return true; + } + + @Specialization + static boolean doPPickleBuffer(@SuppressWarnings("unused") PPickleBuffer object) { + return true; + } + + @Specialization + static boolean doPBytesIOBuffer(@SuppressWarnings("unused") PBytesIOBuffer object) { + return true; + } + + @Specialization + static boolean doNative(PythonAbstractNativeObject object, + @Bind Node inliningTarget, + @Cached CExtNodes.HasNativeBufferNode hasNativeBuffer) { + return hasNativeBuffer.execute(inliningTarget, object); + } + + @Fallback + static boolean doOther(Object object, + @Bind Node inliningTarget, + @Cached IsForeignObjectNode isForeignObjectNode, + @Cached LazyInteropLibrary interopLib) { + if (isForeignObjectNode.execute(inliningTarget, object)) { + return interopLib.get(inliningTarget).hasBufferElements(object); + } else { + return false; + } + } + + @NeverDefault + public static PyObjectCheckBuffer create() { + return PyObjectCheckBufferNodeGen.create(); + } + + public static PyObjectCheckBuffer getUncached() { + return PyObjectCheckBufferNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetBuffer.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetBuffer.java new file mode 100644 index 0000000000..d611d3cc5a --- /dev/null +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyObjectGetBuffer.java @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2021, 2026, 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 + * + * Subject to the condition set forth below, permission is hereby granted to any + * person obtaining a copy of this software, associated documentation and/or + * data (collectively the "Software"), free of charge and under any and all + * copyright rights in the Software, and any and all patent rights owned or + * freely licensable by each licensor hereunder covering either (i) the + * unmodified Software as contributed to or provided by such licensor, or (ii) + * the Larger Works (as defined below), to deal in both + * + * (a) the Software, and + * + * (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if + * one is included with the Software each a "Larger Work" to which the Software + * is contributed by such licensors), + * + * without restriction, including without limitation the rights to copy, create + * derivative works of, display, perform, and distribute the Software and make, + * use, sell, offer for sale, import, export, have made, and have sold the + * Software and the Larger Work(s), and to sublicense the foregoing rights on + * either these or other terms. + * + * This license is subject to the following condition: + * + * The above copyright notice and either this complete permission notice or at a + * minimum a reference to the UPL must be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +package com.oracle.graal.python.lib; + +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.BufferError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.ValueError; + +import com.oracle.graal.python.builtins.modules.io.PBytesIOBuffer; +import com.oracle.graal.python.builtins.modules.pickle.PPickleBuffer; +import com.oracle.graal.python.builtins.objects.array.PArray; +import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; +import com.oracle.graal.python.builtins.objects.buffer.ForeignBufferAdapter; +import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; +import com.oracle.graal.python.builtins.objects.bytes.PByteArray; +import com.oracle.graal.python.builtins.objects.bytes.PBytes; +import com.oracle.graal.python.builtins.objects.cext.PythonAbstractNativeObject; +import com.oracle.graal.python.builtins.objects.cext.capi.CExtNodes; +import com.oracle.graal.python.builtins.objects.memoryview.PMemoryView; +import com.oracle.graal.python.builtins.objects.mmap.PMMap; +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.object.IsForeignObjectNode; +import com.oracle.graal.python.nodes.util.CastToJavaIntExactNode; +import com.oracle.graal.python.nodes.util.LazyInteropLibrary; +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.Cached.Exclusive; +import com.oracle.truffle.api.dsl.Fallback; +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.NeverDefault; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.interop.InteropLibrary; +import com.oracle.truffle.api.interop.UnsupportedMessageException; +import com.oracle.truffle.api.library.CachedLibrary; +import com.oracle.truffle.api.nodes.Node; + +/** + * Equivalent of CPython's {@code PyObject_GetBuffer}. The returned buffer must be accessed using + * {@link PythonBufferAccessLibrary} and released using {@link PyBufferRelease}. + */ +@GenerateUncached +@GenerateInline(false) +public abstract class PyObjectGetBuffer extends PNodeWithContext { + /** + * The flags are defined in {@link BufferFlags}. Managed buffers typically return themselves, + * so callers must ignore format, shape and strides when the flags do not request them. + */ + public abstract Object execute(VirtualFrame frame, Object object, int flags); + + public final Object executeReadonly(VirtualFrame frame, Object object) { + return execute(frame, object, BufferFlags.PyBUF_SIMPLE); + } + + public final Object executeWritable(VirtualFrame frame, Object object) { + return execute(frame, object, BufferFlags.PyBUF_WRITABLE); + } + + @Specialization + static Object doBytes(PBytes object, int flags, + @Bind Node inliningTarget, + @Exclusive @Cached PRaiseNode raiseNode) { + if (BufferFlags.requestsWritable(flags)) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.OBJ_IS_NOT_WRITABLE); + } + return object; + } + + @Specialization + static Object doPByteArray(PByteArray object, @SuppressWarnings("unused") int flags) { + return object; + } + + @Specialization + static Object doPArray(PArray object, @SuppressWarnings("unused") int flags) { + return object; + } + + @Specialization + static Object doPMMap(PMMap object, @SuppressWarnings("unused") int flags) { + return object; + } + + @Specialization + static Object doMemoryView(PMemoryView object, int requestedFlags, + @Bind Node inliningTarget, + @Exclusive @Cached PRaiseNode raiseNode) { + object.checkReleased(inliningTarget, raiseNode); + if (BufferFlags.requestsWritable(requestedFlags) && object.isReadOnly()) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_WRITABLE); + } + if (BufferFlags.requestsCContiguous(requestedFlags) && !object.isCContiguous()) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS); + } + if (BufferFlags.requestsFContiguous(requestedFlags) && !object.isFortranContiguous()) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_FORTRAN_CONTIGUOUS); + } + if (BufferFlags.requestsAnyContiguous(requestedFlags) && !object.isAnyContiguous()) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_CONTIGUOUS); + } + if (!BufferFlags.requestsIndirect(requestedFlags) && (object.getFlags() & PMemoryView.FLAG_PIL) != 0) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_REQUIRES_SUBOFFSETS); + } + if (!BufferFlags.requestsStrides(requestedFlags) && !object.isCContiguous()) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_UNDERLYING_BUF_ISNT_C_CONTIGUOUS); + } + // TODO should reflect the cast to unsigned bytes if necessary + if (!BufferFlags.requestsShape(requestedFlags) && BufferFlags.requestsFormat(requestedFlags)) { + throw raiseNode.raise(inliningTarget, BufferError, ErrorMessages.MV_CANNOT_CAST_UNSIGNED_BYTES_IF_FMT_FLAG); + } + object.getExports().incrementAndGet(); + return object; + } + + @Specialization + static Object doNative(VirtualFrame frame, PythonAbstractNativeObject object, int flags, + @Bind Node inliningTarget, + @Cached CExtNodes.CreateMemoryViewFromNativeNode createMemoryView) { + PMemoryView view = createMemoryView.execute(frame, inliningTarget, object, flags); + view.setShouldReleaseImmediately(true); + return view; + } + + @Specialization + static Object doBytesIO(PBytesIOBuffer object, @SuppressWarnings("unused") int flags) { + return object.getDelegate(); + } + + @Specialization + static Object doPickleBuffer(VirtualFrame frame, PPickleBuffer object, int flags, + @Bind Node inliningTarget, + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Exclusive @Cached PyObjectGetBuffer recursive, + @Exclusive @Cached PRaiseNode raiseNode) { + Object owner = null; + if (object.getView() != null) { + owner = bufferLib.getOwner(object.getView()); + } + if (owner == null) { + throw raiseNode.raise(inliningTarget, ValueError, ErrorMessages.OP_FORBIDDEN_ON_OBJECT, "PickleBuffer"); + } + return recursive.execute(frame, owner, flags); + } + + @Fallback + static Object doOther(Object object, int flags, + @Bind Node inliningTarget, + @Cached IsForeignObjectNode isForeignObjectNode, + @Cached CastToJavaIntExactNode castInt, + @Cached LazyInteropLibrary lazyInteropLib) { + if (isForeignObjectNode.execute(inliningTarget, object)) { + InteropLibrary interopLib = lazyInteropLib.get(inliningTarget); + if (interopLib.hasBufferElements(object)) { + try { + long size = interopLib.getBufferSize(object); + boolean readonly = !interopLib.isBufferWritable(object); + if (BufferFlags.requestsWritable(flags) && readonly) { + throw PRaiseNode.raiseStatic(inliningTarget, BufferError, ErrorMessages.OBJ_IS_NOT_WRITABLE); + } + return new ForeignBufferAdapter(object, castInt.execute(inliningTarget, size), readonly); + } catch (UnsupportedMessageException e) { + throw CompilerDirectives.shouldNotReachHere(e); + } + } + } + throw PRaiseNode.raiseStatic(inliningTarget, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, object); + } + + @NeverDefault + public static PyObjectGetBuffer create() { + return PyObjectGetBufferNodeGen.create(); + } + + public static PyObjectGetBuffer getUncached() { + return PyObjectGetBufferNodeGen.getUncached(); + } +} diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java index 8fcb7036f3..5271eb2885 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/lib/PyUnicodeFromEncodedObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2026, 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 @@ -46,13 +46,10 @@ import com.oracle.graal.python.PythonLanguage; import com.oracle.graal.python.builtins.PythonBuiltinClassType; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.str.PString; import com.oracle.graal.python.nodes.PNodeWithContext; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.object.PFactory; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; @@ -102,16 +99,15 @@ static Object doPString(VirtualFrame frame, PString object, Object encoding, Obj throw PRaiseNode.raiseStatic(inliningTarget, PythonBuiltinClassType.TypeError, DECODING_STR_NOT_SUPPORTED); } - @Specialization(guards = {"!isPBytes(object)", "!isString(object)"}, limit = "3") + @Specialization(guards = {"!isPBytes(object)", "!isString(object)"}) static Object doBuffer(VirtualFrame frame, Node inliningTarget, Object object, Object encoding, Object errors, @Bind PythonLanguage language, - @Cached("createFor($node)") InteropCallData indirectCallNode, @Exclusive @Cached InlinedConditionProfile emptyStringProfile, - @CachedLibrary("object") PythonBufferAcquireLibrary bufferAcquireLib, + @Cached PyObjectGetBuffer getBuffer, @Exclusive @Cached PyUnicodeDecode decode, - @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib) { - PythonContext context = PythonContext.get(inliningTarget); - Object buffer = bufferAcquireLib.acquireReadonly(object, frame, context, context.getLanguage(inliningTarget), indirectCallNode); + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { + Object buffer = getBuffer.executeReadonly(frame, object); try { int len = bufferLib.getBufferLength(buffer); if (emptyStringProfile.profile(inliningTarget, len == 0)) { @@ -120,7 +116,7 @@ static Object doBuffer(VirtualFrame frame, Node inliningTarget, Object object, O PBytes bytes = PFactory.createBytes(language, bufferLib.getInternalOrCopiedByteArray(buffer), len); return decode.execute(frame, inliningTarget, bytes, encoding, errors); } finally { - bufferLib.release(buffer, frame, indirectCallNode); + releaseBuffer.execute(frame, buffer); } } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/ReadableBufferConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/ReadableBufferConversionNode.java index 667855804d..2d71c36278 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/ReadableBufferConversionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/ReadableBufferConversionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, 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 @@ -42,29 +42,21 @@ import com.oracle.graal.python.annotations.ClinicConverterFactory; import com.oracle.graal.python.builtins.objects.PNone; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; -import com.oracle.truffle.api.dsl.Bind; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; -import com.oracle.truffle.api.nodes.Node; public abstract class ReadableBufferConversionNode extends ObjectConversionBaseNode { protected ReadableBufferConversionNode(Object defaultValue, boolean useDefaultForNone) { super(defaultValue, useDefaultForNone); } - @Specialization(guards = "!isHandledPNone(value)", limit = "getCallSiteInlineCacheMaxDepth()") + @Specialization(guards = "!isHandledPNone(value)") Object doObject(VirtualFrame frame, Object value, - @Bind Node inliningTarget, - @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("value") PythonBufferAcquireLibrary acquireLib) { - return acquireLib.acquireReadonly(value, frame, context, context.getLanguage(inliningTarget), callData); + @Cached PyObjectGetBuffer getBuffer) { + return getBuffer.executeReadonly(frame, value); } @ClinicConverterFactory diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java index 1fd6187bc3..9c86bd3040 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/function/builtins/clinic/WritableBufferConversionNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2026, 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 @@ -40,22 +40,20 @@ */ package com.oracle.graal.python.nodes.function.builtins.clinic; -import static com.oracle.graal.python.runtime.exception.PythonErrorType.TypeError; +import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError; import com.oracle.graal.python.annotations.ClinicConverterFactory; import com.oracle.graal.python.annotations.ClinicConverterFactory.BuiltinName; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; import com.oracle.graal.python.runtime.exception.PException; import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; import com.oracle.truffle.api.dsl.NeverDefault; import com.oracle.truffle.api.dsl.Specialization; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.Node; public abstract class WritableBufferConversionNode extends ArgumentCastNode { @@ -65,18 +63,15 @@ public WritableBufferConversionNode(String builtinName) { this.builtinName = builtinName; } - @Specialization(limit = "getCallSiteInlineCacheMaxDepth()") - @SuppressWarnings("truffle-static-method") + @Specialization Object doObject(VirtualFrame frame, Object value, @Bind Node inliningTarget, - @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("value") PythonBufferAcquireLibrary acquireLib, - @Cached PRaiseNode raiseNode) { + @Cached PyObjectGetBuffer getBuffer, + @Cached PRaiseNode raise) { try { - return acquireLib.acquireWritable(value, frame, context, context.getLanguage(inliningTarget), callData); + return getBuffer.execute(frame, value, BufferFlags.PyBUF_WRITABLE); } catch (PException e) { - throw raiseNode.raise(inliningTarget, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, builtinName, value); + throw raise.raise(inliningTarget, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, builtinName, value); } } diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java index 6cac6f5f36..d93c7694fd 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/runtime/formatting/BytesFormatProcessor.java @@ -54,14 +54,16 @@ import com.oracle.graal.python.builtins.objects.PNone; import com.oracle.graal.python.builtins.objects.buffer.BufferFlags; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; import com.oracle.graal.python.builtins.objects.bytes.PBytes; import com.oracle.graal.python.builtins.objects.bytes.PBytesLike; import com.oracle.graal.python.builtins.objects.common.SequenceStorageNodes.ToByteArrayNode; import com.oracle.graal.python.builtins.objects.ints.PInt; import com.oracle.graal.python.builtins.objects.str.PString; +import com.oracle.graal.python.lib.PyBufferRelease; import com.oracle.graal.python.lib.PyMappingCheckNode; import com.oracle.graal.python.lib.PyObjectAsciiAsTruffleStringNode; +import com.oracle.graal.python.lib.PyObjectCheckBuffer; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.lib.PyTupleCheckNode; import com.oracle.graal.python.nodes.ErrorMessages; import com.oracle.graal.python.nodes.PRaiseNode; @@ -250,15 +252,14 @@ private static byte[] toBytes(PBytesLike arg) { } private static byte[] byteBufferAsBytesOrNull(Object obj) { - PythonBufferAcquireLibrary acquireLib = PythonBufferAcquireLibrary.getFactory().getUncached(obj); - if (acquireLib.hasBuffer(obj)) { + if (PyObjectCheckBuffer.executeUncached(obj)) { // TODO PyBUF_FULL_RO - Object buffer = acquireLib.acquire(obj, BufferFlags.PyBUF_ND); + Object buffer = PyObjectGetBuffer.getUncached().execute(null, obj, BufferFlags.PyBUF_ND); PythonBufferAccessLibrary bufferLib = PythonBufferAccessLibrary.getFactory().getUncached(buffer); try { return bufferLib.getCopiedByteArray(buffer); } finally { - bufferLib.release(buffer); + PyBufferRelease.getUncached().execute(null, buffer); } } return null; diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ByteArrayBuilder.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ByteArrayBuilder.java index 1dc92174ab..846fd71823 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ByteArrayBuilder.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/util/ByteArrayBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2026, 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 @@ -41,14 +41,11 @@ package com.oracle.graal.python.util; import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary; -import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAcquireLibrary; +import com.oracle.graal.python.lib.PyBufferRelease; +import com.oracle.graal.python.lib.PyObjectGetBuffer; import com.oracle.graal.python.nodes.PNodeWithContext; -import com.oracle.graal.python.runtime.IndirectCallData.InteropCallData; -import com.oracle.graal.python.runtime.PythonContext; 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.Cached.Shared; import com.oracle.truffle.api.dsl.GenerateCached; import com.oracle.truffle.api.dsl.GenerateInline; import com.oracle.truffle.api.dsl.Specialization; @@ -122,19 +119,18 @@ private void ensureCanAppend(int bytesToAdd) { public abstract static class AppendBytesNode extends PNodeWithContext { public abstract void execute(VirtualFrame frame, Node inliningTarget, ByteArrayBuilder builder, Object bytes); - @Specialization(limit = "3") - static void appendBytes(VirtualFrame frame, Node inliningTarget, ByteArrayBuilder builder, Object data, - @Bind PythonContext context, - @Cached("createFor($node)") InteropCallData callData, - @CachedLibrary("data") PythonBufferAcquireLibrary bufferAcquireLib, - @CachedLibrary(limit = "3") @Shared PythonBufferAccessLibrary bufferLib) { - Object dataBuffer = bufferAcquireLib.acquireReadonly(data, frame, context, context.getLanguage(inliningTarget), callData); + @Specialization + static void appendBytes(VirtualFrame frame, ByteArrayBuilder builder, Object data, + @Cached PyObjectGetBuffer getBuffer, + @CachedLibrary(limit = "3") PythonBufferAccessLibrary bufferLib, + @Cached PyBufferRelease releaseBuffer) { + Object dataBuffer = getBuffer.executeReadonly(frame, data); try { int len = bufferLib.getBufferLength(dataBuffer); byte[] src = bufferLib.getInternalOrCopiedByteArray(dataBuffer); builder.add(src, len); } finally { - bufferLib.release(dataBuffer, frame, callData); + releaseBuffer.execute(frame, dataBuffer); } }