Update opcode handlers.

This commit is contained in:
CismonX 2019-06-07 14:32:15 +08:00
parent fe867b587f
commit 3ebdc418e4
3 changed files with 16 additions and 48 deletions

View File

@ -21,18 +21,6 @@
PHP_ARMA_MAPVAL_OPERATOR_EX(cx_double, func) \
PHP_ARMA_OPERATOR_END()
#define PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(type, func) \
PHP_ARMA_OPERATOR_ASSIGN_EX(mapval_dense <type>, func) \
PHP_ARMA_OPERATOR_ASSIGN_EX(mapval_spmat <type>, func) \
PHP_ARMA_OPERATOR_ASSIGN_EX(mapval_sp_subview<type>, func)
#define PHP_ARMA_MAPVAL_OPERATOR_ASSIGN(func) \
PHP_ARMA_OPERATOR_BEGIN(scalar_ce) \
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(double, func) \
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(zend_long, func) \
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN_EX(cx_double, func) \
PHP_ARMA_OPERATOR_END()
// Forward declarations.
namespace arma
{
@ -126,29 +114,24 @@ namespace php_arma
struct mapval<T, IsSparse, IsSubview>::operators
{
zend_always_inline
static bool assign(zval *zv1, zval *zv2, zval *retval)
{
if (!zval_is_scalar<T>(zv2)) {
return false;
}
set_val(Z_OBJ_P(retval), zval_get_scalar<T>(zv2));
return true;
}
zend_always_inline
static bool mul(zval *zv1, zval *zv2, zval *retval)
{
static bool mul(
#if PHP_VERSION_ID < 70300
if (Z_TYPE_P(zv1) == IS_LONG && Z_LVAL_P(zv1) == 1) {
zval_set_scalar(retval, get_val(Z_OBJ_P(zv2)));
return true;
}
zval *zv1, zval *zv2,
#else
if (Z_TYPE_P(zv2) == IS_LONG && Z_LVAL_P(zv2) == 1) {
zval_set_scalar(retval, get_val(Z_OBJ_P(zv1)));
zval *zv2, zval *zv1,
#endif
zval *retval)
{
if (EXPECTED(Z_TYPE_P(zv1) == IS_LONG)) {
if (Z_LVAL_P(zv1) == 1) {
zval_set_scalar(retval, get_val(Z_OBJ_P(zv2)));
} else if (Z_LVAL_P(zv1) == -1) {
zval_set_scalar(retval, -get_val(Z_OBJ_P(zv2)));
} else {
return false;
}
return true;
}
#endif
return false;
}
};

View File

@ -84,15 +84,6 @@ namespace php_arma
return ZEND_USER_OPCODE_CONTINUE;
}
int assign_handler(zend_execute_data *execute_data)
{
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
PHP_ARMA_MAPVAL_OPERATOR_ASSIGN(assign);
return false;
});
}
int add_handler(zend_execute_data *execute_data)
{
return op_handler(execute_data, PHP_ARMA_OP_HANDLER_FUNC {
@ -205,7 +196,6 @@ namespace php_arma
void operators_init()
{
set_op_handlers(
std::tuple(ZEND_ASSIGN, assign_handler),
std::tuple(ZEND_ADD, add_handler),
std::tuple(ZEND_ASSIGN_ADD, add_assign_handler),
std::tuple(ZEND_SUB, sub_handler),

View File

@ -14,15 +14,10 @@ if (is_php_arma_loaded()) {
require_once 'includes/assert.php';
$mat = Arma\IMat::fromString('1 2; 3 4');
$mapval = $mat(1, 0);
$mapval = 5;
// Unfortunately, the Zend Engine prevents us from writing something like:
// $mat(1, 0) = 5;
// because function return values are not supposed to be used in write context.
// Function `zend_ensure_writable_variable()` does that check in compile time.
batch_assert('operator overloading of `MapVal`',
[5, +$mat->at(1, 0)]
[3, +$mat->at(1, 0)],
[-2, -$mat(0, 1)]
);
?>