* Method that is called right before a static method call is attempted * * @param entry The class entry to find the static function in * @param method The method to get information about * @param key ??? * @return zend_function */
| 259 | * @return zend_function |
| 260 | */ |
| 261 | zend_function *ClassImpl::getStaticMethod(zend_class_entry *entry, zend_string *method) |
| 262 | { |
| 263 | // first we'll check if the default handler does not have an implementation, |
| 264 | // in that case the method is probably already implemented as a regular method |
| 265 | auto *defaultFunction = zend_std_get_static_method(entry, method, nullptr); |
| 266 | |
| 267 | // did the default implementation do anything? |
| 268 | if (defaultFunction) return defaultFunction; |
| 269 | |
| 270 | // just like we did in getMethod() (see comment there) we are going to dynamically |
| 271 | // allocate data holding information about the function |
| 272 | auto *data = (CallData *)emalloc(sizeof(CallData)); |
| 273 | auto *function = &data->func; |
| 274 | |
| 275 | // reset everything to zero (in case future PHP versions add more fields) |
| 276 | memset(function, 0, sizeof(*function)); |
| 277 | |
| 278 | // set all properties for the function |
| 279 | function->type = ZEND_INTERNAL_FUNCTION; |
| 280 | function->arg_flags[0] = 0; |
| 281 | function->arg_flags[1] = 0; |
| 282 | function->arg_flags[2] = 0; |
| 283 | function->fn_flags = ZEND_ACC_CALL_VIA_HANDLER; |
| 284 | function->function_name = nullptr; |
| 285 | function->scope = nullptr; |
| 286 | function->prototype = nullptr; |
| 287 | function->num_args = 0; |
| 288 | function->required_num_args = 0; |
| 289 | function->arg_info = nullptr; |
| 290 | function->handler = &ClassImpl::callMethod; |
| 291 | |
| 292 | // store pointer to ourselves |
| 293 | data->self = self(entry); |
| 294 | |
| 295 | // done (cast to zend_function* is allowed, because a zend_function is a union |
| 296 | // that has one member being a zend_internal_function) |
| 297 | return (zend_function *)data; |
| 298 | } |
| 299 | |
| 300 | /** |
| 301 | * Method that returns the closure -- this is the __invoke handler! |