Skip to content

Commit 97ecf32

Browse files
committed
Support operator overloading
1 parent fb0e219 commit 97ecf32

File tree

10 files changed

+555
-18
lines changed

10 files changed

+555
-18
lines changed

examples/nfft.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,18 @@
99

1010
$finufft = PyCore::import('finufft');
1111

12-
$d = 1;
13-
$M = 1000;
14-
$N = 2048;
12+
$d = PyCore::int(1);
13+
$M = PyCore::int(1000);
14+
$N = PyCore::int(2048);
1515
$x = $operator->sub($np->linspace(0, 1, $M, endpoint: false), 0.5);
1616

1717
$c = $np->ones($M, dtype: $np->complex128);
1818
$f = $finufft->nufft1d1($operator->mul($operator->mul($x, 2), $np->pi), $c, n_modes: $N, eps: 1.0E-14);
19-
$k = $np->arange($operator->floordiv(-$N, 2), $operator->floordiv($N, 2));
19+
$k = $np->arange($operator->floordiv($N->__neg__(), 2), $operator->floordiv($N, 2));
20+
2021
$f_shifted = $np->fft->fftshift($f);
2122
$k_shifted = $np->fft->fftshift($k);
23+
2224
$plt->figure(figsize: PyCore::tuple([12, 8]));
2325
$plt->subplot(3, 1, 1);
2426
$plt->plot($k_shifted, $f_shifted->real, "b-", linewidth: 0.8);
@@ -27,18 +29,21 @@
2729
$plt->ylabel("Re(f[k])");
2830
$plt->grid(true);
2931
$plt->subplot(3, 1, 2);
32+
3033
$plt->plot($k_shifted, $f_shifted->imag, "r-", linewidth: 0.8);
3134
$plt->title("Imaginary Part");
3235
$plt->xlabel("Frequency Index k");
3336
$plt->ylabel("Im(f[k])");
3437
$plt->grid(true);
3538
$plt->subplot(3, 1, 3);
39+
3640
$plt->plot($k_shifted, $np->abs($f_shifted), "g-", linewidth: 1);
3741
$plt->title("Magnitude |f[k]|");
3842
$plt->xlabel("Frequency Index k");
3943
$plt->ylabel("|f[k]|");
4044
$plt->grid(true);
4145
$plt->tight_layout();
46+
4247
$plt->savefig("nfft_result.png", dpi: 150);
4348
$plt->show();
4449

