Skip to content

Commit 46249dc

Browse files
committed
Setup indirect calls for usages of PythonBufferAcquireLibrary
1 parent bf87b29 commit 46249dc

15 files changed

+154
-50
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,7 +1392,7 @@ Object createIntGeneric(VirtualFrame frame, Object cls, Object obj, @SuppressWar
13921392
if (truncResult == PNone.NO_VALUE) {
13931393
Object buffer;
13941394
try {
1395-
buffer = bufferAcquireLib.acquireReadonly(obj);
1395+
buffer = bufferAcquireLib.acquireReadonly(obj, frame, this);
13961396
} catch (PException e) {
13971397
throw raise(TypeError, ErrorMessages.ARG_MUST_BE_STRING_OR_BYTELIKE_OR_NUMBER, "int()", obj);
13981398
}
@@ -1892,7 +1892,7 @@ Object doBuffer(VirtualFrame frame, Object strClass, Object obj, Object encoding
18921892
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) {
18931893
Object buffer;
18941894
try {
1895-
buffer = acquireLib.acquireReadonly(obj);
1895+
buffer = acquireLib.acquireReadonly(obj, frame, this);
18961896
} catch (PException e) {
18971897
throw raise(TypeError, ErrorMessages.NEED_BYTELIKE_OBJ, obj);
18981898
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -847,7 +847,7 @@ PCode generic(VirtualFrame frame, Object wSource, Object wFilename, Object wMode
847847
String filename;
848848
// TODO use PyUnicode_FSDecode
849849
if (acquireLib.hasBuffer(wFilename)) {
850-
Object filenameBuffer = acquireLib.acquireReadonly(wFilename);
850+
Object filenameBuffer = acquireLib.acquireReadonly(wFilename, frame, this);
851851
try {
852852
filename = PythonUtils.newString(bufferLib.getCopiedByteArray(filenameBuffer));
853853
if (!(wFilename instanceof PBytes)) {
@@ -920,7 +920,7 @@ String sourceAsString(VirtualFrame frame, Object source, String filename, Intero
920920
// buffers, since that's fast for us anyway
921921
Object buffer;
922922
try {
923-
buffer = acquireLib.acquireReadonly(source);
923+
buffer = acquireLib.acquireReadonly(source, frame, this);
924924
} catch (PException e) {
925925
throw raise(TypeError, ErrorMessages.ARG_D_MUST_BE_S, "compile()", 1, "string, bytes or AST object");
926926
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -293,10 +293,10 @@ static Object doBytesByteStorage(PBytesLike object) {
293293
}
294294

295295
@Specialization(guards = "!isBytes(object)", limit = "3")
296-
static Object doBuffer(Object object,
296+
Object doBuffer(VirtualFrame frame, Object object,
297297
@CachedLibrary("object") PythonBufferAcquireLibrary acquireLib,
298298
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib) {
299-
Object buffer = acquireLib.acquireReadonly(object);
299+
Object buffer = acquireLib.acquireReadonly(object, frame, this);
300300
try {
301301
return new InteropByteArray(bufferLib.getCopiedByteArray(object));
302302
} finally {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -722,11 +722,11 @@ protected ArgumentClinicProvider getArgumentClinic() {
722722
@GenerateNodeFactory
723723
abstract static class InetNtoANode extends PythonUnaryBuiltinNode {
724724
@Specialization(limit = "3")
725-
String doGeneric(Object addr,
725+
String doGeneric(VirtualFrame frame, Object addr,
726726
@CachedLibrary("addr") PythonBufferAcquireLibrary bufferAcquireLib,
727727
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
728728
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) {
729-
Object buffer = bufferAcquireLib.acquireReadonly(addr);
729+
Object buffer = bufferAcquireLib.acquireReadonly(addr, frame, this);
730730
try {
731731
byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
732732
int len = bufferLib.getBufferLength(buffer);
@@ -774,7 +774,7 @@ String doGeneric(VirtualFrame frame, int family, Object obj,
774774
@CachedLibrary("obj") PythonBufferAcquireLibrary bufferAcquireLib,
775775
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
776776
@CachedLibrary("getPosixSupport()") PosixSupportLibrary posixLib) {
777-
Object buffer = bufferAcquireLib.acquireReadonly(obj);
777+
Object buffer = bufferAcquireLib.acquireReadonly(obj, frame, this);
778778
try {
779779
byte[] bytes = bufferLib.getInternalOrCopiedByteArray(buffer);
780780
int len = bufferLib.getBufferLength(buffer);

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/BytesIOBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -487,13 +487,13 @@ protected static void resizeBuffer(PBytesIO self, int size,
487487
abstract static class WriteNode extends ClosedCheckPythonBinaryBuiltinNode {
488488

489489
@Specialization(guards = {"self.hasBuf()", "checkExports(self)"}, limit = "3")
490-
Object doWrite(PBytesIO self, Object b,
490+
Object doWrite(VirtualFrame frame, PBytesIO self, Object b,
491491
@CachedLibrary("b") PythonBufferAcquireLibrary acquireLib,
492492
@CachedLibrary(limit = "2") PythonBufferAccessLibrary bufferLib,
493493
@Cached GetInternalArrayNode internalArray,
494494
@Cached EnsureCapacityNode ensureCapacityNode,
495495
@Cached SetLenNode setLenNode) {
496-
Object buffer = acquireLib.acquireReadonly(b);
496+
Object buffer = acquireLib.acquireReadonly(b, frame, this);
497497
try {
498498
int len = bufferLib.getBufferLength(buffer);
499499
if (len == 0) {

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/io/TextIOWrapperNodes.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import com.oracle.graal.python.nodes.ErrorMessages;
8787
import com.oracle.graal.python.nodes.PNodeWithContext;
8888
import com.oracle.graal.python.nodes.PNodeWithRaise;
89+
import com.oracle.graal.python.nodes.PNodeWithRaiseAndIndirectCall;
8990
import com.oracle.graal.python.nodes.PRaiseNode;
9091
import com.oracle.graal.python.nodes.util.CannotCastException;
9192
import com.oracle.graal.python.runtime.exception.PException;
@@ -431,7 +432,8 @@ static String readline(VirtualFrame frame, PTextIO self, int limit,
431432
/*
432433
* cpython/Modules/_io/textio.c:textiowrapper_read_chunk
433434
*/
434-
protected abstract static class ReadChunkNode extends PNodeWithRaise {
435+
protected abstract static class ReadChunkNode extends PNodeWithRaiseAndIndirectCall {
436+
435437
public abstract boolean execute(VirtualFrame frame, PTextIO self, int size_hint);
436438

437439
@Specialization(guards = "self.hasDecoder()")
@@ -493,7 +495,7 @@ boolean readChunk(VirtualFrame frame, PTextIO self, int hint,
493495

494496
Object inputChunkBuf;
495497
try {
496-
inputChunkBuf = bufferAcquireLib.acquireReadonly(inputChunk);
498+
inputChunkBuf = bufferAcquireLib.acquireReadonly(inputChunk, frame, this);
497499
} catch (PException e) {
498500
throw raise(TypeError, S_SHOULD_HAVE_RETURNED_A_BYTES_LIKE_OBJECT_NOT_P, (self.isHasRead1() ? READ1 : READ), inputChunk);
499501
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/array/ArrayBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,12 +1045,12 @@ static Object fromstring(VirtualFrame frame, PArray self, Object str,
10451045
}
10461046

10471047
@Specialization(guards = "!isString(str)")
1048-
static Object fromother(VirtualFrame frame, PArray self, Object str,
1048+
Object fromother(VirtualFrame frame, PArray self, Object str,
10491049
@CachedLibrary(limit = "3") PythonBufferAcquireLibrary bufferAcquireLib,
10501050
@Cached WarningsModuleBuiltins.WarnNode warnNode,
10511051
@Cached FromBytesNode fromBytesNode) {
10521052
warnNode.warnEx(frame, DeprecationWarning, "fromstring() is deprecated. Use frombytes() instead.", 1);
1053-
return fromBytesNode.executeWithoutClinic(frame, self, bufferAcquireLib.acquireReadonly(str));
1053+
return fromBytesNode.executeWithoutClinic(frame, self, bufferAcquireLib.acquireReadonly(str, frame, this));
10541054
}
10551055
}
10561056

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/buffer/PythonBufferAcquireLibrary.java

Lines changed: 105 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,16 @@
4242

4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
4444

45+
import com.oracle.graal.python.PythonLanguage;
4546
import com.oracle.graal.python.annotations.ArgumentClinic.ClinicConversion;
4647
import com.oracle.graal.python.nodes.ErrorMessages;
48+
import com.oracle.graal.python.nodes.IndirectCallNode;
49+
import com.oracle.graal.python.nodes.PNodeWithRaiseAndIndirectCall;
4750
import com.oracle.graal.python.nodes.PRaiseNode;
51+
import com.oracle.graal.python.runtime.ExecutionContext.IndirectCallContext;
52+
import com.oracle.graal.python.runtime.PythonContext;
4853
import com.oracle.graal.python.runtime.exception.PException;
54+
import com.oracle.truffle.api.frame.VirtualFrame;
4955
import com.oracle.truffle.api.interop.InteropLibrary;
5056
import com.oracle.truffle.api.library.GenerateLibrary;
5157
import com.oracle.truffle.api.library.GenerateLibrary.Abstract;
@@ -92,24 +98,96 @@ public boolean hasBuffer(@SuppressWarnings("unused") Object receiver) {
9298
* {@link PythonBufferAccessLibrary#release(Object)} on the returned object after the access is
9399
* finished. When intrinsifying CPython {PyObject_GetBuffer} calls, pay attention to what it
94100
* does to the exception. Sometimes it replaces the exception raised here with another one.
101+
* <p>
102+
* <b>IMPORTANT:</b> This method may only be used in the context of an indirect call (see
103+
* {@link IndirectCallContext}). If a frame is available, prefer using convenience methods
104+
* {@link #acquireReadonly(Object, VirtualFrame, PNodeWithRaiseAndIndirectCall)} or
105+
* {@link #acquireReadonly(Object, VirtualFrame, PythonContext, PythonLanguage, IndirectCallNode)}.
106+
* </p>
95107
*/
96108
public final Object acquireReadonly(Object receiver) {
97109
return acquire(receiver, BufferFlags.PyBUF_SIMPLE);
98110
}
99111

112+
/**
113+
* Convenience method that sets up an indirect call and then uses
114+
* {@link #acquireReadonly(Object)}. <b>NOTE:</b> the provided node must be an ancestor of the
115+
* library.
116+
*/
117+
public final Object acquireReadonly(Object receiver, VirtualFrame frame, PNodeWithRaiseAndIndirectCall indirectCallNode) {
118+
PythonLanguage language = indirectCallNode.getLanguage();
119+
PythonContext context = indirectCallNode.getContext();
120+
Object savedState = IndirectCallContext.enter(frame, language, context, indirectCallNode);
121+
try {
122+
return acquire(receiver, BufferFlags.PyBUF_SIMPLE);
123+
} finally {
124+
IndirectCallContext.exit(frame, language, context, savedState);
125+
}
126+
}
127+
128+
/**
129+
* Convenience method that sets up an indirect call and then uses
130+
* {@link #acquireReadonly(Object)}. <b>NOTE:</b> the provided node must be an ancestor of the
131+
* library.
132+
*/
133+
public final Object acquireReadonly(Object receiver, VirtualFrame frame, PythonContext context, PythonLanguage language, IndirectCallNode node) {
134+
Object savedState = IndirectCallContext.enter(frame, language, context, node);
135+
try {
136+
return acquire(receiver, BufferFlags.PyBUF_SIMPLE);
137+
} finally {
138+
IndirectCallContext.exit(frame, language, context, savedState);
139+
}
140+
}
141+
100142
/**
101143
* Acquire a buffer object meant for writing. Equivalent of CPython's {@code PyObject_GetBuffer}
102144
* with flag {@code PyBUF_WRITABLE}. For equivalents of clinic and {@code PyArg_Parse*}
103-
* converters, see {@link #acquireWritableWithTypeError(Object, String)}.Will raise exception if
104-
* the acquisition fails. Must call {@link PythonBufferAccessLibrary#release(Object)} on the
105-
* returned object after the access is finished. When intrinsifying CPython {PyObject_GetBuffer}
106-
* calls, pay attention to what it does to the exception. More often than not, it replaces the
107-
* exception raised here with another one.
145+
* converters, see
146+
* {@link #acquireWritableWithTypeError(Object, String, VirtualFrame, PNodeWithRaiseAndIndirectCall)}.Will
147+
* raise exception if the acquisition fails. Must call
148+
* {@link PythonBufferAccessLibrary#release(Object)} on the returned object after the access is
149+
* finished. When intrinsifying CPython {PyObject_GetBuffer} calls, pay attention to what it
150+
* does to the exception. More often than not, it replaces the exception raised here with
151+
* another one.
152+
* <p>
153+
* <b>IMPORTANT:</b> This method may only be used in the context of an indirect call (see
154+
* {@link IndirectCallContext}). If a frame is available, prefer using convenience methods
155+
* {@link #acquireWritable(Object, VirtualFrame, PNodeWithRaiseAndIndirectCall)} or
156+
* {@link #acquireWritable(Object, VirtualFrame, PythonContext, PythonLanguage, IndirectCallNode)}.
157+
* </p>
108158
*/
109159
public final Object acquireWritable(Object receiver) {
110160
return acquire(receiver, BufferFlags.PyBUF_WRITABLE);
111161
}
112162

163+
/**
164+
* Convenience method that sets up an indirect call and then uses
165+
* {@link #acquireWritable(Object)}. <b>NOTE:</b> the provided node must be an ancestor of the
166+
* library.
167+
*/
168+
public final Object acquireWritable(Object receiver, VirtualFrame frame, PNodeWithRaiseAndIndirectCall indirectCallNode) {
169+
Object savedState = IndirectCallContext.enter(frame, indirectCallNode);
170+
try {
171+
return acquire(receiver, BufferFlags.PyBUF_WRITABLE);
172+
} finally {
173+
IndirectCallContext.exit(frame, indirectCallNode, savedState);
174+
}
175+
}
176+
177+
/**
178+
* Convenience method that sets up an indirect call and then uses
179+
* {@link #acquireWritable(Object)}. <b>NOTE:</b> the provided node must be an ancestor of the
180+
* library.
181+
*/
182+
public final Object acquireWritable(Object receiver, VirtualFrame frame, PythonContext context, PythonLanguage language, IndirectCallNode node) {
183+
Object savedState = IndirectCallContext.enter(frame, language, context, node);
184+
try {
185+
return acquire(receiver, BufferFlags.PyBUF_WRITABLE);
186+
} finally {
187+
IndirectCallContext.exit(frame, language, context, savedState);
188+
}
189+
}
190+
113191
/**
114192
* Acquire a buffer object meant for writing. Equivalent of CPython's:
115193
* <ul>
@@ -120,18 +198,26 @@ public final Object acquireWritable(Object receiver) {
120198
* Will raise a {@code TypeError} if the acquisition fails, regardless of what exception the
121199
* acquisition produced.
122200
*/
123-
public final Object acquireWritableWithTypeError(Object receiver, String callerName) {
201+
public final Object acquireWritableWithTypeError(Object receiver, String callerName, VirtualFrame frame, PNodeWithRaiseAndIndirectCall indirectCallNode) {
202+
Object savedState = IndirectCallContext.enter(frame, indirectCallNode);
124203
try {
125204
return acquireWritable(receiver);
126205
} catch (PException e) {
127206
throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.S_BRACKETS_ARG_MUST_BE_READ_WRITE_BYTES_LIKE_NOT_P, callerName, receiver);
207+
} finally {
208+
IndirectCallContext.exit(frame, indirectCallNode, savedState);
128209
}
129210
}
130211

131212
/**
132213
* Acquire a buffer with given flags. Equivalent of CPython's {@code PyObject_GetBuffer}. Note
133214
* that the API is currently not expressive enough to deal with the more complex types. Make
134215
* sure you know what the flags mean and that you can handle the result properly.
216+
* <p>
217+
* <b>IMPORTANT:</b> This method may only be used in the context of an indirect call (see
218+
* {@link IndirectCallContext}). If a frame is available, prefer using convenience methods
219+
* {@link #acquire(Object, int, VirtualFrame, PNodeWithRaiseAndIndirectCall)}}.
220+
* </p>
135221
*
136222
* @param flags combined constants from {@link BufferFlags}. Unlike CPython, our buffer objects
137223
* typically return themselves for performance reasons and thus cannot remove the
@@ -143,6 +229,19 @@ public Object acquire(Object receiver, int flags) {
143229
throw PRaiseNode.raiseUncached(this, TypeError, ErrorMessages.BYTESLIKE_OBJ_REQUIRED, receiver);
144230
}
145231

232+
/**
233+
* Convenience method that sets up an indirect call and then uses {@link #acquire(Object, int)}.
234+
* <b>NOTE:</b> the provided node must be an ancestor of the library.
235+
*/
236+
public final Object acquire(Object receiver, int flags, VirtualFrame frame, PNodeWithRaiseAndIndirectCall indirectCallNode) {
237+
Object savedState = IndirectCallContext.enter(frame, indirectCallNode);
238+
try {
239+
return acquire(receiver, flags);
240+
} finally {
241+
IndirectCallContext.exit(frame, indirectCallNode, savedState);
242+
}
243+
}
244+
146245
static class Assertions extends PythonBufferAcquireLibrary {
147246
@Child PythonBufferAcquireLibrary delegate;
148247

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/bytes/ByteArrayBuiltins.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ PNone doSliceBuffer(VirtualFrame frame, PByteArray self, PSlice slice, Object va
225225
@Cached SequenceStorageNodes.LenNode lenNode,
226226
@Cached SliceLiteralNode.SliceUnpack unpack,
227227
@Cached SliceLiteralNode.AdjustIndices adjustIndices) {
228-
Object buffer = bufferAcquireLib.acquireReadonly(value);
228+
Object buffer = bufferAcquireLib.acquireReadonly(value, frame, this);
229229
try {
230230
// TODO avoid copying if possible. Note that it is possible that value is self
231231
PBytes bytes = factory().createBytes(bufferLib.getCopiedByteArray(value));
@@ -351,13 +351,13 @@ PByteArray add(PByteArray self, PBytesLike other,
351351
}
352352

353353
@Specialization(guards = "!isBytes(other)", limit = "3")
354-
PByteArray add(PByteArray self, Object other,
354+
PByteArray add(VirtualFrame frame, PByteArray self, Object other,
355355
@CachedLibrary("other") PythonBufferAcquireLibrary bufferAcquireLib,
356356
@CachedLibrary(limit = "1") PythonBufferAccessLibrary bufferLib,
357357
@Cached SequenceStorageNodes.ConcatNode concatNode) {
358358
Object buffer;
359359
try {
360-
buffer = bufferAcquireLib.acquireReadonly(other);
360+
buffer = bufferAcquireLib.acquireReadonly(other, frame, this);
361361
} catch (PException e) {
362362
throw raise(TypeError, ErrorMessages.CANT_CONCAT_P_TO_S, other, "bytearray");
363363
}
@@ -554,7 +554,7 @@ PNone doGeneric(VirtualFrame frame, PByteArray self, Object source,
554554
self.checkCanResize(this);
555555
byte[] b;
556556
if (bufferProfile.profile(bufferAcquireLib.hasBuffer(source))) {
557-
Object buffer = bufferAcquireLib.acquireReadonly(source);
557+
Object buffer = bufferAcquireLib.acquireReadonly(source, frame, this);
558558
try {
559559
// TODO avoid copying
560560
b = bufferLib.getCopiedByteArray(buffer);

0 commit comments

Comments
 (0)