0

I'm using the zend_read_property to read the attribute from an object.

zend_read_property(
    scope: *mut zend_class_entry, 
    object: *mut zval, 
    name: *const c_char, 
    name_length: size_t, 
    silent: zend_bool, 
    rv: *mut zval
) -> *mut zval
zval *output, rv;

output = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("output"), ZEND_FETCH_CLASS_SILENT, &rv);

However, I don't know why it need the rv parameter. What is the purpose of this parameter?

Mark Smith
  • 138
  • 1
  • 8
  • Typically, rv variable name is short for "return value", if that's what you are asking. – Taimoor Zaeem Aug 25 '22 at 08:22
  • @TaimoorZaeem, no it isn't. ```zval *output, rv; output = zend_read_property(ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("output"), ZEND_FETCH_CLASS_SILENT, &rv);``` The *output is the return value. Not sure about the rv. – Mark Smith Aug 25 '22 at 08:24

1 Answers1

0

The rv parameter is an easy way to give the class's read_property handler a place to store the property value (i.e. the return value). An implementation might not readily have the property value stored as a zval, in which case it can use the rv argument and let the caller worry about the lifecycle of the zval. You can think of it like a temporary location for the property value to live.

It's important to note that the read_property handler doesn't have to use the rv argument. Ideally, you should check to see if the return value equals the address of rv, in which case you should free the rv zval in case there is a dynamic memory structure associated with it (e.g. a string or object value).

Here's a blurb from www.phpinternalsbook.com

read_property may directly return a zval owned by the object, in which case its reference count should not be modified by read_property, and the caller should not release it. Alternatively, it may return rv for temporary zvals (e.g. result of call to __get), in which case the refcount should be incremented, and the caller is responsible for releasing the value.

I've looked over some code from php-src, and I see many instances of calling zend_read_property that do not check/free the zv value as I would expect. It could be an optimization if the programmer knows that it won't ever be used by the handler in question.

It's also unclear to me whether the caller is responsible for initializing rv. I tend to think not: if the handler decides to use rv, it will ensure it is initialized and return its address. The caller should then, in the generic case, check if the return value equals rv and free it accordingly.

Roger Gee
  • 851
  • 5
  • 10