| 93 | } |
| 94 | |
| 95 | static int |
| 96 | NumExpr_init(NumExprObject *self, PyObject *args) |
| 97 | { |
| 98 | // NE2to3: Now uses structs instead of seperate arrays for each field |
| 99 | PyObject *bytes_prog = NULL, *reg_tuple = NULL; |
| 100 | NumExprOperation *program = NULL; |
| 101 | NumExprReg *registers = NULL; |
| 102 | PyObject *arrayObj; |
| 103 | PyObject *iter_reg = NULL; |
| 104 | int I, program_len = 0; |
| 105 | NE_REGISTER n_reg = 0, n_scalar = 0, n_temp = 0, n_array = 0, returnReg = -1, returnOperand = -1; |
| 106 | |
| 107 | // Build const blocks variables |
| 108 | npy_intp total_scalar_itemsize = 0, mem_offset = 0, total_temp_itemsize = 0; |
| 109 | char *scalar_mem = NULL, *mem_loc; |
| 110 | |
| 111 | BENCH_TIME(50); |
| 112 | |
| 113 | if( ! PyArg_ParseTuple(args, "SO", &bytes_prog, ®_tuple ) ) { |
| 114 | PyErr_Format(PyExc_RuntimeError, |
| 115 | "numexpr_object.cpp: Could not parse input arguments." ); |
| 116 | return -1; |
| 117 | } |
| 118 | // NE2to3: Move the check_program() logic into _Init before allocating |
| 119 | // new memory. It makes zeros sense to have it in interpreter.cpp |
| 120 | if( ! PyBytes_Check(bytes_prog) ) { // Check if program_bytes is a byte string |
| 121 | PyErr_Format(PyExc_RuntimeError, |
| 122 | "numexpr_object.cpp: argument 'program' is not a bytes string."); |
| 123 | return -1; |
| 124 | } |
| 125 | if (PyBytes_GET_SIZE(bytes_prog) % NE_PROG_LEN != 0) { |
| 126 | PyErr_Format(PyExc_RuntimeError, |
| 127 | "numexpr_object.cpp: invalid program: prog_len %d mod %d = %d", |
| 128 | PyBytes_GET_SIZE(bytes_prog), NE_PROG_LEN, PyBytes_GET_SIZE(bytes_prog) % NE_PROG_LEN ); |
| 129 | return -1; |
| 130 | } |
| 131 | if( ! PyTuple_Check(reg_tuple) ) { // Check if reg_tuple is a tuple |
| 132 | PyErr_Format(PyExc_RuntimeError, |
| 133 | "numexpr_object.cpp: argument 'registers' is not a tuple."); |
| 134 | return -1; |
| 135 | } |
| 136 | n_reg = (int)PyTuple_GET_SIZE( reg_tuple ); |
| 137 | if( n_reg > NE_MAX_BUFFERS ) { // Numpy is limited to 32 args at present |
| 138 | PyErr_Format(PyExc_RuntimeError, |
| 139 | "numexpr_object.cpp: No. buffers (%d) exceeds %d.", n_reg, NE_MAX_BUFFERS); |
| 140 | return -1; |
| 141 | } |
| 142 | |
| 143 | program_len = (int)( PyBytes_GET_SIZE(bytes_prog) / NE_PROG_LEN ); |
| 144 | // Cast from Python_Bytes->char array->NumExprOperation struct array |
| 145 | // which works because we use struct.pack() in Python. |
| 146 | |
| 147 | // We are avoiding using PyMalloc and similar due to the changes in 3.6 |
| 148 | // resulting in some inconsistant behavoir. |
| 149 | program = (NumExprOperation*)malloc( program_len * sizeof(NumExprOperation) ); |
| 150 | memcpy( program, PyBytes_AsString( bytes_prog ), program_len*sizeof(NumExprOperation) ); |
| 151 | |
| 152 | // Build registers |
nothing calls this directly
no test coverage detected
searching dependent graphs…