compatible to PHP 7.4 && refactor

This commit is contained in:
CismonX 2019-12-09 01:32:19 +08:00
parent 3b01039722
commit 5b2fbead25
4 changed files with 54 additions and 27 deletions

View File

@ -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 <size_t... S>
using seq = std::integer_sequence<size_t, S...>;
template <size_t N>
using seq_impl = std::make_integer_sequence<size_t, N>;
constexpr auto get_len(const char *str)
{
auto i = 0;
@ -164,18 +169,17 @@ namespace php_arma
template <const char*, typename, const char*, typename>
struct concat_impl;
template <const char *Str1, size_t... Len1, const char *Str2, size_t... Len2>
struct concat_impl<Str1, seq<Len1...>, Str2, seq<Len2...>>
struct concat_impl<Str1, std::index_sequence<Len1...>, Str2, std::index_sequence<Len2...>>
{
static constexpr const char value[]
{
static constexpr const char value[] {
Str1[Len1]..., Str2[Len2]..., 0
};
};
template <const char *Str1, const char *Str2>
constexpr auto concat
{
concat_impl<Str1, seq_impl<get_len(Str1)>, Str2, seq_impl<get_len(Str2)>>::value
constexpr auto concat {
concat_impl<Str1, std::make_index_sequence<get_len(Str1)>,
Str2, std::make_index_sequence<get_len(Str2)>>::value
};
constexpr const char namespace_prefix[] = "Arma\\";
@ -183,14 +187,12 @@ namespace php_arma
constexpr const char empty[] = "";
template <const char *Str>
constexpr auto with_arma_prefix
{
constexpr auto with_arma_prefix {
concat<namespace_prefix, Str>
};
template <const char *Str>
constexpr auto with_internal_prefix
{
constexpr auto with_internal_prefix {
concat<internal_prefix, Str>
};
}

View File

@ -312,28 +312,29 @@ namespace php_arma
}
template <typename T>
void complex<T>::write_property(zval *obj, zval *member, zval *value, void**)
zobj_write_prop_ret_t complex<T>::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<T>(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 <typename T>

View File

@ -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*);

View File

@ -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 <typename... Ts>
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),