41
41
package com .oracle .graal .python .builtins .modules .ctypes ;
42
42
43
43
import static com .oracle .graal .python .builtins .modules .ctypes .CtypesModuleBuiltins .DICTFLAG_FINAL ;
44
- import static com .oracle .graal .python .builtins .modules .ctypes .CtypesModuleBuiltins .getHandleFromLongObject ;
45
44
import static com .oracle .graal .python .nodes .ErrorMessages .BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES ;
46
45
import static com .oracle .graal .python .nodes .ErrorMessages .CTYPES_OBJECT_STRUCTURE_TOO_DEEP ;
47
46
import static com .oracle .graal .python .nodes .ErrorMessages .EXPECTED_P_INSTANCE_GOT_P ;
48
47
import static com .oracle .graal .python .nodes .ErrorMessages .EXPECTED_P_INSTANCE_INSTEAD_OF_P ;
49
48
import static com .oracle .graal .python .nodes .ErrorMessages .EXPECTED_P_INSTANCE_INSTEAD_OF_POINTER_TO_P ;
50
49
import static com .oracle .graal .python .nodes .ErrorMessages .INCOMPATIBLE_TYPES_P_INSTANCE_INSTEAD_OF_P_INSTANCE ;
51
- import static com .oracle .graal .python .nodes .ErrorMessages .INTEGER_EXPECTED ;
52
50
import static com .oracle .graal .python .nodes .ErrorMessages .NOT_A_CTYPE_INSTANCE ;
53
51
import static com .oracle .graal .python .nodes .ErrorMessages .OFFSET_CANNOT_BE_NEGATIVE ;
54
52
import static com .oracle .graal .python .nodes .ErrorMessages .THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER ;
55
53
import static com .oracle .graal .python .nodes .ErrorMessages .UNDERLYING_BUFFER_IS_NOT_C_CONTIGUOUS ;
56
54
import static com .oracle .graal .python .nodes .ErrorMessages .UNDERLYING_BUFFER_IS_NOT_WRITABLE ;
57
55
import static com .oracle .graal .python .nodes .StringLiterals .T_COLON ;
58
- import static com .oracle .graal .python .runtime .exception .PythonErrorType .NotImplementedError ;
59
56
import static com .oracle .graal .python .runtime .exception .PythonErrorType .TypeError ;
60
57
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
61
58
import static com .oracle .graal .python .util .PythonUtils .TS_ENCODING ;
62
- import static com .oracle .graal .python .util .PythonUtils .toTruffleStringUncached ;
63
59
import static com .oracle .graal .python .util .PythonUtils .tsLiteral ;
64
60
65
61
import java .util .List ;
73
69
import com .oracle .graal .python .builtins .modules .BuiltinConstructors ;
74
70
import com .oracle .graal .python .builtins .modules .BuiltinFunctions .IsInstanceNode ;
75
71
import com .oracle .graal .python .builtins .modules .SysModuleBuiltins .AuditNode ;
76
- import com .oracle .graal .python .builtins .modules .cext .PythonCextLongBuiltins .PyLong_AsVoidPtr ;
77
72
import com .oracle .graal .python .builtins .modules .ctypes .CFieldBuiltins .GetFuncNode ;
78
73
import com .oracle .graal .python .builtins .modules .ctypes .CFieldBuiltins .SetFuncNode ;
79
74
import com .oracle .graal .python .builtins .modules .ctypes .CtypesModuleBuiltins .CtypesDlSymNode ;
80
- import com .oracle .graal .python .builtins .modules .ctypes .CtypesModuleBuiltins .DLHandler ;
81
75
import com .oracle .graal .python .builtins .modules .ctypes .CtypesNodes .PyTypeCheck ;
82
76
import com .oracle .graal .python .builtins .modules .ctypes .FFIType .FieldGet ;
83
77
import com .oracle .graal .python .builtins .modules .ctypes .FFIType .FieldSet ;
87
81
import com .oracle .graal .python .builtins .modules .ctypes .memory .PointerNodes ;
88
82
import com .oracle .graal .python .builtins .objects .PNone ;
89
83
import com .oracle .graal .python .builtins .objects .buffer .PythonBufferAccessLibrary ;
84
+ import com .oracle .graal .python .builtins .objects .cext .PythonNativeVoidPtr ;
90
85
import com .oracle .graal .python .builtins .objects .common .HashingStorageNodes .HashingStorageSetItem ;
91
86
import com .oracle .graal .python .builtins .objects .dict .PDict ;
92
87
import com .oracle .graal .python .builtins .objects .memoryview .PMemoryView ;
93
88
import com .oracle .graal .python .builtins .objects .type .TypeNodes .GetBaseClassNode ;
94
89
import com .oracle .graal .python .builtins .objects .type .TypeNodes .InlinedIsSameTypeNode ;
95
90
import com .oracle .graal .python .lib .PyLongCheckNode ;
96
91
import com .oracle .graal .python .lib .PyObjectLookupAttr ;
92
+ import com .oracle .graal .python .nodes .ErrorMessages ;
97
93
import com .oracle .graal .python .nodes .PGuards ;
98
94
import com .oracle .graal .python .nodes .PNodeWithRaise ;
99
95
import com .oracle .graal .python .nodes .PRaiseNode ;
103
99
import com .oracle .graal .python .nodes .function .builtins .PythonBinaryBuiltinNode ;
104
100
import com .oracle .graal .python .nodes .function .builtins .PythonTernaryClinicBuiltinNode ;
105
101
import com .oracle .graal .python .nodes .function .builtins .clinic .ArgumentClinicProvider ;
102
+ import com .oracle .graal .python .runtime .exception .PException ;
106
103
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
107
104
import com .oracle .truffle .api .CompilerDirectives .TruffleBoundary ;
108
105
import com .oracle .truffle .api .dsl .Bind ;
109
106
import com .oracle .truffle .api .dsl .Cached ;
110
- import com .oracle .truffle .api .dsl .Fallback ;
111
107
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
112
108
import com .oracle .truffle .api .dsl .ImportStatic ;
113
109
import com .oracle .truffle .api .dsl .NodeFactory ;
@@ -201,17 +197,11 @@ Object CDataType_from_param(VirtualFrame frame, Object type, Object value,
201
197
public abstract static class FromAddressNode extends PythonBinaryBuiltinNode {
202
198
203
199
@ Specialization
204
- Object CDataType_from_address (Object type , int value ,
205
- @ Cached PyLong_AsVoidPtr asVoidPtr ,
200
+ static Object CDataType_from_address (Object type , Object value ,
201
+ @ Bind ("this" ) Node inliningTarget ,
202
+ @ Cached PointerNodes .PointerFromLongNode pointerFromLongNode ,
206
203
@ Cached PyCDataAtAddress atAddress ) {
207
- Object buf = asVoidPtr .execute (value );
208
- return atAddress .execute (type , buf , 0 );
209
- }
210
-
211
- @ SuppressWarnings ("unused" )
212
- @ Fallback
213
- Object error (Object type , Object arg ) {
214
- throw raise (TypeError , INTEGER_EXPECTED );
204
+ return atAddress .execute (type , pointerFromLongNode .execute (inliningTarget , value ));
215
205
}
216
206
}
217
207
@@ -235,29 +225,29 @@ Object CDataType_from_buffer(VirtualFrame frame, Object type, Object obj, int of
235
225
@ Cached AuditNode auditNode ) {
236
226
StgDictObject dict = pyTypeStgDictNode .checkAbstractClass (type , getRaiseNode ());
237
227
238
- PMemoryView buffer = memoryViewNode .execute (frame , obj );
228
+ PMemoryView mv = memoryViewNode .execute (frame , obj );
239
229
240
- if (buffer .isReadOnly ()) {
230
+ if (mv .isReadOnly ()) {
241
231
throw raise (TypeError , UNDERLYING_BUFFER_IS_NOT_WRITABLE );
242
232
}
243
233
244
- if (!buffer .isCContiguous ()) {
234
+ if (!mv .isCContiguous ()) {
245
235
throw raise (TypeError , UNDERLYING_BUFFER_IS_NOT_C_CONTIGUOUS );
246
236
}
247
237
248
238
if (offset < 0 ) {
249
239
throw raise (ValueError , OFFSET_CANNOT_BE_NEGATIVE );
250
240
}
251
241
252
- if (dict .size > buffer .getLength () - offset ) {
253
- throw raise (ValueError , BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES , buffer .getLength (), dict .size + offset );
242
+ if (dict .size > mv .getLength () - offset ) {
243
+ throw raise (ValueError , BUFFER_SIZE_TOO_SMALL_D_INSTEAD_OF_AT_LEAST_D_BYTES , mv .getLength (), dict .size + offset );
254
244
}
255
245
256
- auditNode .audit ("ctypes.cdata/buffer" , buffer , buffer .getLength (), offset );
246
+ auditNode .audit ("ctypes.cdata/buffer" , mv , mv .getLength (), offset );
257
247
258
- CDataObject result = atAddress .execute (type , buffer , offset );
248
+ CDataObject result = atAddress .execute (type , Pointer . memoryView ( mv ). withOffset ( offset ) );
259
249
260
- keepRefNode .execute (frame , result , -1 , buffer );
250
+ keepRefNode .execute (frame , result , -1 , mv );
261
251
262
252
return result ;
263
253
}
@@ -323,32 +313,41 @@ protected ArgumentClinicProvider getArgumentClinic() {
323
313
324
314
@ Specialization
325
315
Object CDataType_in_dll (VirtualFrame frame , Object type , Object dll , TruffleString name ,
316
+ @ Bind ("this" ) Node inliningTarget ,
326
317
@ Cached PyLongCheckNode longCheckNode ,
327
318
@ Cached ("create(T__HANDLE)" ) GetAttributeNode getAttributeNode ,
328
319
@ Cached PyCDataAtAddress atAddress ,
329
320
@ Cached AuditNode auditNode ,
330
- @ Cached PyLong_AsVoidPtr asVoidPtr ,
321
+ @ Cached PointerNodes . PointerFromLongNode pointerFromLongNode ,
331
322
@ Cached CtypesDlSymNode dlSymNode ) {
332
323
auditNode .audit ("ctypes.dlsym" , dll , name );
333
324
Object obj = getAttributeNode .executeObject (frame , dll );
334
325
if (!longCheckNode .execute (obj )) {
335
326
throw raise (TypeError , THE_HANDLE_ATTRIBUTE_OF_THE_SECOND_ARGUMENT_MUST_BE_AN_INTEGER );
336
327
}
337
- DLHandler handle = getHandleFromLongObject (obj , getContext (), asVoidPtr , getRaiseNode ());
338
- Object address = dlSymNode .execute (frame , handle , name , ValueError );
339
- return atAddress .execute (type , address , 0 );
328
+ Pointer handlePtr ;
329
+ try {
330
+ handlePtr = pointerFromLongNode .execute (inliningTarget , obj );
331
+ } catch (PException e ) {
332
+ throw raise (ValueError , ErrorMessages .COULD_NOT_CONVERT_THE_HANDLE_ATTRIBUTE_TO_A_POINTER );
333
+ }
334
+ Object address = dlSymNode .execute (frame , handlePtr , name , ValueError );
335
+ if (address instanceof PythonNativeVoidPtr ptr ) {
336
+ address = ptr .getPointerObject ();
337
+ }
338
+ return atAddress .execute (type , Pointer .nativeMemory (address ));
340
339
}
341
340
}
342
341
343
342
protected abstract static class PyCDataAtAddress extends PNodeWithRaise {
344
343
345
- abstract CDataObject execute (Object type , Object obj , int offset );
344
+ abstract CDataObject execute (Object type , Pointer pointer );
346
345
347
346
/*
348
347
* Box a memory block into a CData instance.
349
348
*/
350
349
@ Specialization
351
- CDataObject PyCData_AtAddress_bytes (Object type , byte [] buf , int offset ,
350
+ CDataObject PyCData_AtAddress (Object type , Pointer pointer ,
352
351
@ Cached PyTypeCheck pyTypeCheck ,
353
352
@ Cached PyTypeStgDictNode pyTypeStgDictNode ,
354
353
@ Cached PythonObjectFactory factory ) {
@@ -359,40 +358,11 @@ CDataObject PyCData_AtAddress_bytes(Object type, byte[] buf, int offset,
359
358
360
359
CDataObject pd = factory .createCDataObject (type );
361
360
assert pyTypeCheck .isCDataObject (pd );
362
- pd .b_ptr = Pointer . bytes ( buf , offset ) ;
361
+ pd .b_ptr = pointer ;
363
362
pd .b_length = stgdict .length ;
364
363
pd .b_size = stgdict .size ;
365
364
return pd ;
366
365
}
367
-
368
- protected static boolean isBytes (Object obj ) {
369
- return obj instanceof byte [];
370
- }
371
-
372
- @ Specialization (guards = "!isBytes(obj)" )
373
- CDataObject PyCData_AtAddress (Object type , Object obj , @ SuppressWarnings ("unused" ) int offset ,
374
- @ Cached PyTypeCheck pyTypeCheck ,
375
- @ Cached PyTypeStgDictNode pyTypeStgDictNode ,
376
- @ Cached AuditNode auditNode ,
377
- @ Cached PythonObjectFactory factory ) {
378
- auditNode .audit ("ctypes.cdata" , obj );
379
- // assert(PyType_Check(type));
380
- StgDictObject stgdict = pyTypeStgDictNode .checkAbstractClass (type , getRaiseNode ());
381
- stgdict .flags |= DICTFLAG_FINAL ;
382
-
383
- CDataObject pd = factory .createCDataObject (type );
384
- assert (pyTypeCheck .isCDataObject (pd ));
385
- if (obj instanceof PMemoryView ) {
386
- pd .b_ptr = Pointer .memoryView ((PMemoryView ) obj );
387
- } else {
388
- // TODO get Objects from numeric pointers.
389
- throw raise (NotImplementedError , toTruffleStringUncached ("Storage is not implemented." ));
390
- }
391
- pd .b_length = stgdict .length ;
392
- pd .b_size = stgdict .size ;
393
- return pd ;
394
- }
395
-
396
366
}
397
367
398
368
// corresponds to PyCData_get
0 commit comments