&& offset<=function_being_called->common.arg_types[0] \
&& function_being_called->common.arg_types[offset]==BYREF_FORCE)
-#define MAKE_REF_ON_READ_OBJECT(s) \
- { \
- zval **ptr_ptr; \
- \
- if ((ptr_ptr = (s)) \
- && ((*ptr_ptr)->type == IS_OBJECT) \
- && (!(*ptr_ptr)->is_ref) \
- && ((*ptr_ptr)->refcount>2)) { /* 2 because it's also locked */ \
- zval *ptr = *ptr_ptr; \
- \
- ptr->refcount -= 2; \
- *(ptr_ptr) = (zval *) emalloc(sizeof(zval)); \
- **(ptr_ptr) = *ptr; \
- zval_copy_ctor(*(ptr_ptr)); \
- (*(ptr_ptr))->refcount=2; \
- (*(ptr_ptr))->is_ref = 1; \
- } \
- }
+#define SEPARATE_ON_READ_OBJECT(obj) \
+if ((obj) && (type == BP_VAR_R) && ((*(obj))->type == IS_OBJECT) && (!(*(obj))->is_ref)) { \
+ SEPARATE_ZVAL((obj)); \
+ (*(obj))->is_ref = 1; \
+ }
static inline zval *_get_zval_ptr(znode *node, temp_variable *Ts, int *should_free ELS_DC)
{
if (varname == &tmp_varname) {
zval_dtor(varname);
}
- Ts[result->u.var].var.ptr_ptr = retval;
+ Ts[result->u.var].var.ptr_ptr = retval;
+ SEPARATE_ON_READ_OBJECT(retval);
SELECTIVE_PZVAL_LOCK(*retval, result);
}
} else {
*retval = zend_fetch_dimension_address_inner(container->value.ht, op2, Ts, type ELS_CC);
}
+ SEPARATE_ON_READ_OBJECT(*retval);
SELECTIVE_PZVAL_LOCK(**retval, result);
break;
case IS_STRING: {
zendi_zval_copy_ctor(*container);
}
*retval = zend_fetch_property_address_inner(container->value.obj.properties, op2, Ts, type ELS_CC);
+ SEPARATE_ON_READ_OBJECT(*retval);
SELECTIVE_PZVAL_LOCK(**retval, result);
}
break;
case ZEND_FETCH_R:
zend_fetch_var_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC);
- MAKE_REF_ON_READ_OBJECT(Ts[opline->result.u.var].var.ptr_ptr);
AI_USE_PTR(Ts[opline->result.u.var].var);
break;
case ZEND_FETCH_W:
PZVAL_LOCK(*Ts[opline->op1.u.var].var.ptr_ptr);
}
zend_fetch_dimension_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC);
- MAKE_REF_ON_READ_OBJECT(Ts[opline->result.u.var].var.ptr_ptr);
AI_USE_PTR(Ts[opline->result.u.var].var);
break;
case ZEND_FETCH_DIM_W:
break;
case ZEND_FETCH_OBJ_R:
zend_fetch_property_address(&opline->result, &opline->op1, &opline->op2, Ts, BP_VAR_R ELS_CC);
- MAKE_REF_ON_READ_OBJECT(Ts[opline->result.u.var].var.ptr_ptr);
AI_USE_PTR(Ts[opline->result.u.var].var);
break;
case ZEND_FETCH_OBJ_W: