42
42
43
43
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .TypeError ;
44
44
45
+ import com .oracle .graal .python .PythonLanguage ;
45
46
import com .oracle .graal .python .annotations .ArgumentClinic .ClinicConversion ;
46
47
import com .oracle .graal .python .nodes .ErrorMessages ;
48
+ import com .oracle .graal .python .nodes .IndirectCallNode ;
49
+ import com .oracle .graal .python .nodes .PNodeWithRaiseAndIndirectCall ;
47
50
import com .oracle .graal .python .nodes .PRaiseNode ;
51
+ import com .oracle .graal .python .runtime .ExecutionContext .IndirectCallContext ;
52
+ import com .oracle .graal .python .runtime .PythonContext ;
48
53
import com .oracle .graal .python .runtime .exception .PException ;
54
+ import com .oracle .truffle .api .frame .VirtualFrame ;
49
55
import com .oracle .truffle .api .interop .InteropLibrary ;
50
56
import com .oracle .truffle .api .library .GenerateLibrary ;
51
57
import com .oracle .truffle .api .library .GenerateLibrary .Abstract ;
@@ -92,24 +98,96 @@ public boolean hasBuffer(@SuppressWarnings("unused") Object receiver) {
92
98
* {@link PythonBufferAccessLibrary#release(Object)} on the returned object after the access is
93
99
* finished. When intrinsifying CPython {PyObject_GetBuffer} calls, pay attention to what it
94
100
* 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>
95
107
*/
96
108
public final Object acquireReadonly (Object receiver ) {
97
109
return acquire (receiver , BufferFlags .PyBUF_SIMPLE );
98
110
}
99
111
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
+
100
142
/**
101
143
* Acquire a buffer object meant for writing. Equivalent of CPython's {@code PyObject_GetBuffer}
102
144
* 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>
108
158
*/
109
159
public final Object acquireWritable (Object receiver ) {
110
160
return acquire (receiver , BufferFlags .PyBUF_WRITABLE );
111
161
}
112
162
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
+
113
191
/**
114
192
* Acquire a buffer object meant for writing. Equivalent of CPython's:
115
193
* <ul>
@@ -120,18 +198,26 @@ public final Object acquireWritable(Object receiver) {
120
198
* Will raise a {@code TypeError} if the acquisition fails, regardless of what exception the
121
199
* acquisition produced.
122
200
*/
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 );
124
203
try {
125
204
return acquireWritable (receiver );
126
205
} catch (PException e ) {
127
206
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 );
128
209
}
129
210
}
130
211
131
212
/**
132
213
* Acquire a buffer with given flags. Equivalent of CPython's {@code PyObject_GetBuffer}. Note
133
214
* that the API is currently not expressive enough to deal with the more complex types. Make
134
215
* 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>
135
221
*
136
222
* @param flags combined constants from {@link BufferFlags}. Unlike CPython, our buffer objects
137
223
* typically return themselves for performance reasons and thus cannot remove the
@@ -143,6 +229,19 @@ public Object acquire(Object receiver, int flags) {
143
229
throw PRaiseNode .raiseUncached (this , TypeError , ErrorMessages .BYTESLIKE_OBJ_REQUIRED , receiver );
144
230
}
145
231
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
+
146
245
static class Assertions extends PythonBufferAcquireLibrary {
147
246
@ Child PythonBufferAcquireLibrary delegate ;
148
247
0 commit comments