Skip to content

Commit 51db451

Browse files
committed
implement 'y' and 'y#' argument formats
1 parent 32382a8 commit 51db451

File tree

6 files changed

+55
-6
lines changed

6 files changed

+55
-6
lines changed

graalpython/com.oracle.graal.python.cext/src/modsupport.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,26 @@ int get_buffer_rw(PyObject *arg, Py_buffer *view) {
7979
return 0;
8080
}
8181

82+
Py_ssize_t convertbuffer(PyObject *arg, const void **p) {
83+
PyBufferProcs *pb = Py_TYPE(arg)->tp_as_buffer;
84+
Py_ssize_t count;
85+
Py_buffer view;
86+
87+
*p = NULL;
88+
if (pb != NULL && pb->bf_releasebuffer != NULL) {
89+
// *errmsg = "read-only bytes-like object";
90+
return -3;
91+
}
92+
93+
int get_buffer_result = get_buffer_r(arg, &view);
94+
if (get_buffer_result < 0) {
95+
return get_buffer_result;
96+
}
97+
count = view.len;
98+
*p = view.buf;
99+
PyBuffer_Release(&view);
100+
return count;
101+
}
82102

83103
typedef int (*parseargs_func)(PyObject *argv, PyObject *kwds, const char *format, void* kwdnames, void* varargs);
84104

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ public long getId() {
767767

768768
/**
769769
* Enum of basic C types. These type names need to stay in sync with the declarations in
770-
* 'capi.c'.
770+
* 'modsupport.c'.
771771
*/
772772
public enum LLVMType {
773773
int_t,

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/NativeCAPISymbol.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,7 @@ public enum NativeCAPISymbol implements NativeCExtSymbol {
147147
FUN_GET_NEWFUNC_TYPE_ID("get_newfunc_typeid"),
148148
FUN_GET_BUFFER_R("get_buffer_r"),
149149
FUN_GET_BUFFER_RW("get_buffer_rw"),
150+
FUN_CONVERTBUFFER("convertbuffer"),
150151
FUN_NATIVE_UNICODE_AS_STRING("native_unicode_as_string"),
151152
FUN_PY_UNICODE_GET_LENGTH("PyUnicode_GetLength"),
152153
FUN_GET_UINT32_ARRAY_TYPE_ID("get_uint32_array_typeid"),

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/CExtParseArgumentsNode.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.OverflowError;
4444
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.SystemError;
4545
import static com.oracle.graal.python.builtins.PythonBuiltinClassType.TypeError;
46+
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_CONVERTBUFFER;
4647
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_GET_BUFFER_R;
4748
import static com.oracle.graal.python.builtins.objects.cext.capi.NativeCAPISymbol.FUN_GET_BUFFER_RW;
4849

@@ -371,6 +372,7 @@ static ParserState doBufferR(ParserState stateIn, Object kwds, @SuppressWarnings
371372
@Shared("getArgNode") @Cached GetArgNode getArgNode,
372373
@Cached GetVaArgsNode getVaArgNode,
373374
@Cached PCallCExtFunction callGetBufferRwNode,
375+
@Shared("writeOutVarNode") @Cached WriteOutVarNode writeOutVarNode,
374376
@Cached(value = "createTN(stateIn)", uncached = "getUncachedTN(stateIn)") CExtToNativeNode argToSulongNode,
375377
@Shared("raiseNode") @Cached PRaiseNativeNode raiseNode) throws InteropException, ParseArgumentsException {
376378
ParserState state = stateIn;
@@ -383,15 +385,13 @@ static ParserState doBufferR(ParserState stateIn, Object kwds, @SuppressWarnings
383385
getbuffer(state.nativeContext, callGetBufferRwNode, raiseNode, argToSulongNode.execute(arg), pybufferPtr, true);
384386
}
385387
} else {
386-
// TODO(fa) convertbuffer: create a temporary 'Py_buffer' struct, call
387-
// 'get_buffer_r' and output the buffer's data pointer
388-
getVaArgNode.getPyObjectPtr(varargs, state.outIndex);
388+
Object voidPtr = getVaArgNode.getVoidPtr(varargs, state.outIndex);
389+
Object count = convertbuffer(state.nativeContext, callGetBufferRwNode, raiseNode, argToSulongNode.execute(arg), voidPtr);
389390
if (isLookahead(format, format_idx, '#')) {
390391
/* format_idx++; */
391392
// 'y#'
392-
// TODO(fa) additionally store size
393-
getVaArgNode.getPyObjectPtr(varargs, state.outIndex);
394393
state = state.incrementOutIndex();
394+
writeOutVarNode.writeInt64(varargs, state.outIndex, count);
395395
}
396396
}
397397
return state.incrementOutIndex();
@@ -940,6 +940,25 @@ private static void getbuffer(CExtContext nativeContext, PCallCExtFunction callG
940940
}
941941
}
942942

943+
private static int convertbuffer(CExtContext nativeContext, PCallCExtFunction callConvertbuffer, PRaiseNativeNode raiseNode, Object sulongArg, Object voidPtr)
944+
throws ParseArgumentsException {
945+
Object rc = callConvertbuffer.call(nativeContext, FUN_CONVERTBUFFER, sulongArg, voidPtr);
946+
if (!(rc instanceof Number)) {
947+
CompilerDirectives.shouldNotReachHere("wrong result of internal function");
948+
throw raise(raiseNode, SystemError, ErrorMessages.RETURNED_UNEXPECTE_RET_CODE_EXPECTED_INT_BUT_WAS_S, FUN_CONVERTBUFFER, rc.getClass());
949+
}
950+
int i = intValue((Number) rc);
951+
// first two results are the error results from getbuffer, the third is the one from convertbuffer
952+
if (i == -1) {
953+
throw raise(raiseNode, TypeError, ErrorMessages.READ_WRITE_BYTELIKE_OBJ);
954+
} else if (i == -2) {
955+
throw raise(raiseNode, TypeError, ErrorMessages.CONTIGUOUS_BUFFER);
956+
} else if (i == -3) {
957+
throw raise(raiseNode, TypeError, ErrorMessages.READ_ONLY_BYTELIKE_OBJ);
958+
}
959+
return i;
960+
}
961+
943962
@TruffleBoundary
944963
private static int intValue(Number rc) {
945964
return rc.intValue();
@@ -1215,6 +1234,10 @@ public final void writeUInt64(Object valist, int index, Object value) throws Int
12151234
execute(valist, index, LLVMType.uint64_ptr_t, value);
12161235
}
12171236

1237+
public final void writePySsizeT(Object valist, int index, Object value) throws InteropException {
1238+
execute(valist, index, LLVMType.Py_ssize_ptr_t, value);
1239+
}
1240+
12181241
public final void writeFloat(Object valist, int index, Object value) throws InteropException {
12191242
execute(valist, index, LLVMType.float_ptr_t, value);
12201243
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/common/GetVaArgsNode.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ public final Object getCharPtr(Object valist, int index) throws InteropException
8585
return execute(valist, index, LLVMType.char_ptr_t);
8686
}
8787

88+
public final Object getVoidPtr(Object valist, int index) throws InteropException {
89+
return execute(valist, index, LLVMType.void_ptr_t);
90+
}
91+
8892
public final Object getPyComplexPtr(Object valist, int index) throws InteropException {
8993
return execute(valist, index, LLVMType.Py_complex_ptr_t);
9094
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/nodes/ErrorMessages.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ public abstract class ErrorMessages {
485485
public static final String PYTHON_INT_TOO_LARGE_TO_CONV_TO_C_TYPE = "Python int too large to convert to %s-byte C type";
486486
public static final String RANGE_OUT_OF_BOUNDS = "range index out of range";
487487
public static final String READ_BYTE_OUT_OF_RANGE = "read byte out of range";
488+
public static final String READ_ONLY_BYTELIKE_OBJ = "read-only bytes-like object";
488489
public static final String READ_WRITE_BYTELIKE_OBJ = "read-write bytes-like object";
489490
public static final String READONLY_ATTRIBUTE = "readonly attribute";
490491
public static final String REQUIRES_CODE_OBJ = "%s() requires a code object with %d free vars, not %d";

0 commit comments

Comments
 (0)