com php-src: Fix various update_opN_const issues: ext /opcache/Optimizer/zend_optimizer.c
| From: | Nikita Popov | Date: | Sat, 07 Nov 2015 16:45:26 +0000 |
| Subject: | com php-src: Fix various update_opN_const issues: ext /opcache/Optimizer/zend_optimizer.c | ||
| Groups: | php.cvs | ||
| Request: | Send a blank email to php-cvs+get-89640@lists.php.net to get a copy of this message | ||
Commit: bc3512c1d6857de2d3908c4865328e7947e13493
Author: Nikita Popov <nikic@php.net> Sat, 7 Nov 2015 17:45:26 +0100
Parents: 9da456655c56da3bf3099777fe5dec887f964bfd
Branches: PHP-7.0 master
Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=bc3512c1d6857de2d3908c4865328e7947e13493
Log:
Fix various update_opN_const issues
Changed paths:
M ext/opcache/Optimizer/zend_optimizer.c
Diff:
diff --git a/ext/opcache/Optimizer/zend_optimizer.c b/ext/opcache/Optimizer/zend_optimizer.c
index 81f5060..aa5b6a8 100644
--- a/ext/opcache/Optimizer/zend_optimizer.c
+++ b/ext/opcache/Optimizer/zend_optimizer.c
@@ -137,6 +137,21 @@ static inline void alloc_cache_slots_op2(zend_op_array *op_array, zend_op
*oplin
op_array->cache_size += num * sizeof(void *);
}
+#define REQUIRES_STRING(val) do { \
+ if (Z_TYPE_P(val) != IS_STRING) { \
+ zval_dtor(val); \
+ return 0; \
+ } \
+} while (0)
+
+#define TO_STRING_NOWARN(val) do { \
+ if (Z_TYPE_P(val) >= IS_ARRAY) { \
+ zval_dtor(val); \
+ return 0; \
+ } \
+ convert_to_string(val); \
+} while (0)
+
int zend_optimizer_update_op1_const(zend_op_array *op_array,
zend_op *opline,
zval *val)
@@ -151,10 +166,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
case ZEND_FETCH_CONSTANT:
case ZEND_DEFINED:
case ZEND_NEW:
- if (Z_TYPE_P(val) != IS_STRING) {
- zval_dtor(val);
- return 0;
- }
+ REQUIRES_STRING(val);
ZEND_OP1_TYPE(opline) = IS_CONST;
drop_leading_backslash(val);
opline->op1.constant = zend_optimizer_add_literal(op_array, val);
@@ -165,7 +177,7 @@ int zend_optimizer_update_op1_const(zend_op_array *op_array,
break;
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
- convert_to_string(val);
+ TO_STRING_NOWARN(val);
/* break missing intentionally */
default:
ZEND_OP1_TYPE(opline) = IS_CONST;
@@ -201,23 +213,25 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_ADD_INTERFACE:
case ZEND_ADD_TRAIT:
case ZEND_INSTANCEOF:
- if (Z_TYPE_P(val) != IS_STRING) {
- zval_dtor(val);
- return 0;
- }
-
+ REQUIRES_STRING(val);
drop_leading_backslash(val);
opline->op2..constant = zend_optimizer_add_literal(op_array, val);
zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
alloc_cache_slots_op2(op_array, opline, 1);
break;
case ZEND_INIT_FCALL:
+ REQUIRES_STRING(val);
zend_str_tolower(Z_STRVAL_P(val), Z_STRLEN_P(val));
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
alloc_cache_slots_op2(op_array, opline, 1);
break;
case ZEND_INIT_DYNAMIC_CALL:
if (Z_TYPE_P(val) == IS_STRING) {
+ if (zend_memrchr(Z_STRVAL_P(val), ':', Z_STRLEN_P(val))) {
+ zval_dtor(val);
+ return 0;
+ }
+
opline->opcode = ZEND_INIT_FCALL_BY_NAME;
drop_leading_backslash(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
@@ -229,11 +243,10 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
break;
case ZEND_INIT_METHOD_CALL:
case ZEND_INIT_STATIC_METHOD_CALL:
+ REQUIRES_STRING(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
- if (Z_TYPE_P(val) == IS_STRING) {
- zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
- alloc_cache_slots_op2(op_array, opline, 2);
- }
+ zend_optimizer_add_literal_string(op_array, zend_string_tolower(Z_STR_P(val)));
+ alloc_cache_slots_op2(op_array, opline, 2);
break;
/*case ZEND_FETCH_CONSTANT:*/
case ZEND_ASSIGN_OBJ:
@@ -249,10 +262,9 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_POST_INC_OBJ:
case ZEND_POST_DEC_OBJ:
case ZEND_ISSET_ISEMPTY_PROP_OBJ:
+ TO_STRING_NOWARN(val);
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
- if (Z_TYPE_P(val) == IS_STRING) {
- alloc_cache_slots_op2(op_array, opline, 2);
- }
+ alloc_cache_slots_op2(op_array, opline, 2);
break;
case ZEND_ASSIGN_ADD:
case ZEND_ASSIGN_SUB:
@@ -266,11 +278,12 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_ASSIGN_BW_OR:
case ZEND_ASSIGN_BW_AND:
case ZEND_ASSIGN_BW_XOR:
- opline->op2.constant = zend_optimizer_add_literal(op_array, val);
- if (Z_TYPE_P(val) == IS_STRING) {
- if (opline->extended_value == ZEND_ASSIGN_OBJ) {
- alloc_cache_slots_op2(op_array, opline, 2);
- }
+ if (opline->extended_value == ZEND_ASSIGN_OBJ) {
+ TO_STRING_NOWARN(val);
+ opline->op2.constant = zend_optimizer_add_literal(op_array, val);
+ alloc_cache_slots_op2(op_array, opline, 2);
+ } else {
+ opline->op2.constant = zend_optimizer_add_literal(op_array, val);
}
break;
case ZEND_OP_DATA:
@@ -319,7 +332,7 @@ int zend_optimizer_update_op2_const(zend_op_array *op_array,
case ZEND_ROPE_END:
case ZEND_CONCAT:
case ZEND_FAST_CONCAT:
- convert_to_string(val);
+ TO_STRING_NOWARN(val);
/* break missing intentionally */
default:
opline->op2.constant = zend_optimizer_add_literal(op_array, val);
@@ -351,6 +364,8 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
case ZEND_FETCH_DIM_UNSET:
case ZEND_ASSIGN_DIM:
case ZEND_SEPARATE:
+ case ZEND_RETURN_BY_REF:
+ zval_dtor(val);
return 0;
case ZEND_SEND_VAR:
opline->extended_value = 0;
@@ -373,6 +388,9 @@ int zend_optimizer_replace_by_const(zend_op_array *op_array,
opline->opcode = ZEND_SEND_VAL;
}
break;
+ case ZEND_SEND_USER:
+ opline->opcode = ZEND_SEND_VAL_EX;
+ break;
/* In most cases IS_TMP_VAR operand may be used only once.
* The operands are usually destroyed by the opcode handler.
* ZEND_CASE is an exception, that keeps operand unchanged,