From 8842a2fa593c68b2dbd197e62304aa4ce77dad64 Mon Sep 17 00:00:00 2001 From: CismonX Date: Sun, 17 Mar 2019 11:30:03 +0800 Subject: [PATCH] update --- EXPERIMENTAL | 0 src/complex.hh | 31 ++++++++++++++++- src/php_arma.hh | 89 ++++++++++++++++++++++++------------------------- 3 files changed, 74 insertions(+), 46 deletions(-) create mode 100644 EXPERIMENTAL diff --git a/EXPERIMENTAL b/EXPERIMENTAL new file mode 100644 index 0000000..e69de29 diff --git a/src/complex.hh b/src/complex.hh index a6212bd..4472e8f 100644 --- a/src/complex.hh +++ b/src/complex.hh @@ -9,6 +9,10 @@ #include "php_arma.hh" +#include + +typedef std::complex cx_double; + namespace php_arma { template @@ -19,7 +23,9 @@ namespace php_arma extern zend_class_entry *complex_ce; template - PHP_ARMA_DECLARE_CE_HANDLERS(complex); + PHP_ARMA_DECLARE_CE_HANDLERS(complex); + + /// Helper functions for handling cx_double types. template <> zend_always_inline bool zval_is_scalar(zval *zv) @@ -27,11 +33,34 @@ namespace php_arma return Z_TYPE_P(zv) == IS_OBJECT && instanceof_function(Z_OBJCE_P(zv), PHP_ARMA_CE(complex, double)); } + template <> + struct scalar_type { + static const int value = IS_OBJECT; + }; + template <> zend_always_inline const char *scalar_type_name() { return ZSTR_VAL(PHP_ARMA_CE(complex, double)->name); } + + template <> zend_always_inline + cx_double zval_get_scalar(zval *zv) + { + auto zobj = Z_OBJ_P(zv); + return { Z_DVAL_P(OBJ_PROP_NUM(zobj, 0)), Z_DVAL_P(OBJ_PROP_NUM(zobj, 1)) }; + } + + zend_always_inline + void zval_set_scalar(zval *zv, cx_double val) + { + auto zobj = object_create(PHP_ARMA_CE(complex, double), PHP_ARMA_HANDLERS(complex, double)); + ZVAL_DOUBLE(OBJ_PROP_NUM(zobj, 0), val.real()); + ZVAL_DOUBLE(OBJ_PROP_NUM(zobj, 1), val.imag()); + + zval_ptr_dtor(zv); + ZVAL_OBJ(zv, zobj); + } } #endif //!PHP_ARMA_COMPLEX_HH diff --git a/src/php_arma.hh b/src/php_arma.hh index 6a253ce..427c14b 100644 --- a/src/php_arma.hh +++ b/src/php_arma.hh @@ -13,7 +13,8 @@ #include #include -#include + +#include #define PHP_ARMA_VERSION "0.0.1" @@ -23,8 +24,6 @@ extern zend_module_entry arma_module_entry; -typedef std::complex cx_double; - /// Helper macros for method entry. #define Z_OBJNAME_P(zval_p) \ @@ -81,6 +80,8 @@ typedef std::complex cx_double; namespace php_arma { + /// Helper functions for initializing class entry and object handlers. + template zend_class_entry *ce_init(const char *name, const zend_function_entry *methods, F init_func) { @@ -111,12 +112,11 @@ namespace php_arma return ce_init(name, methods, zend_register_internal_class, interfaces...); } - // Although methods are declared in interfaces as you see in the stubs, - // nothing is declared in the internal interface implementation. - template zend_class_entry *interface_register(const char *name) { + // Although methods are declared in interfaces as you see in the stubs, + // nothing is declared in the internal interface implementation. return ce_init(name, nullptr, zend_register_internal_class); } @@ -156,7 +156,8 @@ namespace php_arma return reinterpret_cast(zobj) - 1; } - /// Create a zend_object which wraps a native object. + /// Helper functions for creating objects. + template zend_object *object_create(zend_class_entry *ce, F init) { @@ -169,29 +170,18 @@ namespace php_arma return zobj; } - /// Create a normal zend_object. - template - zend_object *object_create(zend_class_entry *ce) + zend_always_inline + zend_object *object_create(zend_class_entry *ce, const zend_object_handlers *handlers = &std_object_handlers) { auto zobj = reinterpret_cast(ecalloc(1, sizeof(zend_object) + zend_object_properties_size(ce))); zend_object_std_init(zobj, ce); object_properties_init(zobj, ce); - zobj->handlers = &std_object_handlers; + zobj->handlers = handlers; return zobj; } - zend_always_inline - void zval_set_scalar(zval *zv, double val) - { - ZVAL_DOUBLE(zv, val); - } - - zend_always_inline - void zval_set_scalar(zval *zv, zend_long val) - { - ZVAL_LONG(zv, val); - } + /// Helper functions for handling scalar types. template struct false_type : std::false_type {}; @@ -202,24 +192,6 @@ namespace php_arma static_assert(false_type::value, "Type should be zend_long, double or cx_double"); } - template - T zval_get_scalar(zval *zv) - { - assert_bad_type(); - } - - template <> zend_always_inline - double zval_get_scalar(zval *zv) - { - return Z_DVAL_P(zv); - } - - template <> zend_always_inline - zend_long zval_get_scalar(zval *zv) - { - return Z_LVAL_P(zv); - } - template bool zval_is_scalar(zval *zv) { @@ -251,11 +223,6 @@ namespace php_arma static const int value = IS_LONG; }; - template <> - struct scalar_type { - static const int value = IS_OBJECT; - }; - template const char *scalar_type_name() { @@ -274,6 +241,36 @@ namespace php_arma return zend_get_type_by_const(IS_LONG); } + template + T zval_get_scalar(zval *zv) + { + assert_bad_type(); + } + + template <> zend_always_inline + double zval_get_scalar(zval *zv) + { + return Z_DVAL_P(zv); + } + + template <> zend_always_inline + zend_long zval_get_scalar(zval *zv) + { + return Z_LVAL_P(zv); + } + + zend_always_inline + void zval_set_scalar(zval *zv, double val) + { + ZVAL_DOUBLE(zv, val); + } + + zend_always_inline + void zval_set_scalar(zval *zv, zend_long val) + { + ZVAL_LONG(zv, val); + } + zend_always_inline const char *zval_get_type_name(zval *zv) { @@ -284,6 +281,8 @@ namespace php_arma } } + /// Helper functions for throwing exceptions when errors occur. + zend_always_inline void ex_bad_type(const char *expected, const char *got) {