Created
September 22, 2013 13:24
-
-
Save chobie/6659868 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Zend/zend.h b/Zend/zend.h | |
index 1377fd5..59d811a 100644 | |
--- a/Zend/zend.h | |
+++ b/Zend/zend.h | |
@@ -588,6 +588,8 @@ typedef int (*zend_write_func_t)(const char *str, uint str_length); | |
#define IS_CONSTANT 8 | |
#define IS_CONSTANT_ARRAY 9 | |
#define IS_CALLABLE 10 | |
+#define IS_BYTE 11 | |
+#define IS_ORD 12 | |
/* Ugly hack to support constants as static array indices */ | |
#define IS_CONSTANT_TYPE_MASK 0x00f | |
diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y | |
index 6a9a24a..2cf916c 100644 | |
--- a/Zend/zend_language_parser.y | |
+++ b/Zend/zend_language_parser.y | |
@@ -108,7 +108,7 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); | |
%right '!' | |
%nonassoc T_INSTANCEOF | |
%token T_INSTANCEOF "instanceof (T_INSTANCEOF)" | |
-%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 '@' | |
+%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 T_BYTE_CAST T_ORD_CAST'@' | |
%token T_INC "++ (T_INC)" | |
%token T_DEC "-- (T_DEC)" | |
%token T_INT_CAST "(int) (T_INT_CAST)" | |
@@ -118,6 +118,8 @@ static YYSIZE_T zend_yytnamerr(char*, const char*); | |
%token T_OBJECT_CAST "(object) (T_OBJECT_CAST)" | |
%token T_BOOL_CAST "(bool) (T_BOOL_CAST)" | |
%token T_UNSET_CAST "(unset) (T_UNSET_CAST)" | |
+%token T_BYTE_CAST "(byte) (T_BYTE_CAST)" | |
+%token T_ORD_CAST "(ord) (T_ORD_CAST)" | |
%right '[' | |
%nonassoc T_NEW T_CLONE | |
%token T_NEW "new (T_NEW)" | |
@@ -801,6 +803,8 @@ expr_without_variable: | |
| T_OBJECT_CAST expr { zend_do_cast(&$$, &$2, IS_OBJECT TSRMLS_CC); } | |
| T_BOOL_CAST expr { zend_do_cast(&$$, &$2, IS_BOOL TSRMLS_CC); } | |
| T_UNSET_CAST expr { zend_do_cast(&$$, &$2, IS_NULL TSRMLS_CC); } | |
+ | T_BYTE_CAST expr { zend_do_cast(&$$, &$2, IS_BYTE TSRMLS_CC); } | |
+ | T_ORD_CAST expr { zend_do_cast(&$$, &$2, IS_ORD TSRMLS_CC); } | |
| T_EXIT exit_expr { zend_do_exit(&$$, &$2 TSRMLS_CC); } | |
| '@' { zend_do_begin_silence(&$1 TSRMLS_CC); } expr { zend_do_end_silence(&$1 TSRMLS_CC); $$ = $3; } | |
| scalar { $$ = $1; } | |
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c | |
index 3423738..c215d50 100644 | |
--- a/Zend/zend_operators.c | |
+++ b/Zend/zend_operators.c | |
@@ -759,6 +759,36 @@ ZEND_API void convert_to_object(zval *op) /* {{{ */ | |
} | |
/* }}} */ | |
+ZEND_API void convert_to_byte(zval *op) /* {{{ */ | |
+{ | |
+ long c; | |
+ char temp[2]; | |
+ | |
+ if (Z_TYPE_P(op) != IS_LONG) { | |
+ convert_to_long_base(op, 10); | |
+ } | |
+ | |
+ temp[0] = (char)Z_LVAL_P(op);; | |
+ temp[1] = '\0'; | |
+ | |
+ ZVAL_STRINGL(op, temp, 1, 1); | |
+} | |
+/* }}} */ | |
+ | |
+ZEND_API void convert_to_ord(zval *op) /* {{{ */ | |
+{ | |
+ long c; | |
+ if (Z_TYPE_P(op) != IS_STRING) { | |
+ convert_to_string(op); | |
+ } | |
+ | |
+ c = (unsigned char)Z_STRVAL_P(op)[0]; | |
+ STR_FREE(Z_STRVAL_P(op)); | |
+ ZVAL_LONG(op, c); | |
+} | |
+/* }}} */ | |
+ | |
+ | |
ZEND_API void multi_convert_to_long_ex(int argc, ...) /* {{{ */ | |
{ | |
zval **arg; | |
diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h | |
index 15ad79e..ba54281 100644 | |
--- a/Zend/zend_operators.h | |
+++ b/Zend/zend_operators.h | |
@@ -333,6 +333,8 @@ ZEND_API void convert_to_null(zval *op); | |
ZEND_API void convert_to_boolean(zval *op); | |
ZEND_API void convert_to_array(zval *op); | |
ZEND_API void convert_to_object(zval *op); | |
+ZEND_API void convert_to_byte(zval *op); | |
+ZEND_API void convert_to_ord(zval *op); | |
ZEND_API void multi_convert_to_long_ex(int argc, ...); | |
ZEND_API void multi_convert_to_double_ex(int argc, ...); | |
ZEND_API void multi_convert_to_string_ex(int argc, ...); | |
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h | |
index 2bc80fa..d7dd12c 100644 | |
--- a/Zend/zend_vm_def.h | |
+++ b/Zend/zend_vm_def.h | |
@@ -3735,6 +3735,12 @@ ZEND_VM_HANDLER(21, ZEND_CAST, CONST|TMP|VAR|CV, ANY) | |
case IS_OBJECT: | |
convert_to_object(result); | |
break; | |
+ case IS_BYTE: | |
+ convert_to_byte(result); | |
+ break; | |
+ case IS_ORD: | |
+ convert_to_ord(result); | |
+ break; | |
} | |
FREE_OP1_IF_VAR(); | |
CHECK_EXCEPTION(); | |
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h | |
index 08fb847..5ac8300 100644 | |
--- a/Zend/zend_vm_execute.h | |
+++ b/Zend/zend_vm_execute.h | |
@@ -2638,6 +2638,12 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
case IS_OBJECT: | |
convert_to_object(result); | |
break; | |
+ case IS_BYTE: | |
+ convert_to_byte(result); | |
+ break; | |
+ case IS_ORD: | |
+ convert_to_ord(result); | |
+ break; | |
} | |
CHECK_EXCEPTION(); | |
@@ -7967,6 +7973,12 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
case IS_OBJECT: | |
convert_to_object(result); | |
break; | |
+ case IS_BYTE: | |
+ convert_to_byte(result); | |
+ break; | |
+ case IS_ORD: | |
+ convert_to_ord(result); | |
+ break; | |
} | |
CHECK_EXCEPTION(); | |
@@ -13306,6 +13318,12 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
case IS_OBJECT: | |
convert_to_object(result); | |
break; | |
+ case IS_BYTE: | |
+ convert_to_byte(result); | |
+ break; | |
+ case IS_ORD: | |
+ convert_to_ord(result); | |
+ break; | |
} | |
zval_ptr_dtor(&free_op1.var); | |
CHECK_EXCEPTION(); | |
@@ -30952,6 +30970,12 @@ static int ZEND_FASTCALL ZEND_CAST_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS) | |
case IS_OBJECT: | |
convert_to_object(result); | |
break; | |
+ case IS_BYTE: | |
+ convert_to_byte(result); | |
+ break; | |
+ case IS_ORD: | |
+ convert_to_ord(result); | |
+ break; | |
} | |
CHECK_EXCEPTION(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In most cases, we use wrapper method (e.g)
getBit($buffer, $offset)
) when usingchr
/ord
.so we couldn't realize this optimization as we call
getBIt()
so many times. sigh.