Search code examples
cphp-internals

does zend/php cache hashcodes for functions somewhere in execute data?


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?


Solution

  • 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.