edit: to be clear, I want to identify & track functions called without incurring the cost and ambiguity of hashing on the string of class.function. I was hoping php kept some internal hashes.
I'm working on an extension and I'd like a reliable way of getting a hash code for a particular zend_execute_data->zend_function
, without the overhead of calling some hash function on the function name (which would result in collisions anyway with overloaded functions).
_zend_execute_data.opline has a field called "extended_value" that looks like it gets set with the value of zend_hash_function against something in op1, but only if op2 is a constant.
if (opline->op2.op_type == IS_CONST) {
...
opline->extended_value = zend_hash_func(Z_STRVAL(opline->op1.u.constant), Z_STRLEN(opline->op1.u.constant) + 1);
I'm not sure what op2 type IS_CONST means and I'm not sure if this would be reliable or not. And I'm not sure if this hashcode is for the function definition, or an particular instance on a class.
edit: I'm guessing IS_CONST means the function is not a member of an object instance.
Anything else that could be used as a hash code proxy for the execute_data->zend_function?
A very simple approach is the use the pointer of the zend_function *
itself to index into a hashtable. I.e. use (unsigned long) (uintptr_t) func
as the index.
There is one caveat with this approach: While functions/methods usually have a unique zend_function *
during the lifetime of the script, there are some cases (like __call
magic) where a temporary zend_function *
structure is allocated. In these cases the ZEND_ACC_CALL_VIA_HANDLER
flag will be set on the function. If you want to support these cases as well, you'll have to use a separate mechanism for them.