mirror of
https://github.com/php/pecl-php-operator.git
synced 2026-03-25 15:42:17 +01:00
Compare commits
23 Commits
RELEASE_1_
...
php5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8d08917aad | ||
|
|
63f17c8743 | ||
|
|
214fb2cd8d | ||
|
|
7f9dbc34ea | ||
|
|
f763d3b6d4 | ||
|
|
dc4963d28f | ||
|
|
382784abce | ||
|
|
a1417fd74e | ||
|
|
73e1d2d007 | ||
|
|
45efaa097e | ||
|
|
12993438af | ||
|
|
cf21cb13c6 | ||
|
|
7ad81b5389 | ||
|
|
9d3e29ef40 | ||
|
|
3c6fe465db | ||
|
|
00288f24ee | ||
|
|
cad8f9d1da | ||
|
|
679f719c2f | ||
|
|
c2e6179363 | ||
|
|
8e9db3e04b | ||
|
|
50fb525c5a | ||
|
|
cdf8e3e370 | ||
|
|
0a80128678 |
30
.gitignore
vendored
Normal file
30
.gitignore
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
/.deps
|
||||
/.libs/
|
||||
/Makefile
|
||||
/Makefile.fragments
|
||||
/Makefile.global
|
||||
/Makefile.objects
|
||||
/acinclude.m4
|
||||
/aclocal.m4
|
||||
/autom4te.cache/
|
||||
/build/
|
||||
/config.cache
|
||||
/config.guess
|
||||
/config.h
|
||||
/config.h.in
|
||||
/config.log
|
||||
/config.nice
|
||||
/config.status
|
||||
/config.sub
|
||||
/configure
|
||||
/configure.in
|
||||
/install-sh
|
||||
/libtool
|
||||
/ltmain.sh
|
||||
/missing
|
||||
/mkinstalldirs
|
||||
/modules/
|
||||
/php_test_results_*.txt
|
||||
/run-tests.php
|
||||
/*.lo
|
||||
/*.la
|
||||
66
compare-greater-5.0.5.diff
Normal file
66
compare-greater-5.0.5.diff
Normal file
@@ -0,0 +1,66 @@
|
||||
Index: Zend/zend_compile.c
|
||||
===================================================================
|
||||
RCS file: /repository/ZendEngine2/zend_compile.c,v
|
||||
retrieving revision 1.567.2.33
|
||||
diff -u -r1.567.2.33 zend_compile.c
|
||||
--- Zend/zend_compile.c 24 Nov 2005 11:33:27 -0000 1.567.2.33
|
||||
+++ Zend/zend_compile.c 8 Feb 2006 21:05:21 -0000
|
||||
@@ -235,6 +235,20 @@
|
||||
}
|
||||
|
||||
|
||||
+void zend_do_binary_compare_op(zend_uchar op, znode *result, znode *op1, znode *op2, zend_uint extval TSRMLS_DC)
|
||||
+{
|
||||
+ zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
+
|
||||
+ opline->opcode = op;
|
||||
+ opline->result.op_type = IS_TMP_VAR;
|
||||
+ opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||
+ opline->op1 = *op1;
|
||||
+ opline->op2 = *op2;
|
||||
+ opline->extended_value = extval;
|
||||
+ *result = opline->result;
|
||||
+}
|
||||
+
|
||||
+
|
||||
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC)
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
Index: Zend/zend_compile.h
|
||||
===================================================================
|
||||
RCS file: /repository/ZendEngine2/zend_compile.h,v
|
||||
retrieving revision 1.284.2.7
|
||||
diff -u -r1.284.2.7 zend_compile.h
|
||||
--- Zend/zend_compile.h 20 Sep 2005 11:38:37 -0000 1.284.2.7
|
||||
+++ Zend/zend_compile.h 8 Feb 2006 21:05:21 -0000
|
||||
@@ -321,6 +321,8 @@
|
||||
|
||||
|
||||
/* parser-driven code generators */
|
||||
+#define ZEND_HAVE_DO_BINARY_COMPARE_OP 1
|
||||
+void zend_do_binary_compare_op(zend_uchar op, znode *result, znode *op1, znode *op2, zend_uint extval TSRMLS_DC);
|
||||
void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
|
||||
void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
Index: Zend/zend_language_parser.y
|
||||
===================================================================
|
||||
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
|
||||
retrieving revision 1.144.2.4
|
||||
diff -u -r1.144.2.4 zend_language_parser.y
|
||||
--- Zend/zend_language_parser.y 21 Sep 2005 09:58:10 -0000 1.144.2.4
|
||||
+++ Zend/zend_language_parser.y 8 Feb 2006 21:05:21 -0000
|
||||
@@ -585,10 +585,10 @@
|
||||
| expr T_IS_NOT_IDENTICAL expr { zend_do_binary_op(ZEND_IS_NOT_IDENTICAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
| expr T_IS_EQUAL expr { zend_do_binary_op(ZEND_IS_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
| expr T_IS_NOT_EQUAL expr { zend_do_binary_op(ZEND_IS_NOT_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
- | expr '<' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
- | expr T_IS_SMALLER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
- | expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); }
|
||||
- | expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 TSRMLS_CC); }
|
||||
+ | expr '<' expr { zend_do_binary_compare_op(ZEND_IS_SMALLER, &$$, &$1, &$3, 0 TSRMLS_CC); }
|
||||
+ | expr T_IS_SMALLER_OR_EQUAL expr { zend_do_binary_compare_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3, 0 TSRMLS_CC); }
|
||||
+ | expr '>' expr { zend_do_binary_compare_op(ZEND_IS_SMALLER, &$$, &$3, &$1, 1 TSRMLS_CC); }
|
||||
+ | expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_compare_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1, 1 TSRMLS_CC); }
|
||||
| expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
|
||||
66
compare-greater-5.1.2.diff
Normal file
66
compare-greater-5.1.2.diff
Normal file
@@ -0,0 +1,66 @@
|
||||
Index: Zend/zend_compile.c
|
||||
===================================================================
|
||||
RCS file: /repository/ZendEngine2/zend_compile.c,v
|
||||
retrieving revision 1.647.2.21
|
||||
diff -u -r1.647.2.21 zend_compile.c
|
||||
--- Zend/zend_compile.c 4 Jan 2006 23:53:04 -0000 1.647.2.21
|
||||
+++ Zend/zend_compile.c 8 Feb 2006 21:06:49 -0000
|
||||
@@ -267,6 +267,20 @@
|
||||
}
|
||||
|
||||
|
||||
+void zend_do_binary_compare_op(zend_uchar op, znode *result, znode *op1, znode *op2, zend_uint extval TSRMLS_DC)
|
||||
+{
|
||||
+ zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
+
|
||||
+ opline->opcode = op;
|
||||
+ opline->result.op_type = IS_TMP_VAR;
|
||||
+ opline->result.u.var = get_temporary_variable(CG(active_op_array));
|
||||
+ opline->op1 = *op1;
|
||||
+ opline->op2 = *op2;
|
||||
+ opline->extended_value = extval;
|
||||
+ *result = opline->result;
|
||||
+}
|
||||
+
|
||||
+
|
||||
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC)
|
||||
{
|
||||
zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);
|
||||
Index: Zend/zend_compile.h
|
||||
===================================================================
|
||||
RCS file: /repository/ZendEngine2/zend_compile.h,v
|
||||
retrieving revision 1.316.2.6
|
||||
diff -u -r1.316.2.6 zend_compile.h
|
||||
--- Zend/zend_compile.h 4 Jan 2006 23:53:04 -0000 1.316.2.6
|
||||
+++ Zend/zend_compile.h 8 Feb 2006 21:06:49 -0000
|
||||
@@ -336,6 +336,8 @@
|
||||
|
||||
|
||||
/* parser-driven code generators */
|
||||
+#define ZEND_HAVE_DO_BINARY_COMPARE_OP 1
|
||||
+void zend_do_binary_compare_op(zend_uchar op, znode *result, znode *op1, znode *op2, zend_uint extval TSRMLS_DC);
|
||||
void zend_do_binary_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
void zend_do_unary_op(zend_uchar op, znode *result, znode *op1 TSRMLS_DC);
|
||||
void zend_do_binary_assign_op(zend_uchar op, znode *result, znode *op1, znode *op2 TSRMLS_DC);
|
||||
Index: Zend/zend_language_parser.y
|
||||
===================================================================
|
||||
RCS file: /repository/ZendEngine2/zend_language_parser.y,v
|
||||
retrieving revision 1.160.2.3
|
||||
diff -u -r1.160.2.3 zend_language_parser.y
|
||||
--- Zend/zend_language_parser.y 4 Jan 2006 23:53:04 -0000 1.160.2.3
|
||||
+++ Zend/zend_language_parser.y 8 Feb 2006 21:06:49 -0000
|
||||
@@ -597,10 +597,10 @@
|
||||
| expr T_IS_NOT_IDENTICAL expr { zend_do_binary_op(ZEND_IS_NOT_IDENTICAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
| expr T_IS_EQUAL expr { zend_do_binary_op(ZEND_IS_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
| expr T_IS_NOT_EQUAL expr { zend_do_binary_op(ZEND_IS_NOT_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
- | expr '<' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
- | expr T_IS_SMALLER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3 TSRMLS_CC); }
|
||||
- | expr '>' expr { zend_do_binary_op(ZEND_IS_SMALLER, &$$, &$3, &$1 TSRMLS_CC); }
|
||||
- | expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1 TSRMLS_CC); }
|
||||
+ | expr '<' expr { zend_do_binary_compare_op(ZEND_IS_SMALLER, &$$, &$1, &$3, 0 TSRMLS_CC); }
|
||||
+ | expr T_IS_SMALLER_OR_EQUAL expr { zend_do_binary_compare_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$1, &$3, 0 TSRMLS_CC); }
|
||||
+ | expr '>' expr { zend_do_binary_compare_op(ZEND_IS_SMALLER, &$$, &$3, &$1, 1 TSRMLS_CC); }
|
||||
+ | expr T_IS_GREATER_OR_EQUAL expr { zend_do_binary_compare_op(ZEND_IS_SMALLER_OR_EQUAL, &$$, &$3, &$1, 1 TSRMLS_CC); }
|
||||
| expr T_INSTANCEOF class_name_reference { zend_do_instanceof(&$$, &$1, &$3, 0 TSRMLS_CC); }
|
||||
| '(' expr ')' { $$ = $2; }
|
||||
| expr '?' { zend_do_begin_qm_op(&$1, &$2 TSRMLS_CC); }
|
||||
377
operator.c
377
operator.c
@@ -2,6 +2,8 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
@@ -30,7 +32,7 @@
|
||||
#define ZEND_VM_KIND_CALL 1
|
||||
#endif
|
||||
|
||||
#if (PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION > 0) && ZEND_VM_KIND != ZEND_VM_KIND_CALL
|
||||
#if defined(ZEND_ENGINE_2_1) && ZEND_VM_KIND != ZEND_VM_KIND_CALL
|
||||
# error "Operator overload support requires CALL style Zend VM"
|
||||
#endif
|
||||
|
||||
@@ -38,7 +40,9 @@
|
||||
* Helpers *
|
||||
*********** */
|
||||
|
||||
#define PHP_OPERATOR_EX_T(offset) (*(temp_variable *)((char*)execute_data->Ts + offset))
|
||||
#ifndef EX_TMP_VAR
|
||||
# define EX_TMP_VAR(ex, ofs) ((temp_variable *)((char*)(ex)->Ts + (ofs)))
|
||||
#endif
|
||||
|
||||
static inline int php_operator_method(zval *result, zval *op1, const char *method, int method_len, zval *op2 TSRMLS_DC)
|
||||
{
|
||||
@@ -48,7 +52,7 @@ static inline int php_operator_method(zval *result, zval *op1, const char *metho
|
||||
ALLOC_INIT_ZVAL(caller);
|
||||
array_init(caller);
|
||||
|
||||
ZVAL_ADDREF(op1);
|
||||
Z_ADDREF_P(op1);
|
||||
add_index_zval(caller, 0, op1);
|
||||
add_index_stringl(caller, 1, (char*)method, method_len, 1);
|
||||
|
||||
@@ -58,26 +62,38 @@ static inline int php_operator_method(zval *result, zval *op1, const char *metho
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline zval *php_operator_zval_ptr(znode *node, zend_free_op *should_free, zend_execute_data *execute_data TSRMLS_DC)
|
||||
#ifdef ZEND_ENGINE_2_4
|
||||
typedef znode_op operator_znode_op;
|
||||
#else
|
||||
typedef znode operator_znode_op;
|
||||
#endif
|
||||
|
||||
static inline zval *php_operator_zval_ptr(zend_uchar optype, operator_znode_op *node_op, zend_free_op *should_free, zend_execute_data *execute_data, zend_bool silent TSRMLS_DC)
|
||||
{
|
||||
should_free->var = NULL;
|
||||
|
||||
switch (node->op_type) {
|
||||
switch (optype) {
|
||||
case IS_CONST:
|
||||
return &(node->u.constant);
|
||||
#ifdef ZEND_ENGINE_2_4
|
||||
return &node_op->literal->constant;
|
||||
#else
|
||||
return &(node_op->u.constant);
|
||||
#endif
|
||||
case IS_VAR:
|
||||
return PHP_OPERATOR_EX_T(node->u.var).var.ptr;
|
||||
return EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(*node_op).var)->var.ptr;
|
||||
case IS_TMP_VAR:
|
||||
return (should_free->var = &PHP_OPERATOR_EX_T(node->u.var).tmp_var);
|
||||
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION > 0
|
||||
return (should_free->var = &EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(*node_op).var)->tmp_var);
|
||||
#ifdef ZEND_ENGINE_2_1
|
||||
case IS_CV:
|
||||
{
|
||||
zval ***ret = &execute_data->CVs[node->u.var];
|
||||
zval ***ret = EX_CV_NUM(execute_data, PHP_OPERATOR_OP_U(*node_op).var);
|
||||
|
||||
if (!*ret) {
|
||||
zend_compiled_variable *cv = &EG(active_op_array)->vars[node->u.var];
|
||||
zend_compiled_variable *cv = &EG(active_op_array)->vars[PHP_OPERATOR_OP_U(*node_op).var];
|
||||
if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ret)==FAILURE) {
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
if (!silent) {
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
}
|
||||
return &EG(uninitialized_zval);
|
||||
}
|
||||
}
|
||||
@@ -90,20 +106,22 @@ static inline zval *php_operator_zval_ptr(znode *node, zend_free_op *should_free
|
||||
}
|
||||
}
|
||||
|
||||
static inline zval **php_operator_zval_ptr_ptr(znode *node, zend_execute_data *execute_data TSRMLS_DC)
|
||||
static inline zval **php_operator_zval_ptr_ptr(zend_uchar optype, operator_znode_op *node_op, zend_execute_data *execute_data, zend_bool silent TSRMLS_DC)
|
||||
{
|
||||
switch (node->op_type) {
|
||||
switch (optype) {
|
||||
case IS_VAR:
|
||||
return PHP_OPERATOR_EX_T(node->u.var).var.ptr_ptr;
|
||||
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION > 0
|
||||
return EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(*node_op).var)->var.ptr_ptr;
|
||||
#ifdef ZEND_ENGINE_2_1
|
||||
case IS_CV:
|
||||
{
|
||||
zval ***ret = &execute_data->CVs[node->u.var];
|
||||
zval ***ret = EX_CV_NUM(execute_data, PHP_OPERATOR_OP_U(*node_op).var);
|
||||
|
||||
if (!*ret) {
|
||||
zend_compiled_variable *cv = &EG(active_op_array)->vars[node->u.var];
|
||||
zend_compiled_variable *cv = &EG(active_op_array)->vars[PHP_OPERATOR_OP_U(*node_op).var];
|
||||
if (zend_hash_quick_find(EG(active_symbol_table), cv->name, cv->name_len+1, cv->hash_value, (void **)ret)==FAILURE) {
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
if (!silent) {
|
||||
zend_error(E_NOTICE, "Undefined variable: %s", cv->name);
|
||||
}
|
||||
return &EG(uninitialized_zval_ptr);
|
||||
}
|
||||
}
|
||||
@@ -122,8 +140,8 @@ static inline zval *php_operator_get_result_ptr(zend_op *opline, zend_execute_da
|
||||
{
|
||||
zval *tmp;
|
||||
|
||||
if (opline->result.op_type == IS_TMP_VAR) {
|
||||
return &PHP_OPERATOR_EX_T(opline->result.u.var).tmp_var;
|
||||
if (PHP_OPERATOR_OP_TYPE(opline->result) == IS_TMP_VAR) {
|
||||
return &EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(opline->result).var)->tmp_var;
|
||||
}
|
||||
|
||||
ALLOC_INIT_ZVAL(tmp);
|
||||
@@ -132,31 +150,32 @@ static inline zval *php_operator_get_result_ptr(zend_op *opline, zend_execute_da
|
||||
|
||||
static inline void php_operator_set_result_ptr(zval *result, zend_op *opline, zend_execute_data *execute_data)
|
||||
{
|
||||
switch (opline->result.op_type) {
|
||||
switch (PHP_OPERATOR_OP_TYPE(opline->result)) {
|
||||
case IS_TMP_VAR:
|
||||
/* Nothing to do */
|
||||
return;
|
||||
case IS_VAR:
|
||||
PHP_OPERATOR_EX_T(opline->result.u.var).var.ptr = result;
|
||||
PHP_OPERATOR_EX_T(opline->result.u.var).var.ptr_ptr = &PHP_OPERATOR_EX_T(opline->result.u.var).var.ptr;
|
||||
EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(opline->result).var)->var.ptr = result;
|
||||
EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(opline->result).var)->var.ptr_ptr =
|
||||
&EX_TMP_VAR(execute_data, PHP_OPERATOR_OP_U(opline->result).var)->var.ptr;
|
||||
return;
|
||||
default:
|
||||
zval_ptr_dtor(&result);
|
||||
}
|
||||
}
|
||||
|
||||
#if PHP_MAJOR_VERSION > 5 || PHP_MINOR_VERSION > 0
|
||||
#ifdef ZEND_ENGINE_2_1
|
||||
static inline int _php_operator_decode(zend_op *opline)
|
||||
{
|
||||
int ret = opline->opcode * 25;
|
||||
switch (opline->op1.op_type) {
|
||||
switch (PHP_OPERATOR_OP_TYPE(opline->op1)) {
|
||||
case IS_CONST: break;
|
||||
case IS_TMP_VAR: ret += 5; break;
|
||||
case IS_VAR: ret += 10; break;
|
||||
case IS_UNUSED: ret += 15; break;
|
||||
case IS_CV: ret += 20; break;
|
||||
}
|
||||
switch (opline->op2.op_type) {
|
||||
switch (PHP_OPERATOR_OP_TYPE(opline->op2)) {
|
||||
case IS_CONST: break;
|
||||
case IS_TMP_VAR: ret += 1; break;
|
||||
case IS_VAR: ret += 2; break;
|
||||
@@ -165,35 +184,72 @@ static inline int _php_operator_decode(zend_op *opline)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#define PHP_OPERATOR_OPHANDLER_COUNT ((25 * 151) + 1)
|
||||
|
||||
#if defined(ZEND_ENGINE_2_5)
|
||||
# define PHP_OPERATOR_OPCODE_COUNT 163
|
||||
#elif defined(ZEND_ENGINE_2_4)
|
||||
# define PHP_OPERATOR_OPCODE_COUNT 158
|
||||
#elif defined(ZEND_ENGINE_2_3)
|
||||
# define PHP_OPERATOR_OPCODE_COUNT 153
|
||||
#else /* PHP 5.1 and 5.2 */
|
||||
# define PHP_OPERATOR_OPCODE_COUNT 150
|
||||
#endif
|
||||
|
||||
#define PHP_OPERATOR_OPHANDLER_COUNT ((25 * (PHP_OPERATOR_OPCODE_COUNT + 1)) + 1)
|
||||
#define PHP_OPERATOR_REPLACE_OPCODE(opname) { int i; for(i = 5; i < 25; i++) if (php_operator_opcode_handlers[(opname*25) + i]) php_operator_opcode_handlers[(opname*25) + i] = php_operator_op_##opname; }
|
||||
#define PHP_OPERATOR_REPLACE_ALL_OPCODE(opname) { int i; for(i = 0; i < 25; i++) if (php_operator_opcode_handlers[(opname*25) + i]) php_operator_opcode_handlers[(opname*25) + i] = php_operator_op_##opname; }
|
||||
#define PHP_OPERATOR_DECODE(opline) _php_operator_decode(opline)
|
||||
#define PHP_OPERATOR_GET_OPLINE zend_op *opline = (execute_data->opline);
|
||||
#else
|
||||
#define PHP_OPERATOR_OPHANDLER_COUNT 512
|
||||
#define PHP_OPERATOR_OPCODE_COUNT 512
|
||||
#define PHP_OPERATOR_OPHANDLER_COUNT PHP_OPERATOR_OPCODE_COUNT
|
||||
#define PHP_OPERATOR_REPLACE_OPCODE(opname) zend_opcode_handlers[opname] = php_operator_op_##opname
|
||||
#define PHP_OPERATOR_DECODE(opline) (opline->code)
|
||||
#define PHP_OPERATOR_REPLACE_ALL_OPCODE(opname) zend_opcode_handlers[opname] = php_operator_op_##opname
|
||||
#define PHP_OPERATOR_DECODE(opline) (opline->opcode)
|
||||
#define PHP_OPERATOR_GET_OPLINE
|
||||
#endif
|
||||
|
||||
static opcode_handler_t *php_operator_original_opcode_handlers;
|
||||
static opcode_handler_t php_operator_opcode_handlers[PHP_OPERATOR_OPHANDLER_COUNT];
|
||||
|
||||
#ifndef ZEND_FASTCALL
|
||||
#define ZEND_FASTCALL
|
||||
#endif
|
||||
|
||||
#ifndef Z_ADDREF_P
|
||||
# define Z_ADDREF_P(pzv) ((pzv)->refcount++)
|
||||
#endif
|
||||
|
||||
/* *******************
|
||||
* Op Replacements *
|
||||
******************* */
|
||||
|
||||
#define PHP_OPERATOR_BINARY_OP(opname,methodname) static int php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_binary_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
#define PHP_OPERATOR_BINARY_OP(opname,methodname) static int ZEND_FASTCALL php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_binary_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static inline int _php_operator_binary_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zend_free_op free_op1, free_op2;
|
||||
zval *result;
|
||||
zval *op1 = php_operator_zval_ptr(&(opline->op1), &free_op1, execute_data TSRMLS_CC);
|
||||
zval *op2 = php_operator_zval_ptr(&(opline->op2), &free_op2, execute_data TSRMLS_CC);
|
||||
zval *op1 = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op1), &(opline->op1), &free_op1, execute_data, (opline->opcode == ZEND_ASSIGN) TSRMLS_CC);
|
||||
zval *op2 = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op2), &(opline->op2), &free_op2, execute_data, 0 TSRMLS_CC);
|
||||
|
||||
if (opline->op1.op_type == IS_CONST ||
|
||||
op1->type != IS_OBJECT ||
|
||||
#ifdef ZEND_HAVE_DO_BINARY_COMPARE_OP
|
||||
if (opline->extended_value &&
|
||||
opline->opcode == ZEND_IS_SMALLER) {
|
||||
zval *swap = op1; op1 = op2; op2 = swap;
|
||||
|
||||
methodname = "__is_greater";
|
||||
methodname_len = sizeof("__is_greater") - 1;
|
||||
} else if (opline->extended_value &&
|
||||
opline->opcode == ZEND_IS_SMALLER_OR_EQUAL) {
|
||||
zval *swap = op1; op1 = op2; op2 = swap;
|
||||
|
||||
methodname = "__is_greater_or_equal";
|
||||
methodname_len = sizeof("__is_greater_or_equal") - 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!op1 || op1->type != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_P(op1)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
@@ -202,7 +258,7 @@ static inline int _php_operator_binary_op(ZEND_OPCODE_HANDLER_ARGS, const char *
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, op1, methodname, methodname_len, op2 TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (opline->result.op_type != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
if (PHP_OPERATOR_OP_TYPE(opline->result) != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
@@ -213,15 +269,15 @@ static inline int _php_operator_binary_op(ZEND_OPCODE_HANDLER_ARGS, const char *
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PHP_OPERATOR_UNARY_OP(opname,methodname) static int php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
#define PHP_OPERATOR_UNARY_OP(opname,methodname) static int ZEND_FASTCALL php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static inline int _php_operator_unary_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zend_free_op free_op1;
|
||||
zval *result;
|
||||
zval *op1 = php_operator_zval_ptr(&(opline->op1), &free_op1, execute_data TSRMLS_CC);
|
||||
zval *op1 = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op1), &(opline->op1), &free_op1, execute_data, 0 TSRMLS_CC);
|
||||
|
||||
if (opline->op1.op_type == IS_CONST ||
|
||||
if (!op1 ||
|
||||
op1->type != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_P(op1)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
/* Rely on primary handler */
|
||||
@@ -231,7 +287,7 @@ static inline int _php_operator_unary_op(ZEND_OPCODE_HANDLER_ARGS, const char *m
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, op1, methodname, methodname_len, NULL TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (opline->result.op_type != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
if (PHP_OPERATOR_OP_TYPE(opline->result) != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
@@ -241,12 +297,93 @@ static inline int _php_operator_unary_op(ZEND_OPCODE_HANDLER_ARGS, const char *m
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PHP_OPERATOR_UNARY_ASSIGN_OP(opname,methodname) static int php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
#ifdef ZEND_ENGINE_2_5
|
||||
# define BP_VAR_RW_55_CC , BP_VAR_RW
|
||||
#else
|
||||
# define BP_VAR_RW_55_CC
|
||||
#endif
|
||||
|
||||
#define PHP_OPERATOR_BINARY_ASSIGN_OP(opname,methodname) static int ZEND_FASTCALL php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_binary_assign_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static int _php_operator_binary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zend_free_op free_value, free_prop, free_obj;
|
||||
zval *var = NULL, *value, *result;
|
||||
zend_bool increment_opline = 0;
|
||||
|
||||
free_prop.var = free_obj.var = NULL;
|
||||
switch (opline->extended_value) {
|
||||
case ZEND_ASSIGN_OBJ:
|
||||
case ZEND_ASSIGN_DIM:
|
||||
{
|
||||
zend_op *opdata = opline + 1;
|
||||
zval *object = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op1), &(opline->op1), &free_obj, execute_data, 0 TSRMLS_CC);
|
||||
zval *prop = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op2), &(opline->op2), &free_prop, execute_data, (opline->opcode == ZEND_ASSIGN) TSRMLS_CC);
|
||||
|
||||
if (!object || Z_TYPE_P(object) != IS_OBJECT || !prop) {
|
||||
/* Let orignal handler throw error */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
increment_opline = 1;
|
||||
value = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opdata->op1), &(opdata->op1), &free_value, execute_data, 0 TSRMLS_CC);
|
||||
if (!value) {
|
||||
/* Shouldn't happen */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
/* Plan A */
|
||||
if (opline->extended_value == ZEND_ASSIGN_OBJ &&
|
||||
Z_OBJ_HT_P(object)->get_property_ptr_ptr) {
|
||||
zval **varpp = Z_OBJ_HT_P(object)->get_property_ptr_ptr(object, prop BP_VAR_RW_55_CC PHP_OPERATOR_LITERAL_NULL_CC TSRMLS_CC);
|
||||
if (varpp) {
|
||||
var = *varpp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Plan B */
|
||||
if (opline->extended_value == ZEND_ASSIGN_OBJ &&
|
||||
Z_OBJ_HT_P(object)->read_property) {
|
||||
var = Z_OBJ_HT_P(object)->read_property(object, prop, BP_VAR_RW PHP_OPERATOR_LITERAL_NULL_CC TSRMLS_CC);
|
||||
} else if (opline->extended_value == ZEND_ASSIGN_DIM &&
|
||||
Z_OBJ_HT_P(object)->read_dimension) {
|
||||
var = Z_OBJ_HT_P(object)->read_dimension(object, prop, BP_VAR_RW TSRMLS_CC);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
default:
|
||||
var = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op1), &(opline->op1), &free_obj, execute_data, (opline->opcode == ZEND_ASSIGN) TSRMLS_CC);
|
||||
value = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op2), &(opline->op2), &free_value, execute_data, 0 TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!var || Z_TYPE_P(var) != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_P(var)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, var, methodname, methodname_len, value TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (PHP_OPERATOR_OP_TYPE(opline->result) != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
if (free_prop.var) zval_dtor(free_prop.var);
|
||||
if (free_value.var) zval_dtor(free_value.var);
|
||||
php_operator_set_result_ptr(result, opline, execute_data);
|
||||
execute_data->opline += increment_opline ? 2 : 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PHP_OPERATOR_UNARY_ASSIGN_OP(opname,methodname) static int ZEND_FASTCALL php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static inline int _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zval *result;
|
||||
zval **op1 = php_operator_zval_ptr_ptr(&(opline->op1), execute_data TSRMLS_CC);
|
||||
zval **op1 = php_operator_zval_ptr_ptr(PHP_OPERATOR_OP_TYPE(opline->op1), &(opline->op1), execute_data, 0 TSRMLS_CC);
|
||||
|
||||
if (!op1 || Z_TYPE_PP(op1) != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_PP(op1)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
@@ -257,7 +394,7 @@ static inline int _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, *op1, methodname, methodname_len, NULL TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (opline->result.op_type != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
if (PHP_OPERATOR_OP_TYPE(opline->result) != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
@@ -266,26 +403,95 @@ static inline int _php_operator_unary_assign_op(ZEND_OPCODE_HANDLER_ARGS, const
|
||||
return 0;
|
||||
}
|
||||
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_ADD, "__add")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SUB, "__sub")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MUL, "__mul")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_DIV, "__div")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MOD, "__mod")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SL, "__sl")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SR, "__sr")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_CONCAT, "__concat")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_OR, "__bw_or")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_AND, "__bw_and")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_XOR, "__bw_xor")
|
||||
#define PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(opname,methodname) static int ZEND_FASTCALL php_operator_op_##opname (ZEND_OPCODE_HANDLER_ARGS) { return _php_operator_unary_assign_obj_op(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU, methodname, sizeof(methodname) - 1); }
|
||||
static inline int _php_operator_unary_assign_obj_op(ZEND_OPCODE_HANDLER_ARGS, const char *methodname, int methodname_len)
|
||||
{
|
||||
PHP_OPERATOR_GET_OPLINE
|
||||
zend_free_op free_obj, free_prop;
|
||||
zval *result;
|
||||
zval *obj = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op1), &(opline->op1), &free_obj, execute_data, 0 TSRMLS_CC);
|
||||
zval *prop = php_operator_zval_ptr(PHP_OPERATOR_OP_TYPE(opline->op2), &(opline->op2), &free_prop, execute_data, 0 TSRMLS_CC);
|
||||
zval *var = NULL;
|
||||
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BW_NOT, "__bw_not")
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BOOL, "__bool")
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BOOL_NOT, "__bool_not")
|
||||
if (!obj || Z_TYPE_P(obj) != IS_OBJECT || !prop) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_INC, "__pre_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_DEC, "__pre_dec")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_INC, "__post_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_DEC, "__post_dec")
|
||||
if (Z_OBJ_HT_P(obj)->get_property_ptr_ptr) {
|
||||
zval **varpp = Z_OBJ_HT_P(obj)->get_property_ptr_ptr(obj, prop BP_VAR_RW_55_CC PHP_OPERATOR_LITERAL_NULL_CC TSRMLS_CC);
|
||||
if (varpp) {
|
||||
var = *varpp;
|
||||
}
|
||||
}
|
||||
if (!var && Z_OBJ_HT_P(obj)->read_property) {
|
||||
var = Z_OBJ_HT_P(obj)->read_property(obj, prop, BP_VAR_RW PHP_OPERATOR_LITERAL_NULL_CC TSRMLS_CC);
|
||||
}
|
||||
|
||||
if (!var || Z_TYPE_P(var) != IS_OBJECT ||
|
||||
!zend_hash_exists(&Z_OBJCE_P(var)->function_table, (char*)methodname, methodname_len + 1)) {
|
||||
/* Rely on primary handler */
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
result = php_operator_get_result_ptr(opline, execute_data);
|
||||
if (php_operator_method(result, var, methodname, methodname_len, NULL TSRMLS_CC) == FAILURE) {
|
||||
/* Fallback on original handler */
|
||||
if (PHP_OPERATOR_OP_TYPE(opline->result) != IS_TMP_VAR) zval_ptr_dtor(&result);
|
||||
return php_operator_original_opcode_handlers[PHP_OPERATOR_DECODE(opline)](ZEND_OPCODE_HANDLER_ARGS_PASSTHRU);
|
||||
}
|
||||
|
||||
if (free_obj.var) { zval_dtor(free_obj.var); }
|
||||
if (free_prop.var) { zval_dtor(free_prop.var); }
|
||||
php_operator_set_result_ptr(result, opline, execute_data);
|
||||
execute_data->opline++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_ADD, "__add")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SUB, "__sub")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MUL, "__mul")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_DIV, "__div")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_MOD, "__mod")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SL, "__sl")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_SR, "__sr")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_CONCAT, "__concat")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_OR, "__bw_or")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_AND, "__bw_and")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_BW_XOR, "__bw_xor")
|
||||
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_IS_IDENTICAL, "__is_identical")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_IS_NOT_IDENTICAL, "__is_not_identical")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_IS_EQUAL, "__is_equal")
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_IS_NOT_EQUAL, "__is_not_equal")
|
||||
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_IS_SMALLER, "__is_smaller") /* includes __is_greater when patch applied */
|
||||
PHP_OPERATOR_BINARY_OP(ZEND_IS_SMALLER_OR_EQUAL, "__is_smaller_or_equal") /* includes __is_greater_or_equal ... */
|
||||
|
||||
PHP_OPERATOR_UNARY_OP(ZEND_BW_NOT, "__bw_not")
|
||||
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN, "__assign")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_ADD, "__assign_add")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_SUB, "__assign_sub")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_MUL, "__assign_mul")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_DIV, "__assign_div")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_MOD, "__assign_mod")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_SL, "__assign_sl")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_SR, "__assign_sr")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_CONCAT, "__assign_concat")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_BW_OR, "__assign_bw_or")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_BW_AND, "__assign_bw_and")
|
||||
PHP_OPERATOR_BINARY_ASSIGN_OP(ZEND_ASSIGN_BW_XOR, "__assign_bw_xor")
|
||||
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_INC, "__pre_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_PRE_DEC, "__pre_dec")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_INC, "__post_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OP(ZEND_POST_DEC, "__post_dec")
|
||||
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_PRE_INC_OBJ, "__pre_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_PRE_DEC_OBJ, "__pre_dec")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_POST_INC_OBJ, "__post_inc")
|
||||
PHP_OPERATOR_UNARY_ASSIGN_OBJ_OP(ZEND_POST_DEC_OBJ, "__post_dec")
|
||||
|
||||
/* ***********************
|
||||
* Module Housekeeping *
|
||||
@@ -315,10 +521,39 @@ PHP_MINIT_FUNCTION(operator)
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BW_AND);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BW_XOR);
|
||||
|
||||
/* Comparators (Binaries in disguise) */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_IS_IDENTICAL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_IS_NOT_IDENTICAL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_IS_EQUAL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_IS_NOT_EQUAL);
|
||||
|
||||
#ifdef ZEND_HAVE_DO_BINARY_COMPARE_OP
|
||||
/* __is_greater and __is_greater_or_equal support requires patching parser: compare-greater-VERSION.diff */
|
||||
REGISTER_LONG_CONSTANT("OPERATOR_COMPARE_PATCH", 1, CONST_CS | CONST_PERSISTENT);
|
||||
PHP_OPERATOR_REPLACE_ALL_OPCODE(ZEND_IS_SMALLER);
|
||||
PHP_OPERATOR_REPLACE_ALL_OPCODE(ZEND_IS_SMALLER_OR_EQUAL);
|
||||
#else
|
||||
REGISTER_LONG_CONSTANT("OPERATOR_COMPARE_PATCH", 0, CONST_CS | CONST_PERSISTENT);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_IS_SMALLER);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_IS_SMALLER_OR_EQUAL);
|
||||
#endif
|
||||
|
||||
/* Unaries */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BW_NOT);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BOOL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_BOOL_NOT);
|
||||
|
||||
/* Binary Assign */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_ADD);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_SUB);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_MUL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_DIV);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_MOD);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_SL);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_SR);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_CONCAT);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_BW_OR);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_BW_AND);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_ASSIGN_BW_XOR);
|
||||
|
||||
/* Unary Assign */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_INC);
|
||||
@@ -326,6 +561,12 @@ PHP_MINIT_FUNCTION(operator)
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_INC);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_DEC);
|
||||
|
||||
/* Unary Assign Obj */
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_INC_OBJ);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_PRE_DEC_OBJ);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_INC_OBJ);
|
||||
PHP_OPERATOR_REPLACE_OPCODE(ZEND_POST_DEC_OBJ);
|
||||
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -344,7 +585,13 @@ PHP_MSHUTDOWN_FUNCTION(operator)
|
||||
PHP_MINFO_FUNCTION(operator)
|
||||
{
|
||||
php_info_print_table_start();
|
||||
php_info_print_table_header(2, "operator overloading support", "+ - * / % << >> . | & ^ ~ ! ++ --");
|
||||
php_info_print_table_header(2, "operator overloading support", "+ - * / % << >> . | & ^ ~ ! ++ -- "
|
||||
"+= -= *= /= %= <<= >>= .= |= &= ^= ~= === !== == != < <= "
|
||||
#ifdef ZEND_HAVE_DO_BINARY_COMPARE_OP
|
||||
"> >= "
|
||||
#endif
|
||||
);
|
||||
php_info_print_table_row(2, "version", PHP_OPERATOR_VERSION);
|
||||
php_info_print_table_end();
|
||||
}
|
||||
|
||||
@@ -360,7 +607,7 @@ zend_module_entry operator_module_entry = {
|
||||
NULL, /* RSHUTDOWN */
|
||||
PHP_MINFO(operator),
|
||||
#if ZEND_MODULE_API_NO >= 20010901
|
||||
PHP_OPERATOR_EXTVER,
|
||||
PHP_OPERATOR_VERSION,
|
||||
#endif
|
||||
STANDARD_MODULE_PROPERTIES
|
||||
};
|
||||
|
||||
138
package.xml
138
package.xml
@@ -1,40 +1,106 @@
|
||||
<package version="1.0">
|
||||
<name>operator</name>
|
||||
<summary>Operator overloading for Objects</summary>
|
||||
<description>
|
||||
Operator overloading for +, -, *, /, %, <<, >>, ., |, &, ^, ~, and ! operators.
|
||||
</description>
|
||||
<license>PHP</license>
|
||||
<maintainers>
|
||||
<maintainer>
|
||||
<user>pollita</user>
|
||||
<name>Sara Golemon</name>
|
||||
<email>pollita@php.net</email>
|
||||
<role>lead</role>
|
||||
</maintainer>
|
||||
</maintainers>
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
|
||||
http://pear.php.net/dtd/tasks-1.0.xsd
|
||||
http://pear.php.net/dtd/package-2.0
|
||||
http://pear.php.net/dtd/package-2.0.xsd">
|
||||
<name>operator</name>
|
||||
<channel>pecl.php.net</channel>
|
||||
<summary>Operator overloading for Objects</summary>
|
||||
<description>Operator overloading for: +, -, *, /, %, <<, >>, ., |, &, ^, ~, !, ++, --,
|
||||
+=, -=, *=, /=, %=, <<=, >>=, .=, |=, &=, ^=, ~=,
|
||||
==, !=, ===, !==, <, and <= operators.
|
||||
Conditional support for > and >= available with application of a patch.
|
||||
|
||||
</description>
|
||||
<lead>
|
||||
<name>Sara Golemon</name>
|
||||
<user>pollita</user>
|
||||
<email>pollita@php.net</email>
|
||||
<active>yes</active>
|
||||
</lead>
|
||||
<date>2009-11-05</date>
|
||||
<time>17:54:16</time>
|
||||
<version>
|
||||
<release>0.3</release>
|
||||
<api>0.3</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<license uri="http://www.php.net/license">PHP</license>
|
||||
<notes>
|
||||
* Added support for comparator ops
|
||||
|
||||
Note: ZE treats > style comparisons as backwards < comparisons, so what looks like a left-associative greater than becomes a right-associative less-than.
|
||||
Because of this, overloading the > and >= operators for left-association requires application of a parser patch.
|
||||
</notes>
|
||||
<contents>
|
||||
<dir name="/">
|
||||
<dir name="tests">
|
||||
<file name="binary.phpt" role="test" />
|
||||
<file name="binary_assign.phpt" role="test" />
|
||||
<file name="binary_assign_objdim.phpt" role="test" />
|
||||
<file name="compare.phpt" role="test" />
|
||||
<file name="compare2.phpt" role="test" />
|
||||
<file name="incdec.phpt" role="test" />
|
||||
<file name="unary.phpt" role="test" />
|
||||
</dir> <!-- //tests -->
|
||||
<file name="compare-greater-5.0.5.diff" role="src" />
|
||||
<file name="compare-greater-5.1.2.diff" role="src" />
|
||||
<file name="config.m4" role="src" />
|
||||
<file name="config.w32" role="src" />
|
||||
<file name="CREDITS" role="doc" />
|
||||
<file name="EXPERIMENTAL" role="doc" />
|
||||
<file name="operator.c" role="src" />
|
||||
<file name="php_operator.h" role="src" />
|
||||
</dir> <!-- / -->
|
||||
</contents>
|
||||
<dependencies>
|
||||
<required>
|
||||
<php>
|
||||
<min>4.0.0</min>
|
||||
</php>
|
||||
<pearinstaller>
|
||||
<min>1.4.0b1</min>
|
||||
</pearinstaller>
|
||||
</required>
|
||||
</dependencies>
|
||||
<providesextension>operator</providesextension>
|
||||
<extsrcrelease />
|
||||
<changelog>
|
||||
<release>
|
||||
<version>0.1</version>
|
||||
<state>beta</state>
|
||||
<date>2006-01-12</date>
|
||||
<notes>Initial Release</notes>
|
||||
<version>
|
||||
<release>0.2</release>
|
||||
<api>0.2</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2006-01-25</date>
|
||||
<license uri="http://www.php.net/license">PHP</license>
|
||||
<notes>
|
||||
* Added support for pre/post inc/dec operators
|
||||
* Added support for assignment operators
|
||||
* Refactored opline->result handling
|
||||
* Refactored opcode handlers
|
||||
</notes>
|
||||
</release>
|
||||
|
||||
<filelist>
|
||||
<file role="doc" name="CREDITS"/>
|
||||
<file role="doc" name="EXPERIMENTAL"/>
|
||||
<file role="src" name="config.m4"/>
|
||||
<file role="src" name="config.w32"/>
|
||||
<file role="src" name="operator.c"/>
|
||||
<file role="src" name="php_operator.h"/>
|
||||
<dir role="test" name="tests">
|
||||
<file role="test" name="unary.phpt"/>
|
||||
<file role="test" name="binary.phpt"/>
|
||||
</dir>
|
||||
</filelist>
|
||||
|
||||
<release>
|
||||
<version>
|
||||
<release>0.1</release>
|
||||
<api>0.1</api>
|
||||
</version>
|
||||
<stability>
|
||||
<release>beta</release>
|
||||
<api>beta</api>
|
||||
</stability>
|
||||
<date>2006-01-12</date>
|
||||
<license uri="http://www.php.net/license">PHP</license>
|
||||
<notes>
|
||||
Initial Release
|
||||
</notes>
|
||||
</release>
|
||||
</changelog>
|
||||
</package>
|
||||
<!--
|
||||
vim: et ts=1 sw=1
|
||||
-->
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
+----------------------------------------------------------------------+
|
||||
| PHP Version 5 |
|
||||
+----------------------------------------------------------------------+
|
||||
| Copyright (c) 1997-2006 The PHP Group |
|
||||
+----------------------------------------------------------------------+
|
||||
| This source file is subject to version 3.0 of the PHP license, |
|
||||
| that is bundled with this package in the file LICENSE, and is |
|
||||
| available through the world-wide-web at the following url: |
|
||||
@@ -20,14 +22,47 @@
|
||||
#define PHP_OPERATOR_H
|
||||
|
||||
#define PHP_OPERATOR_EXTNAME "operator"
|
||||
#define PHP_OPERATOR_EXTVER "0.1"
|
||||
#define PHP_OPERATOR_VERSION "0.4.0-dev"
|
||||
|
||||
#if PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION == 0
|
||||
#if ZEND_MODULE_API_NO > 20121211
|
||||
#define ZEND_ENGINE_2_5
|
||||
#endif
|
||||
#if ZEND_MODULE_API_NO > 20100524
|
||||
#define ZEND_ENGINE_2_4
|
||||
#endif
|
||||
#if ZEND_MODULE_API_NO > 20090625
|
||||
#define ZEND_ENGINE_2_3
|
||||
#endif
|
||||
#if ZEND_MODULE_API_NO > 20050922
|
||||
#define ZEND_ENGINE_2_2
|
||||
#endif
|
||||
#if ZEND_MODULE_API_NO > 20050921
|
||||
#define ZEND_ENGINE_2_1
|
||||
#endif
|
||||
|
||||
#ifdef ZEND_ENGINE_2_4
|
||||
# define PHP_OPERATOR_OP_TYPE(zop) (zop##_type)
|
||||
# define PHP_OPERATOR_OP_U(zop) (zop)
|
||||
# define PHP_OPERATOR_LITERAL_DC , const struct _zend_literal *key
|
||||
# define PHP_OPERATOR_LITERAL_CC , key
|
||||
# define PHP_OPERATOR_LITERAL_NULL_CC , NULL
|
||||
#else
|
||||
# define PHP_OPERATOR_OP_TYPE(zop) ((zop).op_type)
|
||||
# define PHP_OPERATOR_OP_U(zop) ((zop).u)
|
||||
# define PHP_OPERATOR_LITERAL_DC
|
||||
# define PHP_OPERATOR_LITERAL_CC
|
||||
# define PHP_OPERATOR_LITERAL_NULL_CC
|
||||
#endif
|
||||
|
||||
#if defined(ZEND_ENGINE_2) && !defined(ZEND_ENGINE_2_1)
|
||||
typedef struct {
|
||||
zval *var;
|
||||
} zend_free_op;
|
||||
#endif
|
||||
|
||||
#ifndef EX_CV_NUM
|
||||
# define EX_CV_NUM(ex, n) (&((ex)->CVs[(n)]))
|
||||
#endif
|
||||
|
||||
extern zend_module_entry operator_module_entry;
|
||||
#define phpext_operator_ptr &operator_module_entry
|
||||
|
||||
103
tests/binary_assign.phpt
Normal file
103
tests/binary_assign.phpt
Normal file
@@ -0,0 +1,103 @@
|
||||
--TEST--
|
||||
Basic binary assign ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __assign($val) {
|
||||
return $this->value = $val;
|
||||
}
|
||||
|
||||
function __assign_add($val) {
|
||||
return $this->value += $val;
|
||||
}
|
||||
|
||||
function __assign_sub($val) {
|
||||
return $this->value -= $val;
|
||||
}
|
||||
|
||||
function __assign_mul($val) {
|
||||
return $this->value *= $val;
|
||||
}
|
||||
|
||||
function __assign_div($val) {
|
||||
return $this->value /= $val;
|
||||
}
|
||||
|
||||
function __assign_mod($val) {
|
||||
return $this->value %= $val;
|
||||
}
|
||||
|
||||
function __assign_sl($val) {
|
||||
return $this->value <<= $val;
|
||||
}
|
||||
|
||||
function __assign_sr($val) {
|
||||
return $this->value >>= $val;
|
||||
}
|
||||
|
||||
function __assign_concat($val) {
|
||||
return $this->value .= $val;
|
||||
}
|
||||
|
||||
function __assign_bw_or($val) {
|
||||
return $this->value |= $val;
|
||||
}
|
||||
|
||||
function __assign_bw_and($val) {
|
||||
return $this->value &= $val;
|
||||
}
|
||||
|
||||
function __assign_bw_xor($val) {
|
||||
return $this->value ^= $val;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
$a = new foo(1);
|
||||
var_dump($a = 2);
|
||||
var_dump($a += 2);
|
||||
var_dump(is_object($a));
|
||||
|
||||
$c = new foo(4);
|
||||
|
||||
var_dump($c += 3);
|
||||
var_dump($c -= 3);
|
||||
var_dump($c *= 3);
|
||||
var_dump($c /= 2);
|
||||
var_dump($c %= 3);
|
||||
|
||||
$d = new foo(14);
|
||||
var_dump($d <<= 2);
|
||||
var_dump($d >>= 2);
|
||||
|
||||
$e = new foo('PHP');
|
||||
var_dump($e .= ' with');
|
||||
var_dump($e .= ' overloading');
|
||||
|
||||
$f = new foo(0x5A);
|
||||
var_dump($f |= 0xAA);
|
||||
var_dump($f &= 0xAA);
|
||||
var_dump($f ^= 0xAA);
|
||||
--EXPECT--
|
||||
int(2)
|
||||
int(4)
|
||||
bool(true)
|
||||
int(7)
|
||||
int(4)
|
||||
int(12)
|
||||
int(6)
|
||||
int(0)
|
||||
int(56)
|
||||
int(14)
|
||||
string(8) "PHP with"
|
||||
string(20) "PHP with overloading"
|
||||
int(250)
|
||||
int(170)
|
||||
int(0)
|
||||
43
tests/binary_assign_objdim.phpt
Normal file
43
tests/binary_assign_objdim.phpt
Normal file
@@ -0,0 +1,43 @@
|
||||
--TEST--
|
||||
binary assign obj/dim ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __assign_add($val) {
|
||||
return $this->value += $val;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
class bar implements arrayaccess {
|
||||
public $baz;
|
||||
|
||||
function offsetget($ofs) {
|
||||
return $this->{$ofs};
|
||||
}
|
||||
|
||||
function offsetset($ofs,$val) { echo "argh"; }
|
||||
function offsetunset($ofs) { echo "oof"; }
|
||||
function offsetexists($ofs) { echo "ick"; return true; }
|
||||
}
|
||||
|
||||
$a = new foo(4);
|
||||
$b = new bar;
|
||||
$b->baz = $a;
|
||||
|
||||
var_dump($b->baz += 10);
|
||||
var_dump($b->baz += 5);
|
||||
var_dump($b['baz'] += 10);
|
||||
var_dump($b['baz'] += 5);
|
||||
--EXPECT--
|
||||
int(14)
|
||||
int(19)
|
||||
int(29)
|
||||
int(34)
|
||||
33
tests/bug56904.phpt
Normal file
33
tests/bug56904.phpt
Normal file
@@ -0,0 +1,33 @@
|
||||
--TEST--
|
||||
Bug#56904 Mixing direct calls and implicit overloads
|
||||
--FILE--
|
||||
<?php
|
||||
class a {
|
||||
|
||||
public $v = 'initial';
|
||||
|
||||
public function __assign_sl($val) {
|
||||
$this->v = $val;
|
||||
}
|
||||
}
|
||||
|
||||
$bob = new a;
|
||||
var_dump($bob);
|
||||
$bob->__assign_sl('abc');
|
||||
var_dump($bob);
|
||||
$bob <<= 'def';
|
||||
var_dump($bob);
|
||||
|
||||
--EXPECTF--
|
||||
object(a)#%d (1) {
|
||||
["v"]=>
|
||||
string(7) "initial"
|
||||
}
|
||||
object(a)#%d (1) {
|
||||
["v"]=>
|
||||
string(3) "abc"
|
||||
}
|
||||
object(a)#%d (1) {
|
||||
["v"]=>
|
||||
string(3) "def"
|
||||
}
|
||||
69
tests/compare.phpt
Normal file
69
tests/compare.phpt
Normal file
@@ -0,0 +1,69 @@
|
||||
--TEST--
|
||||
Basic comparison ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __is_identical($val) {
|
||||
return $this->value === $val;
|
||||
}
|
||||
|
||||
function __is_not_identical($val) {
|
||||
return $this->value !== $val;
|
||||
}
|
||||
|
||||
function __is_equal($val) {
|
||||
return $this->value == $val;
|
||||
}
|
||||
|
||||
function __is_not_equal($val) {
|
||||
return $this->value != $val;
|
||||
}
|
||||
|
||||
function __is_smaller($val) {
|
||||
return $this->value < $val;
|
||||
}
|
||||
|
||||
function __is_smaller_or_equal($val) {
|
||||
return $this->value <= $val;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
$c = new foo(5);
|
||||
|
||||
var_dump($c === 5);
|
||||
var_dump($c === '5');
|
||||
var_dump($c !== 5);
|
||||
var_dump($c !== '5');
|
||||
var_dump($c == 5);
|
||||
var_dump($c == '5');
|
||||
var_dump($c == 6);
|
||||
var_dump($c != 5);
|
||||
var_dump($c != '5');
|
||||
var_dump($c != 6);
|
||||
var_dump($c < 5);
|
||||
var_dump($c < 6);
|
||||
var_dump($c <= 5);
|
||||
var_dump($c <= 4);
|
||||
--EXPECT--
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
34
tests/compare2.phpt
Normal file
34
tests/compare2.phpt
Normal file
@@ -0,0 +1,34 @@
|
||||
--TEST--
|
||||
Extended comparison ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip";
|
||||
if(!OPERATOR_COMPARE_PATCH) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __is_greater($val) {
|
||||
return $this->value > $val;
|
||||
}
|
||||
|
||||
function __is_greater_or_equal($val) {
|
||||
return $this->value >= $val;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
$c = new foo(5);
|
||||
|
||||
var_dump($c > 5);
|
||||
var_dump($c > 4);
|
||||
var_dump($c >= 5);
|
||||
var_dump($c >= 6);
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(true)
|
||||
bool(true)
|
||||
bool(false)
|
||||
65
tests/incdec_obj.phpt
Normal file
65
tests/incdec_obj.phpt
Normal file
@@ -0,0 +1,65 @@
|
||||
--TEST--
|
||||
Inc/Dec obj ops
|
||||
--SKIPIF--
|
||||
<?php if(!extension_loaded("operator")) print "skip"; ?>
|
||||
--FILE--
|
||||
<?php
|
||||
class foo {
|
||||
private $value;
|
||||
|
||||
function __post_inc() {
|
||||
return $this->value++;
|
||||
}
|
||||
|
||||
function __post_dec() {
|
||||
return $this->value--;
|
||||
}
|
||||
|
||||
function __pre_inc() {
|
||||
$this->value++;
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function __pre_dec() {
|
||||
$this->value--;
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
function __construct($init) {
|
||||
$this->value = $init;
|
||||
}
|
||||
}
|
||||
|
||||
class bar {
|
||||
public $baz;
|
||||
}
|
||||
|
||||
$c = new foo(7);
|
||||
$d = new bar;
|
||||
$d->baz = $c;
|
||||
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump($d->baz++);
|
||||
}
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump($d->baz--);
|
||||
}
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump(++$d->baz);
|
||||
}
|
||||
for($i = 0; $i < 3; $i++) {
|
||||
var_dump(--$d->baz);
|
||||
}
|
||||
--EXPECT--
|
||||
int(7)
|
||||
int(8)
|
||||
int(9)
|
||||
int(10)
|
||||
int(9)
|
||||
int(8)
|
||||
int(8)
|
||||
int(9)
|
||||
int(10)
|
||||
int(9)
|
||||
int(8)
|
||||
int(7)
|
||||
Reference in New Issue
Block a user