rfc:propertygetsetsyntax-implementation-details

This is an old revision of the document!


Internal Implementation Details for Property Accessors

  • Version: 1.1 (to be updated prior to vote)
  • Created: 2012-12-29
  • Author: Clint Priest <phpdev at zerocue dot com>
  • Contributors: Nikita Popov

Internal Implementation

Note: These implementation details have not been kept up with the semi-rapidly changing internal implementation and will be updated near the beginning of the voting period when all code has been completed

Accessor information is stored in a new zend_accessor_info struct. These structures are stored in a new HashTable property in a zend_class_entry structure named accessors. They are indexed by the hash_value of the property name and are thus quickly accessed during property resolution.

typedef struct _zend_accessor_info {
	zend_uint	flags;
	const char 	*doc_comment;
	int 		doc_comment_len;
	zend_function 	*getter;
	zend_function 	*setter;
	zend_function 	*isset;
	zend_function 	*unset;
} zend_accessor_info;

Internally the accessors are implemented as ordinary functions (with appropriate access levels) with specialized names. get/set/isset/unset for a property named $Hours would be __getHours(), __setHours($value), __issetHours() and __unsetHours() respectively.

Two new function flags have been defined:

#define ZEND_ACC_READONLY     0x20000000
#define ZEND_ACC_WRITEONLY    0x40000000

An additional byte was added to zend_internal_function:

zend_uchar purpose;

This was in lieu of using 4 additional flag values for which there was not room. There are presently five states purpose can be in, they are:

#define ZEND_FNP_UNDEFINED			0		/* No special purpose function */
#define ZEND_FNP_PROP_GETTER			1		/* Special purpose accessor: getter */
#define ZEND_FNP_PROP_SETTER			2		/* Special purpose accessor: setter */
#define ZEND_FNP_PROP_ISSETTER			3		/* Special purpose accessor: issetter */
#define ZEND_FNP_PROP_UNSETTER			4		/* Special purpose accessor: unsetter */

* __get(), __set(), __isset() and __unset() guards were used and the functionality is the same with the new accessors.

* Error producing lines have been modified to check the function for ZEND_ACC_IS_ACCESSOR mask with more appropriate error report occurring. For example: Cannot override final property getter TimePeriod::$Hours

Static Accessors

There was no built-in mechanism to handle custom get/set/isset/unset for static properties, these were handled by catching references to static properties, checking for the existence of a static accessor and converting the compilation into a function call. When a static setter is being used, the compiled code first becomes a static getter call and the zend_do_assign backpatches the op_array to become a call to the setter, as appropriate.

This yielded the possibility that a getter call was being made while it should not be allowed (if there was no getter defined) and so pass_two() was changed to look for these non-backpatched illegal static getter calls and a compile time error is produced.

rfc/propertygetsetsyntax-implementation-details.1356892530.txt.gz · Last modified: 2017/09/22 13:28 (external edit)