Skip to content

Commit 41089c4

Browse files
committed
Re-add argument.keep
1 parent 0b55b3a commit 41089c4

File tree

6 files changed

+47
-32
lines changed

6 files changed

+47
-32
lines changed

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CArgObjectBuiltins.java

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -115,25 +115,25 @@ TruffleString doit(PyCArgObject self,
115115
case 'L':
116116
case 'q': // TODO big int
117117
case 'Q': // TODO big int
118-
ret = PythonUtils.formatJString("<cparam '%c' (%d)>", self.tag, self.value);
118+
ret = PythonUtils.formatJString("<cparam '%c' (%d)>", self.tag, self.valuePointer);
119119
break;
120120
case 'd':
121121
case 'f': {
122-
ret = PythonUtils.formatJString("<cparam '%c' (%f)>", self.tag, self.value);
122+
ret = PythonUtils.formatJString("<cparam '%c' (%f)>", self.tag, self.valuePointer);
123123
break;
124124
}
125125
case 'c':
126-
byte val = readByteNode.execute(inliningTarget, self.value);
126+
byte val = readByteNode.execute(inliningTarget, self.valuePointer);
127127
if (isLiteralChar((char) val)) {
128-
ret = PythonUtils.formatJString("<cparam '%c' ('%c')>", self.tag, self.value);
128+
ret = PythonUtils.formatJString("<cparam '%c' ('%c')>", self.tag, self.valuePointer);
129129
} else {
130-
ret = PythonUtils.formatJString("<cparam '%c' ('\\x%02x')>", self.tag, PythonAbstractObject.systemHashCode(self.value));
130+
ret = PythonUtils.formatJString("<cparam '%c' ('\\x%02x')>", self.tag, PythonAbstractObject.systemHashCode(self.valuePointer));
131131
}
132132
break;
133133
case 'z':
134134
case 'Z':
135135
case 'P':
136-
ret = PythonUtils.formatJString("<cparam '%c' 0x%x>", self.tag, PythonAbstractObject.systemHashCode(self.value));
136+
ret = PythonUtils.formatJString("<cparam '%c' 0x%x>", self.tag, PythonAbstractObject.systemHashCode(self.valuePointer));
137137
break;
138138
default:
139139
if (isLiteralChar(self.tag)) {
@@ -166,7 +166,7 @@ protected static PyCArgObject paramFunc(CDataObject self, StgDictObject stgDict,
166166
case PyCArrayTypeParamFunc -> {
167167
parg.tag = 'P';
168168
parg.pffi_type = FFIType.ffi_type_pointer;
169-
parg.value = self.b_ptr.createReference();
169+
parg.valuePointer = self.b_ptr.createReference();
170170
parg.obj = self;
171171
return parg;
172172
}
@@ -175,7 +175,7 @@ protected static PyCArgObject paramFunc(CDataObject self, StgDictObject stgDict,
175175
parg.tag = 'P';
176176
parg.pffi_type = FFIType.ffi_type_pointer;
177177
parg.obj = self;
178-
parg.value = self.b_ptr;
178+
parg.valuePointer = self.b_ptr;
179179
return parg;
180180
}
181181
// Corresponds to PyCSimpleType_paramfunc
@@ -188,15 +188,15 @@ protected static PyCArgObject paramFunc(CDataObject self, StgDictObject stgDict,
188188
parg.tag = code;
189189
parg.pffi_type = fd.pffi_type;
190190
parg.obj = self;
191-
parg.value = self.b_ptr;
191+
parg.valuePointer = self.b_ptr;
192192
return parg;
193193
}
194194
// Corresponds to StructUnionType_paramfunc
195195
case StructUnionTypeParamFunc -> {
196196
Pointer ptr = self.b_ptr;
197197
parg.pffi_type = stgDict.ffi_type_pointer;
198198
parg.tag = 'V';
199-
parg.value = ptr;
199+
parg.valuePointer = ptr;
200200
parg.size = self.b_size;
201201
parg.obj = self;
202202
return parg;

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/CtypesModuleBuiltins.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@
109109
import com.oracle.graal.python.builtins.modules.ctypes.StgDictBuiltins.PyTypeStgDictNode;
110110
import com.oracle.graal.python.builtins.modules.ctypes.memory.Pointer;
111111
import com.oracle.graal.python.builtins.modules.ctypes.memory.PointerNodes;
112+
import com.oracle.graal.python.builtins.modules.ctypes.memory.PointerReference;
112113
import com.oracle.graal.python.builtins.objects.PNone;
113114
import com.oracle.graal.python.builtins.objects.buffer.PythonBufferAccessLibrary;
114115
import com.oracle.graal.python.builtins.objects.bytes.BytesNodes.ToBytesNode;
@@ -972,7 +973,7 @@ Object doit(CDataObject obj, int offset,
972973
parg.tag = 'P';
973974
parg.pffi_type = FFIType.ffi_type_pointer;
974975
parg.obj = obj;
975-
parg.value = obj.b_ptr.createReference(offset);
976+
parg.valuePointer = obj.b_ptr.createReference(offset);
976977

977978
return parg;
978979
}
@@ -1067,6 +1068,8 @@ protected static final class argument {
10671068
FFIType ffi_type;
10681069
StgDictObject stgDict;
10691070
Object value;
1071+
// Used to hold reference to object that have native memory finalizers
1072+
Object keep;
10701073
}
10711074

10721075
/**
@@ -1438,14 +1441,16 @@ void convParam(VirtualFrame frame, Object obj, int index, argument pa, boolean i
14381441
if (obj instanceof CDataObject cdata) {
14391442
pa.stgDict = pyObjectStgDictNode.execute(cdata);
14401443
PyCArgObject carg = paramFuncNode.execute(cdata, pa.stgDict);
1441-
setArgValue(inliningTarget, pa, carg.value, carg.pffi_type, intrinsic, convertToParameterNode, readPointerNode);
1444+
setArgValue(inliningTarget, pa, carg.valuePointer, carg.pffi_type, intrinsic, convertToParameterNode, readPointerNode);
1445+
pa.keep = cdata;
14421446
return;
14431447
}
14441448

14451449
if (PGuards.isPyCArg(obj)) {
14461450
PyCArgObject carg = (PyCArgObject) obj;
14471451
pa.stgDict = pyObjectStgDictNode.execute(carg.obj); // helpful for llvm backend
1448-
setArgValue(inliningTarget, pa, carg.value, carg.pffi_type, intrinsic, convertToParameterNode, readPointerNode);
1452+
setArgValue(inliningTarget, pa, carg.valuePointer, carg.pffi_type, intrinsic, convertToParameterNode, readPointerNode);
1453+
pa.keep = carg;
14491454
return;
14501455
}
14511456

@@ -1475,7 +1480,10 @@ void convParam(VirtualFrame frame, Object obj, int index, argument pa, boolean i
14751480
int len = bufferLib.getBufferLength(obj);
14761481
byte[] bytes = new byte[len + 1];
14771482
bufferLib.readIntoByteArray(obj, 0, bytes, 0, len);
1478-
setArgValue(inliningTarget, pa, Pointer.bytes(bytes).createReference(), FFIType.ffi_type_pointer, intrinsic, convertToParameterNode, readPointerNode);
1483+
Pointer valuePtr = Pointer.bytes(bytes);
1484+
setArgValue(inliningTarget, pa, valuePtr.createReference(), FFIType.ffi_type_pointer, intrinsic, convertToParameterNode, readPointerNode);
1485+
// Unlike CPython, we can attach the lifetime directly to the argument object
1486+
new PointerReference(pa, valuePtr, PythonContext.get(this).getSharedFinalizer());
14791487
return;
14801488
}
14811489

@@ -1484,7 +1492,10 @@ void convParam(VirtualFrame frame, Object obj, int index, argument pa, boolean i
14841492
int len = string.byteLength(WCHAR_T_ENCODING);
14851493
byte[] bytes = new byte[len + WCHAR_T_SIZE];
14861494
copyToByteArrayNode.execute(string, 0, bytes, 0, len, WCHAR_T_ENCODING);
1487-
setArgValue(inliningTarget, pa, Pointer.bytes(bytes).createReference(), FFIType.ffi_type_pointer, intrinsic, convertToParameterNode, readPointerNode);
1495+
Pointer valuePtr = Pointer.bytes(bytes);
1496+
setArgValue(inliningTarget, pa, valuePtr.createReference(), FFIType.ffi_type_pointer, intrinsic, convertToParameterNode, readPointerNode);
1497+
// Unlike CPython, we can attach the lifetime directly to the argument object
1498+
new PointerReference(pa, valuePtr, PythonContext.get(this).getSharedFinalizer());
14881499
return;
14891500
}
14901501

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/LazyPyCSimpleTypeBuiltins.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -157,8 +157,8 @@ Object c_wchar_p_from_param(VirtualFrame frame, Object type, Object value,
157157
PyCArgObject parg = factory().createCArgObject();
158158
parg.pffi_type = ffi_type_pointer;
159159
parg.tag = 'Z';
160-
parg.value = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
161-
parg.obj = setFuncNode.execute(frame, FieldDesc.Z.setfunc, parg.value, value, 0);
160+
parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
161+
parg.obj = setFuncNode.execute(frame, FieldDesc.Z.setfunc, parg.valuePointer, value, 0);
162162
return parg;
163163
}
164164
boolean res = isInstanceNode.executeWith(frame, value, type);
@@ -215,8 +215,8 @@ Object voidPtr(@SuppressWarnings("unused") Object type, Object value,
215215
PyCArgObject parg = factory().createCArgObject();
216216
parg.pffi_type = ffi_type_pointer;
217217
parg.tag = 'P';
218-
parg.value = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
219-
setFuncNode.execute(null, FFIType.FieldSet.P_set, parg.value, value, 0);
218+
parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
219+
setFuncNode.execute(null, FFIType.FieldSet.P_set, parg.valuePointer, value, 0);
220220
parg.obj = PNone.NONE;
221221
return parg;
222222
}
@@ -228,8 +228,8 @@ Object bytes(@SuppressWarnings("unused") Object type, PBytes value,
228228
PyCArgObject parg = factory().createCArgObject();
229229
parg.pffi_type = ffi_type_pointer;
230230
parg.tag = 'z';
231-
parg.value = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
232-
setFuncNode.execute(null, FFIType.FieldSet.z_set, parg.value, value, 0);
231+
parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
232+
setFuncNode.execute(null, FFIType.FieldSet.z_set, parg.valuePointer, value, 0);
233233
parg.obj = value;
234234
return parg;
235235
}
@@ -241,8 +241,8 @@ Object string(@SuppressWarnings("unused") Object type, TruffleString value,
241241
PyCArgObject parg = factory().createCArgObject();
242242
parg.pffi_type = ffi_type_pointer;
243243
parg.tag = 'Z';
244-
parg.value = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
245-
setFuncNode.execute(null, FFIType.FieldSet.Z_set, parg.value, value, 0);
244+
parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
245+
setFuncNode.execute(null, FFIType.FieldSet.Z_set, parg.valuePointer, value, 0);
246246
parg.obj = value;
247247
return parg;
248248
}
@@ -280,7 +280,7 @@ Object c_void_p_from_param(VirtualFrame frame, Object type, Object value,
280280
PyCArgObject parg = factory().createCArgObject();
281281
parg.pffi_type = ffi_type_pointer;
282282
parg.tag = 'P';
283-
parg.value = func.b_ptr;
283+
parg.valuePointer = func.b_ptr;
284284
parg.obj = value;
285285
return parg;
286286
}
@@ -295,7 +295,7 @@ Object c_void_p_from_param(VirtualFrame frame, Object type, Object value,
295295
parg.tag = 'Z';
296296
parg.obj = value;
297297
/* Remember: b_ptr points to where the pointer is stored! */
298-
parg.value = ((CDataObject) value).b_ptr;
298+
parg.valuePointer = ((CDataObject) value).b_ptr;
299299
return parg;
300300
}
301301
}
@@ -326,8 +326,8 @@ Object bytes(@SuppressWarnings("unused") Object type, PBytes value,
326326
PyCArgObject parg = factory().createCArgObject();
327327
parg.pffi_type = ffi_type_pointer;
328328
parg.tag = 'z';
329-
parg.value = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
330-
setFuncNode.execute(null, FFIType.FieldSet.z_set, parg.value, value, 0);
329+
parg.valuePointer = Pointer.allocate(parg.pffi_type, parg.pffi_type.size);
330+
setFuncNode.execute(null, FFIType.FieldSet.z_set, parg.valuePointer, value, 0);
331331
parg.obj = value;
332332
return parg;
333333
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCArgObject.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,11 @@ public final class PyCArgObject extends PythonBuiltinObject {
4848

4949
FFIType pffi_type;
5050
char tag;
51-
Pointer value;
51+
/*
52+
* In CPython, the struct directly contains the value as an union. We use a pointer to a value,
53+
* thus there is one more pointer indirection.
54+
*/
55+
Pointer valuePointer;
5256
Object obj;
5357
int size;
5458

@@ -57,7 +61,7 @@ public PyCArgObject(Object cls, Shape instanceShape) {
5761
pffi_type = null;
5862
tag = '\0';
5963
obj = null;
60-
value = Pointer.NULL;
64+
valuePointer = Pointer.NULL;
6165
}
6266

6367
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCPointerTypeBuiltins.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ protected PyCArgObject byref(Object obj,
189189
parg.tag = 'P';
190190
parg.pffi_type = ffi_type_pointer;
191191
parg.obj = cdata;
192-
parg.value = cdata.b_ptr;
192+
parg.valuePointer = cdata.b_ptr;
193193
return parg;
194194
}
195195

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/modules/ctypes/PyCSimpleTypeBuiltins.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -324,9 +324,9 @@ Object PyCSimpleType_from_param(VirtualFrame frame, Object type, Object value,
324324
PyCArgObject parg = factory().createCArgObject();
325325
parg.tag = code;
326326
parg.pffi_type = fd.pffi_type;
327-
parg.value = Pointer.allocate(parg.pffi_type, dict.size);
327+
parg.valuePointer = Pointer.allocate(parg.pffi_type, dict.size);
328328
try {
329-
parg.obj = setFuncNode.execute(frame, fd.setfunc, parg.value, value, 0);
329+
parg.obj = setFuncNode.execute(frame, fd.setfunc, parg.valuePointer, value, 0);
330330
return parg;
331331
} catch (PException e) {
332332
// pass through to check for _as_parameter_

0 commit comments

Comments
 (0)