44
44
import static com .oracle .graal .python .builtins .PythonBuiltinClassType .ValueError ;
45
45
import static com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiCallPath .Direct ;
46
46
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .ConstCharPtr ;
47
- import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .ConstCharPtrAsTruffleString ;
48
47
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Int ;
49
48
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PY_CAPSULE_DESTRUCTOR ;
50
49
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .Pointer ;
51
50
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObject ;
52
51
import static com .oracle .graal .python .builtins .objects .cext .capi .transitions .ArgDescriptor .PyObjectTransfer ;
52
+ import static com .oracle .graal .python .nodes .ErrorMessages .CALLED_WITH_INCORRECT_NAME ;
53
53
import static com .oracle .graal .python .nodes .ErrorMessages .CALLED_WITH_INVALID_PY_CAPSULE_OBJECT ;
54
+ import static com .oracle .graal .python .nodes .ErrorMessages .CALLED_WITH_NULL_POINTER ;
54
55
import static com .oracle .graal .python .nodes .ErrorMessages .PY_CAPSULE_IMPORT_S_IS_NOT_VALID ;
55
56
import static com .oracle .graal .python .util .PythonUtils .TS_ENCODING ;
56
57
57
58
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiBinaryBuiltinNode ;
58
59
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiBuiltin ;
59
60
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiTernaryBuiltinNode ;
60
61
import com .oracle .graal .python .builtins .modules .cext .PythonCextBuiltins .CApiUnaryBuiltinNode ;
61
- import com .oracle .graal .python .builtins .objects .PNone ;
62
62
import com .oracle .graal .python .builtins .objects .capsule .PyCapsule ;
63
63
import com .oracle .graal .python .builtins .objects .capsule .PyCapsuleNameMatchesNode ;
64
- import com .oracle .graal .python .builtins .objects .cext .common . CArrayWrappers . CStringWrapper ;
64
+ import com .oracle .graal .python .builtins .objects .cext .capi . transitions . CApiTransitions ;
65
65
import com .oracle .graal .python .nodes .PRaiseNode ;
66
66
import com .oracle .graal .python .nodes .StringLiterals ;
67
67
import com .oracle .graal .python .nodes .attributes .ReadAttributeFromObjectNode ;
68
68
import com .oracle .graal .python .nodes .statement .AbstractImportNode ;
69
69
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
70
70
import com .oracle .truffle .api .dsl .Bind ;
71
71
import com .oracle .truffle .api .dsl .Cached ;
72
- import com .oracle .truffle .api .dsl .Cached .Shared ;
73
72
import com .oracle .truffle .api .dsl .Fallback ;
74
73
import com .oracle .truffle .api .dsl .Specialization ;
75
74
import com .oracle .truffle .api .interop .InteropLibrary ;
76
75
import com .oracle .truffle .api .library .CachedLibrary ;
77
76
import com .oracle .truffle .api .nodes .Node ;
78
77
import com .oracle .truffle .api .strings .TruffleString ;
79
- import com .oracle .truffle .api .strings .TruffleString .Encoding ;
80
- import com .oracle .truffle .api .strings .TruffleString .GetInternalNativePointerNode ;
81
78
82
79
public final class PythonCextCapsuleBuiltins {
83
80
84
- @ CApiBuiltin (ret = PyObjectTransfer , args = {Pointer , ConstCharPtrAsTruffleString , PY_CAPSULE_DESTRUCTOR }, call = Direct )
81
+ @ CApiBuiltin (ret = PyObjectTransfer , args = {Pointer , ConstCharPtr , PY_CAPSULE_DESTRUCTOR }, call = Direct )
85
82
abstract static class PyCapsule_New extends CApiTernaryBuiltinNode {
86
83
@ Specialization
87
- static Object doGeneric (Object pointer , Object name , Object destructor ,
84
+ static Object doGeneric (Object pointer , Object namePtr , Object destructor ,
88
85
@ Bind ("this" ) Node inliningTarget ,
89
- @ CachedLibrary (limit = "2 " ) InteropLibrary interopLibrary ,
86
+ @ CachedLibrary (limit = "1 " ) InteropLibrary interopLibrary ,
90
87
@ Cached PythonObjectFactory factory ,
91
88
@ Cached PRaiseNode .Lazy raiseNode ) {
92
89
if (interopLibrary .isNull (pointer )) {
93
90
throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INVALID_PY_CAPSULE_OBJECT );
94
91
}
95
- Object n = interopLibrary .isNull (name ) ? null : name ;
96
- PyCapsule capsule = factory .createCapsule (pointer , n );
92
+ PyCapsule capsule = factory .createCapsuleNativeName (pointer , interopLibrary .isNull (namePtr ) ? null : namePtr );
97
93
if (!interopLibrary .isNull (destructor )) {
98
94
capsule .registerDestructor (destructor );
99
95
}
100
96
return capsule ;
101
97
}
102
98
}
103
99
104
- @ CApiBuiltin (ret = Int , args = {PyObject , ConstCharPtrAsTruffleString }, call = Direct )
105
- public abstract static class PyCapsule_IsValid extends CApiBinaryBuiltinNode {
100
+ @ CApiBuiltin (ret = Int , args = {PyObject , ConstCharPtr }, call = Direct )
101
+ abstract static class PyCapsule_IsValid extends CApiBinaryBuiltinNode {
106
102
@ Specialization
107
- public static int doCapsule (PyCapsule o , TruffleString name ,
103
+ static int doCapsule (PyCapsule o , Object namePtr ,
108
104
@ Bind ("this" ) Node inliningTarget ,
109
105
@ Cached PyCapsuleNameMatchesNode nameMatchesNode ) {
110
106
if (o .getPointer () == null ) {
111
107
return 0 ;
112
108
}
113
- if (!nameMatchesNode .execute (inliningTarget , name , o .getName ())) {
109
+ if (!nameMatchesNode .execute (inliningTarget , namePtr , o .getNamePtr ())) {
114
110
return 0 ;
115
111
}
116
112
return 1 ;
@@ -122,7 +118,7 @@ static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("u
122
118
}
123
119
}
124
120
125
- @ CApiBuiltin (ret = Pointer , args = {PyObject , ConstCharPtrAsTruffleString }, call = Direct )
121
+ @ CApiBuiltin (ret = Pointer , args = {PyObject , ConstCharPtr }, call = Direct )
126
122
abstract static class PyCapsule_GetPointer extends CApiBinaryBuiltinNode {
127
123
@ Specialization
128
124
static Object doCapsule (PyCapsule o , Object name ,
@@ -132,8 +128,8 @@ static Object doCapsule(PyCapsule o, Object name,
132
128
if (o .getPointer () == null ) {
133
129
throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INVALID_PY_CAPSULE_OBJECT , "PyCapsule_GetPointer" );
134
130
}
135
- if (!nameMatchesNode .execute (inliningTarget , name , o .getName ())) {
136
- throw raiseNode .get (inliningTarget ).raise (ValueError , PY_CAPSULE_IMPORT_S_IS_NOT_VALID );
131
+ if (!nameMatchesNode .execute (inliningTarget , name , o .getNamePtr ())) {
132
+ throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INCORRECT_NAME , "PyCapsule_GetPointer" );
137
133
}
138
134
return o .getPointer ();
139
135
}
@@ -147,53 +143,15 @@ static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("u
147
143
148
144
@ CApiBuiltin (ret = ConstCharPtr , args = {PyObject }, call = Direct )
149
145
abstract static class PyCapsule_GetName extends CApiUnaryBuiltinNode {
150
- private static void checkLegalCapsule (Node inliningTarget , PyCapsule capsule , PRaiseNode .Lazy raiseNode ) {
151
- if (capsule .getPointer () == null ) {
152
- throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INVALID_PY_CAPSULE_OBJECT , "PyCapsule_GetName" );
153
- }
154
- }
155
-
156
- private static Object tsToNative (TruffleString tname , GetInternalNativePointerNode getInternalNativePointerNode ) {
157
- if (tname .isNative ()) {
158
- /*
159
- * We assume encoding UTF-8 because it's the most common one and also specified in
160
- * HPy. However, CPython does not actually specify an encoding.
161
- */
162
- return getInternalNativePointerNode .execute (tname , Encoding .UTF_8 );
163
- }
164
- return new CStringWrapper (tname );
165
- }
166
146
167
- @ Specialization (guards = "isTruffleString(name)" )
168
- static Object doTruffleString (PyCapsule o ,
169
- @ Bind ("this" ) Node inliningTarget ,
170
- @ Bind ("o.getName()" ) Object name ,
171
- @ Shared ("a" ) @ Cached GetInternalNativePointerNode getInternalNativePointerNode ,
172
- @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
173
- checkLegalCapsule (inliningTarget , o , raiseNode );
174
-
175
- // cast to TruffleString guaranteed by the guard
176
- return tsToNative ((TruffleString ) name , getInternalNativePointerNode );
177
- }
178
-
179
- @ Specialization (replaces = "doTruffleString" )
180
- Object doGeneric (PyCapsule o ,
147
+ @ Specialization
148
+ Object get (PyCapsule o ,
181
149
@ Bind ("this" ) Node inliningTarget ,
182
- @ Bind ("o.getName()" ) Object name ,
183
- @ Shared ("a" ) @ Cached GetInternalNativePointerNode getInternalNativePointerNode ,
184
- @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
185
- checkLegalCapsule (inliningTarget , o , raiseNode );
186
- if (name == null ) {
187
- return getNULL ();
188
- }
189
- if (name instanceof TruffleString ) {
190
- return tsToNative ((TruffleString ) name , getInternalNativePointerNode );
150
+ @ Cached PRaiseNode .Lazy raiseNode ) {
151
+ if (o .getPointer () == null ) {
152
+ throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INVALID_PY_CAPSULE_OBJECT , "PyCapsule_GetName" );
191
153
}
192
- /*
193
- * If 'name' is not a TruffleString, we assume it is a native pointer and return it
194
- * without further conversion.
195
- */
196
- return name ;
154
+ return o .getNamePtr () == null ? getNULL () : o .getNamePtr ();
197
155
}
198
156
199
157
@ Fallback
@@ -255,7 +213,7 @@ static int doCapsule(PyCapsule o, Object pointer,
255
213
@ CachedLibrary (limit = "2" ) InteropLibrary interopLibrary ,
256
214
@ Cached PRaiseNode .Lazy raiseNode ) {
257
215
if (interopLibrary .isNull (pointer )) {
258
- throw raiseNode .get (inliningTarget ).raise (ValueError , PY_CAPSULE_IMPORT_S_IS_NOT_VALID );
216
+ throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_NULL_POINTER , "PyCapsule_SetPointer" );
259
217
}
260
218
261
219
if (o .getPointer () == null ) {
@@ -273,27 +231,17 @@ static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("u
273
231
}
274
232
}
275
233
276
- @ CApiBuiltin (ret = Int , args = {PyObject , ConstCharPtrAsTruffleString }, call = Direct )
234
+ @ CApiBuiltin (ret = Int , args = {PyObject , ConstCharPtr }, call = Direct )
277
235
abstract static class PyCapsule_SetName extends CApiBinaryBuiltinNode {
278
236
@ Specialization
279
- static int doCapsuleTruffleString (PyCapsule o , TruffleString name ,
237
+ static int set (PyCapsule o , Object namePtr ,
280
238
@ Bind ("this" ) Node inliningTarget ,
281
- @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
282
- if (o .getPointer () == null ) {
283
- throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INVALID_PY_CAPSULE_OBJECT , "PyCapsule_SetName" );
284
- }
285
- o .setName (name );
286
- return 0 ;
287
- }
288
-
289
- @ Specialization (guards = "isNoValue(name)" )
290
- static int doCapsuleNone (PyCapsule o , @ SuppressWarnings ("unused" ) PNone name ,
291
- @ Bind ("this" ) Node inliningTarget ,
292
- @ Shared @ Cached PRaiseNode .Lazy raiseNode ) {
239
+ @ CachedLibrary (limit = "1" ) InteropLibrary lib ,
240
+ @ Cached PRaiseNode .Lazy raiseNode ) {
293
241
if (o .getPointer () == null ) {
294
242
throw raiseNode .get (inliningTarget ).raise (ValueError , CALLED_WITH_INVALID_PY_CAPSULE_OBJECT , "PyCapsule_SetName" );
295
243
}
296
- o .setName ( null );
244
+ o .setNamePtr ( lib . isNull ( namePtr ) ? null : namePtr );
297
245
return 0 ;
298
246
}
299
247
@@ -345,17 +293,19 @@ static Object doError(@SuppressWarnings("unused") Object o, @SuppressWarnings("u
345
293
}
346
294
}
347
295
348
- @ CApiBuiltin (ret = Pointer , args = {ConstCharPtrAsTruffleString , Int }, call = Direct )
296
+ @ CApiBuiltin (ret = Pointer , args = {ConstCharPtr , Int }, call = Direct )
349
297
abstract static class PyCapsule_Import extends CApiBinaryBuiltinNode {
350
298
@ Specialization
351
- static Object doGeneric (TruffleString name , @ SuppressWarnings ("unused" ) int noBlock ,
299
+ static Object doGeneric (Object namePtr , @ SuppressWarnings ("unused" ) int noBlock ,
352
300
@ Bind ("this" ) Node inliningTarget ,
301
+ @ Cached CApiTransitions .CharPtrToPythonNode charPtrToPythonNode ,
353
302
@ Cached PyCapsuleNameMatchesNode nameMatchesNode ,
354
303
@ Cached TruffleString .CodePointLengthNode codePointLengthNode ,
355
304
@ Cached TruffleString .IndexOfStringNode indexOfStringNode ,
356
305
@ Cached TruffleString .SubstringNode substringNode ,
357
306
@ Cached ReadAttributeFromObjectNode getAttrNode ,
358
307
@ Cached PRaiseNode .Lazy raiseNode ) {
308
+ TruffleString name = (TruffleString ) charPtrToPythonNode .execute (namePtr );
359
309
TruffleString trace = name ;
360
310
Object object = null ;
361
311
while (trace != null ) {
@@ -377,7 +327,7 @@ static Object doGeneric(TruffleString name, @SuppressWarnings("unused") int noBl
377
327
378
328
/* compare attribute name to module.name by hand */
379
329
PyCapsule capsule = object instanceof PyCapsule ? (PyCapsule ) object : null ;
380
- if (capsule != null && PyCapsule_IsValid .doCapsule (capsule , name , inliningTarget , nameMatchesNode ) == 1 ) {
330
+ if (capsule != null && PyCapsule_IsValid .doCapsule (capsule , namePtr , inliningTarget , nameMatchesNode ) == 1 ) {
381
331
return capsule .getPointer ();
382
332
} else {
383
333
throw raiseNode .get (inliningTarget ).raise (AttributeError , PY_CAPSULE_IMPORT_S_IS_NOT_VALID , name );
0 commit comments