diff --git a/src/common/php_arma.hh b/src/common/php_arma.hh index 04660cc..4eccfc1 100644 --- a/src/common/php_arma.hh +++ b/src/common/php_arma.hh @@ -21,7 +21,11 @@ #define PHP_ARMA_VERSION "0.0.1" #if PHP_VERSION_ID >= 70400 -#define ZEND_ACC_CTOR 0 +#define ZOBJ_WRITE_PROP_RET() return value +#define ZOBJ_WRITE_PROP_FAIL_RET() return &EG(error_zval) +#else +#define ZOBJ_WRITE_PROP_RET() +#define ZOBJ_WRITE_PROP_FAIL_RET() return #endif /// Helper macros for method entry. @@ -130,6 +134,12 @@ namespace php_arma { extern zend_module_entry module_entry; +#if PHP_VERSION_ID >= 70400 + using zobj_write_prop_ret_t = zval*; +#else + using zobj_write_prop_ret_t = void; +#endif + /// Utilities. namespace util { @@ -149,11 +159,6 @@ namespace php_arma /// Helpers for compile-time string concatenation for better module startup performance. namespace str { - template - using seq = std::integer_sequence; - template - using seq_impl = std::make_integer_sequence; - constexpr auto get_len(const char *str) { auto i = 0; @@ -164,18 +169,17 @@ namespace php_arma template struct concat_impl; template - struct concat_impl, Str2, seq> + struct concat_impl, Str2, std::index_sequence> { - static constexpr const char value[] - { + static constexpr const char value[] { Str1[Len1]..., Str2[Len2]..., 0 }; }; template - constexpr auto concat - { - concat_impl, Str2, seq_impl>::value + constexpr auto concat { + concat_impl, + Str2, std::make_index_sequence>::value }; constexpr const char namespace_prefix[] = "Arma\\"; @@ -183,14 +187,12 @@ namespace php_arma constexpr const char empty[] = ""; template - constexpr auto with_arma_prefix - { + constexpr auto with_arma_prefix { concat }; template - constexpr auto with_internal_prefix - { + constexpr auto with_internal_prefix { concat }; } diff --git a/src/complex.cc b/src/complex.cc index ce2246d..b61e90f 100644 --- a/src/complex.cc +++ b/src/complex.cc @@ -312,28 +312,29 @@ namespace php_arma } template - void complex::write_property(zval *obj, zval *member, zval *value, void**) + zobj_write_prop_ret_t complex::write_property(zval *obj, zval *member, zval *value, void**) { // Theoretically we won't get non-string values here, add type check just in case. if (UNEXPECTED(Z_TYPE_P(member) != IS_STRING)) { throw_error("unexpected error, please contact developer."); - return; + ZOBJ_WRITE_PROP_FAIL_RET(); } if (UNEXPECTED(!zval_check_scalar(value))) { - return; + ZOBJ_WRITE_PROP_FAIL_RET(); } if (strcmp(Z_STRVAL_P(member), "real") == 0) { object_set_property(Z_OBJ_P(obj), 0, value); - return; + ZOBJ_WRITE_PROP_RET(); } if (strcmp(Z_STRVAL_P(member), "imag") == 0) { object_set_property(Z_OBJ_P(obj), 1, value); - return; + ZOBJ_WRITE_PROP_RET(); } throw_error("bad property name for %s, expected 'real' or 'imag', '%s' given", Z_OBJNAME_P(obj), Z_STRVAL_P(member)); + ZOBJ_WRITE_PROP_FAIL_RET(); } template diff --git a/src/complex.hh b/src/complex.hh index d691b7c..ad47f3a 100644 --- a/src/complex.hh +++ b/src/complex.hh @@ -109,7 +109,7 @@ namespace php_arma static PHP_FUNCTION(__toString); static zval *read_dimension(zval*, zval*, int, zval*); - static void write_property(zval*, zval*, zval*, void**); + static zobj_write_prop_ret_t write_property(zval*, zval*, zval*, void**); static int compare_objects(zval*, zval*); static void ce_init(zend_class_entry*); diff --git a/src/operators.cc b/src/operators.cc index 6e0af45..a4fad27 100644 --- a/src/operators.cc +++ b/src/operators.cc @@ -247,6 +247,26 @@ namespace php_arma }); } + int assign_op_handler(zend_execute_data *execute_data) + { + switch (EX(opline)->extended_value) { + case ZEND_ADD: + return add_assign_handler(execute_data); + case ZEND_SUB: + return sub_assign_handler(execute_data); + case ZEND_MUL: + return mul_assign_handler(execute_data); + case ZEND_DIV: + return div_assign_handler(execute_data); + case ZEND_MOD: + return mod_assign_handler(execute_data); + case ZEND_POW: + return pow_assign_handler(execute_data); + default: + return ZEND_USER_OPCODE_DISPATCH; + } + } + template zend_always_inline void set_op_handlers(Ts&&... op_handlers) @@ -260,17 +280,21 @@ namespace php_arma { set_op_handlers( std::make_tuple(ZEND_ADD, add_handler), - std::make_tuple(ZEND_ASSIGN_ADD, add_assign_handler), std::make_tuple(ZEND_SUB, sub_handler), - std::make_tuple(ZEND_ASSIGN_SUB, sub_assign_handler), std::make_tuple(ZEND_MUL, mul_handler), - std::make_tuple(ZEND_ASSIGN_MUL, mul_assign_handler), std::make_tuple(ZEND_DIV, div_handler), - std::make_tuple(ZEND_ASSIGN_DIV, div_assign_handler), std::make_tuple(ZEND_MOD, mod_handler), - std::make_tuple(ZEND_ASSIGN_MOD, mod_assign_handler), std::make_tuple(ZEND_POW, pow_handler), +#if PHP_VERSION_ID >= 70400 + std::make_tuple(ZEND_ASSIGN_OP, assign_op_handler), +#else + std::make_tuple(ZEND_ASSIGN_ADD, add_assign_handler), + std::make_tuple(ZEND_ASSIGN_SUB, sub_assign_handler), + std::make_tuple(ZEND_ASSIGN_MUL, mul_assign_handler), + std::make_tuple(ZEND_ASSIGN_DIV, div_assign_handler), + std::make_tuple(ZEND_ASSIGN_MOD, mod_assign_handler), std::make_tuple(ZEND_ASSIGN_POW, pow_assign_handler), +#endif std::make_tuple(ZEND_BW_NOT, bw_not_handler), std::make_tuple(ZEND_IS_EQUAL, is_equal_handler), std::make_tuple(ZEND_IS_NOT_EQUAL, is_not_equal_handler),