]> granicus.if.org Git - php/commitdiff
Improve class constant fetch fix
authorNikita Popov <nikic@php.net>
Thu, 29 May 2014 09:17:33 +0000 (11:17 +0200)
committerNikita Popov <nikic@php.net>
Thu, 29 May 2014 09:17:33 +0000 (11:17 +0200)
Dereference the cached constant for Test::TEST as well (and not just
self::TEST).

Also improve the phpt file to test this case as well - previously
this only manifested with opcache enabled, due to literal sharing.

Additionally the Z_TYPE_P != IS_REFERENCE assertion is now moved
into the TMP_VAR fetching code (as it applies to more than just
property assignments.)

Zend/tests/class_constant_to_reference_cached.phpt
Zend/zend_execute.c
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

index b752226aba3d1945fae7fcb7e118548840c42591..5bfbc61dd08ff4244e1fab8e04097ff1cd139f1b 100644 (file)
@@ -13,17 +13,16 @@ class Test {
     }
 }
 
-$obj = new Test;
-$obj->readConst();
-unset($obj);
-var_dump(Test::TEST);
+function doTest() {
+    $obj = new Test;
+    $obj->readConst();
+    unset($obj);
+    var_dump(Test::TEST);
+}
 
+doTest();
 eval('class Test2 extends Test {}');
-
-$obj = new Test;
-$obj->readConst();
-unset($obj);
-var_dump(Test::TEST);
+doTest();
 
 ?>
 --EXPECT--
index 9cc0f3a4cf914fd3c17ab81c5653149a20526a2f..ae66364aa991bebea87be67a968d21edddd9c4a6 100644 (file)
@@ -147,8 +147,10 @@ ZEND_API zval* zend_get_compiled_variable_value(const zend_execute_data *execute
 static zend_always_inline zval *_get_zval_ptr_tmp(zend_uint var, const zend_execute_data *execute_data, zend_free_op *should_free TSRMLS_DC)
 {
        zval *ret = EX_VAR(var);
-
        should_free->var = ret;
+
+       ZEND_ASSERT(Z_TYPE_P(ret) != IS_REFERENCE);
+
        return ret;
 }
 
@@ -724,7 +726,6 @@ static inline void zend_assign_to_object(zval *retval, zval *object_ptr, zval *p
 
        /* separate our value if necessary */
        if (value_type == IS_TMP_VAR) {
-               ZEND_ASSERT(Z_TYPE_P(value) != IS_REFERENCE);
                ZVAL_COPY_VALUE(&tmp, value);
                value = &tmp;
        } else if (value_type == IS_CONST) {
index 5042c065ba41d6e1dc067d0ad4125deba0b32544..c27570c9dfd3d321d69cf30e27c4d48bfc05f6ea 100644 (file)
@@ -3614,6 +3614,7 @@ ZEND_VM_HANDLER(99, ZEND_FETCH_CONSTANT, VAR|CONST|UNUSED, CONST)
                if (OP1_TYPE == IS_CONST) {
                        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
                                value = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                               ZVAL_DEREF(value);
                                ZVAL_DUP(EX_VAR(opline->result.var), value);
                                goto constant_fetch_end;
                        } else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
index 5b5c69923a00b1d791583e0d668c4abeed3811de..4534be8639c6abd3bc12a6ccb13f55d01e9ea073 100644 (file)
@@ -3886,6 +3886,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_CONST_CONST_HANDLER(ZEND_OPCO
                if (IS_CONST == IS_CONST) {
                        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
                                value = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                               ZVAL_DEREF(value);
                                ZVAL_DUP(EX_VAR(opline->result.var), value);
                                goto constant_fetch_end;
                        } else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
@@ -15328,6 +15329,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE
                if (IS_VAR == IS_CONST) {
                        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
                                value = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                               ZVAL_DEREF(value);
                                ZVAL_DUP(EX_VAR(opline->result.var), value);
                                goto constant_fetch_end;
                        } else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {
@@ -24538,6 +24540,7 @@ static int ZEND_FASTCALL  ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPC
                if (IS_UNUSED == IS_CONST) {
                        if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv))) {
                                value = CACHED_PTR(Z_CACHE_SLOT_P(opline->op2.zv));
+                               ZVAL_DEREF(value);
                                ZVAL_DUP(EX_VAR(opline->result.var), value);
                                goto constant_fetch_end;
                        } else if (CACHED_PTR(Z_CACHE_SLOT_P(opline->op1.zv))) {