After a short discussion on the zend-engine-2 list about handling
unsigned values I decided to write a quick patch (Attached) that adds an
unsigned right shift operator, and an unsigned right shift assign
operator (Similar to Java).
The following code/output displays the difference:
Code:
<?php
$signed = 1 << 31 >> 31;
$unsigned = 1 << 31 >>> 31;
print "Signed: $signed\n";
print "Unsigned: $unsigned\n";
?>
Output:
Signed: -1
Unsigned: 1
Index: zend_compile.h
===================================================================
RCS file: /repository/Zend/zend_compile.h,v
retrieving revision 1.141
diff -u -r1.141 zend_compile.h
--- zend_compile.h 10 Feb 2002 12:52:45 -0000 1.141
+++ zend_compile.h 18 Mar 2002 05:12:02 -0000
@@ -396,6 +396,7 @@
#define ZEND_MOD 5
#define ZEND_SL 6
#define ZEND_SR 7
+#define ZEND_USR 107
#define ZEND_CONCAT 8
#define ZEND_BW_OR 9
#define ZEND_BW_AND 10
@@ -419,6 +420,7 @@
#define ZEND_ASSIGN_MOD 27
#define ZEND_ASSIGN_SL 28
#define ZEND_ASSIGN_SR 29
+#define ZEND_ASSIGN_USR 108
#define ZEND_ASSIGN_CONCAT 30
#define ZEND_ASSIGN_BW_OR 31
#define ZEND_ASSIGN_BW_AND 32
@@ -521,7 +523,6 @@
#define ZEND_TICKS 105
#define ZEND_SEND_VAR_NO_REF 106
-
/* end of block */
Index: zend_execute.c
===================================================================
RCS file: /repository/Zend/zend_execute.c,v
retrieving revision 1.293
diff -u -r1.293 zend_execute.c
--- zend_execute.c 6 Jan 2002 15:21:09 -0000 1.293
+++ zend_execute.c 18 Mar 2002 05:12:08 -0000
@@ -1077,6 +1077,9 @@
case ZEND_SR:
EG(binary_op) = shift_right_function;
goto binary_op_addr;
+ case ZEND_USR:
+ EG(binary_op) = ushift_right_function;
+ goto binary_op_addr;
case ZEND_CONCAT:
EG(binary_op) = concat_function;
goto binary_op_addr;
@@ -1144,6 +1147,9 @@
goto binary_assign_op_addr;
case ZEND_ASSIGN_SR:
EG(binary_op) = shift_right_function;
+ goto binary_assign_op_addr;
+ case ZEND_ASSIGN_USR:
+ EG(binary_op) = ushift_right_function;
goto binary_assign_op_addr;
case ZEND_ASSIGN_CONCAT:
EG(binary_op) = concat_function;
Index: zend_language_parser.y
===================================================================
RCS file: /repository/Zend/zend_language_parser.y,v
retrieving revision 1.17
diff -u -r1.17 zend_language_parser.y
--- zend_language_parser.y 19 Jan 2002 10:28:26 -0000 1.17
+++ zend_language_parser.y 18 Mar 2002 05:12:10 -0000
@@ -53,7 +53,7 @@
%left T_LOGICAL_XOR
%left T_LOGICAL_AND
%right T_PRINT
-%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL
T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL
+%left '=' T_PLUS_EQUAL T_MINUS_EQUAL T_MUL_EQUAL T_DIV_EQUAL T_CONCAT_EQUAL
+T_MOD_EQUAL T_AND_EQUAL T_OR_EQUAL T_XOR_EQUAL T_SL_EQUAL T_SR_EQUAL T_USR_EQUAL
%left '?' ':'
%left T_BOOLEAN_OR
%left T_BOOLEAN_AND
@@ -62,7 +62,7 @@
%left '&'
%nonassoc T_IS_EQUAL T_IS_NOT_EQUAL T_IS_IDENTICAL T_IS_NOT_IDENTICAL
%nonassoc '<' T_IS_SMALLER_OR_EQUAL '>' T_IS_GREATER_OR_EQUAL
-%left T_SL T_SR
+%left T_SL T_SR T_USR
%left '+' '-' '.'
%left '*' '/' '%'
%right '!' '~' T_INC T_DEC T_INT_CAST T_DOUBLE_CAST T_STRING_CAST T_ARRAY_CAST
T_OBJECT_CAST T_BOOL_CAST T_UNSET_CAST '@'
@@ -430,8 +430,9 @@
| cvar T_AND_EQUAL expr {
zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC);
zend_do_binary_assign_op(ZEND_ASSIGN_BW_AND, &$$, &$1, &$3 TSRMLS_CC); }
| cvar T_OR_EQUAL expr {
zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC);
zend_do_binary_assign_op(ZEND_ASSIGN_BW_OR, &$$, &$1, &$3 TSRMLS_CC); }
| cvar T_XOR_EQUAL expr {
zend_do_end_variable_parse(BP_VAR_RW, 0 TSRMLS_CC);
zend_do_binary_assign_op(ZEND_ASSIGN_BW_XOR, &$$, &$1, &$3 TSRMLS_CC); }
- | cvar T_SL_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0
TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 TSRMLS_CC); }
- | cvar T_SR_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0
TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 TSRMLS_CC); }
+ | cvar T_SL_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0
+TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SL, &$$, &$1, &$3 TSRMLS_CC); }
+ | cvar T_SR_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0
+TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_SR, &$$, &$1, &$3 TSRMLS_CC); }
+ | cvar T_USR_EQUAL expr { zend_do_end_variable_parse(BP_VAR_RW, 0
+TSRMLS_CC); zend_do_binary_assign_op(ZEND_ASSIGN_USR, &$$, &$1, &$3 TSRMLS_CC); }
| rw_cvar T_INC { zend_do_post_incdec(&$$, &$1, ZEND_POST_INC
TSRMLS_CC); }
| T_INC rw_cvar { zend_do_pre_incdec(&$$, &$2, ZEND_PRE_INC TSRMLS_CC); }
| rw_cvar T_DEC { zend_do_post_incdec(&$$, &$1, ZEND_POST_DEC
TSRMLS_CC); }
@@ -452,6 +453,7 @@
| expr '%' expr { zend_do_binary_op(ZEND_MOD, &$$, &$1, &$3
TSRMLS_CC); }
| expr T_SL expr { zend_do_binary_op(ZEND_SL, &$$, &$1, &$3 TSRMLS_CC);
}
| expr T_SR expr { zend_do_binary_op(ZEND_SR, &$$, &$1, &$3 TSRMLS_CC);
}
+ | expr T_USR expr { zend_do_binary_op(ZEND_USR, &$$, &$1, &$3
+TSRMLS_CC); }
| '+' expr { $1.u.constant.value.lval=0; $1.u.constant.type=IS_LONG;
$1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_ADD, &$$,
&$1, &$2 TSRMLS_CC); }
| '-' expr { $1.u.constant.value.lval=0; $1.u.constant.type=IS_LONG;
$1.op_type = IS_CONST; INIT_PZVAL(&$1.u.constant); zend_do_binary_op(ZEND_SUB, &$$,
&$1, &$2 TSRMLS_CC); }
| '!' expr { zend_do_unary_op(ZEND_BOOL_NOT, &$$, &$2 TSRMLS_CC); }
Index: zend_language_scanner.l
===================================================================
RCS file: /repository/Zend/zend_language_scanner.l,v
retrieving revision 1.43
diff -u -r1.43 zend_language_scanner.l
--- zend_language_scanner.l 6 Jan 2002 15:21:09 -0000 1.43
+++ zend_language_scanner.l 18 Mar 2002 05:12:12 -0000
@@ -765,6 +765,10 @@
return T_SR_EQUAL;
}
+<ST_IN_SCRIPTING>">>>=" {
+ return T_USR_EQUAL;
+}
+
<ST_IN_SCRIPTING>"&=" {
return T_AND_EQUAL;
}
@@ -803,6 +807,10 @@
<ST_IN_SCRIPTING>">>" {
return T_SR;
+}
+
+<ST_IN_SCRIPTING>">>>" {
+ return T_USR;
}
<ST_IN_SCRIPTING>{TOKENS} {
Index: zend_operators.c
===================================================================
RCS file: /repository/Zend/zend_operators.c,v
retrieving revision 1.117
diff -u -r1.117 zend_operators.c
--- zend_operators.c 6 Jan 2002 15:21:09 -0000 1.117
+++ zend_operators.c 18 Mar 2002 05:12:16 -0000
@@ -983,6 +983,17 @@
return SUCCESS;
}
+ZEND_API int ushift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC)
+{
+ zval op1_copy, op2_copy;
+
+ zendi_convert_to_long(op1, op1_copy, result);
+ zendi_convert_to_long(op2, op2_copy, result);
+ result->value.lval = (unsigned long) op1->value.lval >> op2->value.lval;
+ result->type = IS_LONG;
+ return SUCCESS;
+}
+
/* must support result==op1 */
Index: zend_operators.h
===================================================================
RCS file: /repository/Zend/zend_operators.h,v
retrieving revision 1.50
diff -u -r1.50 zend_operators.h
--- zend_operators.h 6 Jan 2002 15:21:09 -0000 1.50
+++ zend_operators.h 18 Mar 2002 05:12:16 -0000
@@ -49,6 +49,7 @@
ZEND_API int bitwise_xor_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int shift_left_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int shift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
+ZEND_API int ushift_right_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int concat_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
ZEND_API int is_equal_function(zval *result, zval *op1, zval *op2 TSRMLS_DC);
--
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php