format.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
clang-format -i src/bridge/*.cc
2+
clang-format -i src/php/*.cc

include/phpy.h

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,21 +108,31 @@ void object2string(PyObject *pv, zval *zv);
108108
void long2long(PyObject *pv, zval *zv);
109109
/**
110110
* Type conversion, PHP to Python
111+
* Return value: New reference.
111112
*/
112113
PyObject *php2py(zval *zv);
113114
/**
114115
* PHP to Python, Convert actual value to python object type as much as possible
116+
* Return value: New reference.
115117
*/
116118
PyObject *php2py_object(zval *zv);
117119
/**
118120
* Python to Python, Convert actual value to PHP scalar type as much as possible
119121
*/
120122
PyObject *py2py_scalar(PyObject *pv);
121-
123+
/**
124+
* Return value: New reference.
125+
*/
122126
PyObject *array2list(zend_array *ht);
127+
/**
128+
* Return value: New reference.
129+
*/
123130
static inline PyObject *array2list(zval *zv) {
124131
return array2list(Z_ARRVAL_P(zv));
125132
}
133+
/**
134+
* Return value: New reference.
135+
*/
126136
PyObject *array2set(zend_array *ht);
127137
static inline PyObject *array2set(zval *zv) {
128138
return array2set(Z_ARRVAL_P(zv));
@@ -133,14 +143,27 @@ static inline PyObject *array2tuple(zval *zv) {
133143
}
134144
PyObject *resource2py(zval *zres);
135145
PyObject *reference2py(zval *zv);
146+
/**
147+
* Return value: New reference.
148+
*/
136149
PyObject *array2dict(zend_array *ht);
150+
/**
151+
* Return value: New reference.
152+
*/
137153
PyObject *string2py(zend_string *zv);
154+
/**
155+
* Return value: New reference.
156+
*/
138157
PyObject *long2long(zval *zv);
139-
158+
/**
159+
* Return value: New reference.
160+
*/
140161
static inline PyObject *array2dict(zval *zv) {
141162
return array2dict(Z_ARRVAL_P(zv));
142163
}
143-
164+
/**
165+
* Return value: New reference.
166+
*/
144167
static inline PyObject *string2py(zval *zv) {
145168
return string2py(Z_STR_P(zv));
146169
}
@@ -185,6 +208,7 @@ int php_class_iter_init(INIT_FUNC_ARGS);
185208
int php_class_fn_init(INIT_FUNC_ARGS);
186209
int php_class_error_init(INIT_FUNC_ARGS);
187210
void php_class_init_all(INIT_FUNC_ARGS);
211+
int php_python_operator_init(INIT_FUNC_ARGS);
188212

189213
zend_class_entry *phpy_object_get_ce();
190214
zend_class_entry *phpy_sequence_get_ce();
@@ -239,6 +263,11 @@ namespace php {
239263
void new_module(zval *zv, PyObject *pv);
240264
void new_object(zval *zv, PyObject *pv);
241265
void new_object(zval *zv, PyObject *pv, zend_class_entry *ce);
266+
/**
267+
* This function does not increment the reference count for pv object;
268+
* a new reference must be passed in, otherwise a gc error will occur.
269+
*/
270+
void new_object_no_addref(zval *zv, PyObject *pv);
242271
void new_dict(zval *zv, PyObject *pv);
243272
void new_list(zval *zv, PyObject *pv);
244273
void new_tuple(zval *zv, PyObject *pv);

src/bridge/core.cc

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,9 @@ void long2long(PyObject *pv, zval *zv) {
179179
}
180180
}
181181

182+
/**
183+
* Return value: New reference.
184+
*/
182185
PyObject *long2long(zval *zv) {
183186
PyObject *pv;
184187
if (Z_TYPE_P(zv) == IS_LONG) {
@@ -218,6 +221,9 @@ static bool py2php_base_type(PyObject *pv, zval *zv) {
218221
return true;
219222
}
220223

224+
/**
225+
* Return value: New reference.
226+
*/
221227
PyObject *array2list(zend_array *ht) {
222228
zval *current;
223229
PyObject *list = PyList_New(0);
@@ -230,6 +236,9 @@ PyObject *array2list(zend_array *ht) {
230236
return list;
231237
}
232238

239+
/**
240+
* Return value: New reference.
241+
*/
233242
PyObject *array2tuple(zend_array *ht) {
234243
zval *current;
235244
PyObject *tuple = PyTuple_New(phpy::php::array_count(ht));
@@ -243,6 +252,9 @@ PyObject *array2tuple(zend_array *ht) {
243252
return tuple;
244253
}
245254

255+
/**
256+
* Return value: New reference.
257+
*/
246258
PyObject *array2set(zend_array *ht) {
247259
zval *current;
248260
PyObject *pset = PySet_New(0);
@@ -271,6 +283,9 @@ static void iterator2array(PyObject *pv, zval *zv) {
271283
Py_DECREF(iter);
272284
}
273285

286+
/**
287+
* Return value: New reference.
288+
*/
274289
PyObject *array2dict(zend_array *ht) {
275290
uint32_t index;
276291
zend_string *key;
@@ -322,6 +337,9 @@ static void dict2array(PyObject *pv, zval *zv) {
322337
Py_DECREF(iter);
323338
}
324339

340+
/**
341+
* Return value: New reference.
342+
*/
325343
static PyObject *array2py(zval *zv) {
326344
zend_array *ht = Z_ARRVAL_P(zv);
327345
if (zend_array_is_list(ht)) {
@@ -368,10 +386,15 @@ PyObject *php2py(zval *zv) {
368386
case IS_ARRAY:
369387
return array2py(zv);
370388
default:
371-
return PyErr_Format(PyExc_TypeError, "[php2py] Unsupported php type[%d]", Z_TYPE_P(zv));
389+
PyErr_Format(PyExc_TypeError, "[php2py] Unsupported php type[%d]", Z_TYPE_P(zv));
390+
Py_INCREF(Py_None);
391+
return Py_None;
372392
}
373393
}
374394

395+
/**
396+
* Return value: New reference.
397+
*/
375398
PyObject *php2py_object(zval *zv) {
376399
PyObject *pv = php2py_base_type(zv);
377400
if (pv != NULL) {
@@ -383,7 +406,9 @@ PyObject *php2py_object(zval *zv) {
383406
case IS_ARRAY:
384407
return phpy::python::new_array(zv);
385408
default:
386-
return PyErr_Format(PyExc_TypeError, "[php2py] Unsupported php type[%d]", Z_TYPE_P(zv));
409+
PyErr_Format(PyExc_TypeError, "[php2py] Unsupported php type[%d]", Z_TYPE_P(zv));
410+
Py_INCREF(Py_None);
411+
return Py_None;
387412
}
388413
}
389414

src/php/core.cc

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -122,9 +122,7 @@ ZEND_METHOD(PyCore, int) {
122122
Z_PARAM_ZVAL(zv)
123123
ZEND_PARSE_PARAMETERS_END_EX(return );
124124

125-
PyObject *pv = long2long(zv);
126-
phpy::php::new_object(return_value, pv);
127-
Py_DECREF(pv);
125+
phpy::php::new_object_no_addref(return_value, long2long(zv));
128126
}
129127

130128
ZEND_METHOD(PyCore, object) {
@@ -138,7 +136,7 @@ ZEND_METHOD(PyCore, object) {
138136
if (zv == NULL || ZVAL_IS_NULL(zv)) {
139137
phpy::php::call_builtin_fn(ZEND_STRL("object"), nullptr, return_value);
140138
} else {
141-
phpy::php::new_object(return_value, php2py_object(zv));
139+
phpy::php::new_object_no_addref(return_value, php2py_object(zv));
142140
}
143141
}
144142

@@ -149,9 +147,7 @@ ZEND_METHOD(PyCore, float) {
149147
Z_PARAM_ZVAL(zv)
150148
ZEND_PARSE_PARAMETERS_END_EX(return );
151149

152-
PyObject *pv = PyFloat_FromDouble(zval_get_double(zv));
153-
phpy::php::new_object(return_value, pv);
154-
Py_DECREF(pv);
150+
phpy::php::new_object_no_addref(return_value, PyFloat_FromDouble(zval_get_double(zv)));
155151
}
156152

157153
ZEND_METHOD(PyCore, fn) {
@@ -281,6 +277,8 @@ PHP_MINIT_FUNCTION(phpy) {
281277
}
282278

283279
php_class_init_all(INIT_FUNC_ARGS_PASSTHRU);
280+
php_python_operator_init(INIT_FUNC_ARGS_PASSTHRU);
281+
284282
return SUCCESS;
285283
}
286284

@@ -413,8 +411,7 @@ ZEND_METHOD(PyCore, bytes) {
413411
pv = PyBytes_FromStringAndSize(Z_STRVAL_P(zv), Z_STRLEN_P(zv));
414412
zend_string_release(s);
415413
}
416-
phpy::php::new_object(return_value, pv);
417-
Py_DECREF(pv);
414+
phpy::php::new_object_no_addref(return_value, pv);
418415
}
419416

420417
ZEND_METHOD(PyCore, fileno) {

src/php/error.cc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ zend_class_entry *PyError_ce;
2626

2727
namespace phpy {
2828
namespace php {
29+
/**
30+
* PyErr_Occurred(): Return value: Borrowed reference
31+
*/
2932
void new_error(zval *zv, PyObject *error) {
3033
object_init_ex(zv, PyError_ce);
3134
zval zerror;

src/php/object.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,10 @@ void new_object(zval *zv, PyObject *object, zend_class_entry *ce) {
140140
Py_INCREF(object);
141141
phpy_object_get_object(zv)->object = object;
142142
}
143+
void new_object_no_addref(zval *zv, PyObject *object) {
144+
object_init_ex(zv, PyObject_ce);
145+
phpy_object_get_object(zv)->object = object;
146+
}
143147
PyObject *arg_1(INTERNAL_FUNCTION_PARAMETERS) {
144148
zval *zk;
145149

0 commit comments

Comments
 (0)