/* {{{ php_foreach_all */ static int php_foreach_all (int instatus, char *inkey, int inkeylen, char *inval, int invallen, char *indata) { int is_stop = 0; zval *args; zval *retval; TSRMLS_FETCH(); MAKE_STD_ZVAL(args); array_init(args); add_index_long(args, 0, instatus); add_index_stringl(args, 1, inkey, inkeylen, 1); add_index_stringl(args, 2, inval, invallen, 1); php_yp_all_callback *cb = (php_yp_all_callback *) indata; zend_fcall_info_args(&cb->fci, args TSRMLS_CC); zend_fcall_info_call(&cb->fci, &cb->fcc, &retval, args TSRMLS_CC); zend_fcall_info_args_clear(&cb->fci, 1); if (retval) { is_stop = zval_is_true(retval); zval_ptr_dtor(&retval); } return is_stop; }
/* {{{ */ zval * pthreads_read_property (PTHREADS_READ_PROPERTY_PASSTHRU_D) { zend_long *guard = NULL; pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object)); rebuild_object_properties(&threaded->std); if (Z_OBJCE_P(object)->__get && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_GET)) { zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; fci.size = sizeof(zend_fcall_info); fci.retval = rv; fci.object = &threaded->std; zend_fcall_info_argn(&fci, 1, member); fcc.initialized = 1; fcc.function_handler = Z_OBJCE_P(object)->__get; fcc.object = &threaded->std; (*guard) |= IN_GET; zend_call_function(&fci, &fcc); (*guard) &= ~IN_GET; zend_fcall_info_args_clear(&fci, 1); } else { pthreads_store_read(object, member, type, rv); } return rv; }
/* {{{ */ void pthreads_write_property(PTHREADS_WRITE_PROPERTY_PASSTHRU_D) { pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object)); zend_bool nulled = 0; rebuild_object_properties(&threaded->std); switch(Z_TYPE_P(value)){ case IS_UNDEF: case IS_STRING: case IS_LONG: case IS_ARRAY: case IS_OBJECT: case IS_NULL: case IS_DOUBLE: case IS_RESOURCE: case IS_TRUE: case IS_FALSE: { zend_long *guard = NULL; if ((member && Z_TYPE_P(member) != IS_NULL) && Z_OBJCE_P(object)->__set && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_SET)) { zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; zval rv; ZVAL_UNDEF(&rv); fci.size = sizeof(zend_fcall_info); fci.retval = &rv; fci.object = &threaded->std; zend_fcall_info_argn(&fci, 2, member, value); fcc.initialized = 1; fcc.function_handler = Z_OBJCE_P(object)->__set; fcc.object = &threaded->std; (*guard) |= IN_SET; zend_call_function(&fci, &fcc); (*guard) &= ~IN_SET; if (Z_TYPE(rv) != IS_UNDEF) zval_dtor(&rv); zend_fcall_info_args_clear(&fci, 1); } else { pthreads_store_write(object, member, value); } } break; default: { zend_throw_exception_ex( spl_ce_RuntimeException, 0, "pthreads detected an attempt to use unsupported data (%s) for %s::$%s", zend_get_type_by_const(Z_TYPE_P(value)), ZSTR_VAL(Z_OBJCE_P(object)->name), Z_STRVAL_P(member)); } } }
static void swoole_corountine_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zend_bool use_array) { int i; zend_execute_data *call, *current_ex = EG(current_execute_data); zend_function *func = fci_cache->function_handler; zend_object *object = (func->common.fn_flags & ZEND_ACC_STATIC) ? NULL : fci_cache->object; #if ZEND_MODULE_API_NO < 20160303 zend_class_entry* origal_scope = EG(scope); call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION, func, fci->param_count, fci_cache->called_scope, object); EG(scope) = func->common.scope; #else call = zend_vm_stack_push_call_frame(ZEND_CALL_TOP_FUNCTION | ZEND_CALL_DYNAMIC, func, fci->param_count, fci_cache->called_scope, object); #endif for (i = 0; i < fci->param_count; ++i) { zval *target; target = ZEND_CALL_ARG(call, i + 1); ZVAL_COPY(target, &fci->params[i]); } call->symbol_table = NULL; zend_init_execute_data(call, &func->op_array, fci->retval); jmp_buf *prev_checkpoint = swReactorCheckPoint; swReactorCheckPoint = emalloc(sizeof(jmp_buf)); if (!setjmp(*swReactorCheckPoint)) { zend_execute_ex(call); efree(swReactorCheckPoint); swReactorCheckPoint = prev_checkpoint; #if ZEND_MODULE_API_NO < 20160303 EG(scope) = origal_scope; #endif } else { call->prev_execute_data = current_ex->prev_execute_data; #if ZEND_MODULE_API_NO < 20160303 ZEND_SET_CALL_INFO(call, ZEND_CALL_NESTED); #else ZEND_SET_CALL_INFO(call, object, ZEND_CALL_DYNAMIC|ZEND_CALL_NESTED); #endif efree(swReactorCheckPoint); swReactorCheckPoint = prev_checkpoint; if (use_array) { zend_fcall_info_args_clear(fci, 1); } zend_vm_stack_free_args(current_ex); longjmp(*swReactorCheckPoint, 1); } }
static PHP_METHOD(swoole_coroutine_util, call_user_func_array) { zval *params; zend_fcall_info fci; zend_fcall_info_cache fci_cache; ZEND_PARSE_PARAMETERS_START(2, 2) Z_PARAM_FUNC(fci, fci_cache) Z_PARAM_ARRAY_EX(params, 0, 1) ZEND_PARSE_PARAMETERS_END(); zend_fcall_info_args(&fci, params); fci.retval = (execute_data->prev_execute_data->opline->result_type != IS_UNUSED) ? return_value : NULL; swoole_corountine_call_function(&fci, &fci_cache, 1); zend_fcall_info_args_clear(&fci, 1); }
PHP_APCU_API void apc_cache_entry(apc_cache_t *cache, zval *key, zend_fcall_info *fci, zend_fcall_info_cache *fcc, zend_long ttl, zval *return_value) { apc_cache_entry_t *entry = NULL; if(!cache || apc_cache_busy(cache)) { return; } if (!key || Z_TYPE_P(key) != IS_STRING) { /* only strings, for now */ return; } #ifndef APC_LOCK_RECURSIVE if (APCG(recursion)++ == 0) { APC_LOCK(cache->header); } #else APC_LOCK(cache->header); #endif entry = apc_cache_find_internal( cache, Z_STR_P(key), ttl, 0); if (!entry) { int result = 0; fci->retval = return_value; zend_fcall_info_argn(fci, 1, key); zend_try { result = zend_call_function(fci, fcc); } zend_end_try (); if (result == SUCCESS) { zend_fcall_info_args_clear(fci, 1); if (!EG(exception)) { apc_cache_store_internal( cache, Z_STR_P(key), return_value, (uint32_t) ttl, 1); } } } else apc_cache_fetch_internal(cache, Z_STR_P(key), entry, ttl, &return_value);
/* {{{ */ int pthreads_has_property(PTHREADS_HAS_PROPERTY_PASSTHRU_D) { int isset = 0; zend_long *guard = NULL; pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object)); cache = NULL; if (Z_OBJCE_P(object)->__isset && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_ISSET)) { zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; zval rv; ZVAL_UNDEF(&rv); fci.size = sizeof(zend_fcall_info); fci.retval = &rv; fci.object = &threaded->std; zend_fcall_info_argn(&fci, 1, member); fcc.initialized = 1; fcc.function_handler = Z_OBJCE_P(object)->__isset; fcc.object = &threaded->std; (*guard) |= IN_ISSET; zend_call_function(&fci, &fcc); (*guard) &= ~IN_ISSET; if (Z_TYPE(rv) != IS_UNDEF) { isset = zend_is_true(&rv); zval_dtor(&rv); } zend_fcall_info_args_clear(&fci, 1); } else { isset = pthreads_store_isset(object, member, has_set_exists); } return isset; }
/* {{{ */ void pthreads_unset_property(PTHREADS_UNSET_PROPERTY_PASSTHRU_D) { zend_long *guard = NULL; pthreads_object_t* threaded = PTHREADS_FETCH_FROM(Z_OBJ_P(object)); cache = NULL; rebuild_object_properties(&threaded->std); if (Z_OBJCE_P(object)->__unset && (guard = pthreads_get_guard(&threaded->std, member)) && !((*guard) & IN_UNSET)) { zend_fcall_info fci = empty_fcall_info; zend_fcall_info_cache fcc = empty_fcall_info_cache; zval rv; ZVAL_UNDEF(&rv); fci.size = sizeof(zend_fcall_info); fci.retval = &rv; fci.object = &threaded->std; zend_fcall_info_argn(&fci, 1, member); fcc.initialized = 1; fcc.function_handler = Z_OBJCE_P(object)->__unset; fcc.object = &threaded->std; (*guard) |= IN_UNSET; zend_call_function(&fci, &fcc); (*guard) &= ~IN_UNSET; if (Z_TYPE(rv) != IS_UNDEF) { zval_dtor(&rv); } zend_fcall_info_args_clear(&fci, 1); } else { if (pthreads_store_delete(object, member) == SUCCESS){ } } }
static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_headers, struct curl_pushheaders *push_headers, void *userp) /* {{{ */ { php_curl *ch; php_curl *parent; php_curlm *mh = (php_curlm *)userp; size_t rval = CURL_PUSH_DENY; php_curlm_server_push *t = mh->handlers->server_push; zval *pz_parent_ch = NULL; zval pz_ch; zval headers; zval retval; zend_resource *res; char *header; int error; zend_fcall_info fci = empty_fcall_info; pz_parent_ch = _php_curl_multi_find_easy_handle(mh, parent_ch); if (pz_parent_ch == NULL) { return rval; } parent = (php_curl*)zend_fetch_resource(Z_RES_P(pz_parent_ch), le_curl_name, le_curl); ch = alloc_curl_handle(); ch->cp = easy; _php_setup_easy_copy_handlers(ch, parent); Z_ADDREF_P(pz_parent_ch); res = zend_register_resource(ch, le_curl); ZVAL_RES(&pz_ch, res); size_t i; array_init(&headers); for(i=0; i<num_headers; i++) { header = curl_pushheader_bynum(push_headers, i); add_next_index_string(&headers, header); } zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL); zend_fcall_info_argn( &fci, 3, pz_parent_ch, &pz_ch, &headers ); fci.retval = &retval; error = zend_call_function(&fci, &t->fci_cache); zend_fcall_info_args_clear(&fci, 1); zval_dtor(&headers); if (error == FAILURE) { php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION"); } else if (!Z_ISUNDEF(retval)) { if (CURL_PUSH_DENY != zval_get_long(&retval)) { rval = CURL_PUSH_OK; /* we want to create a copy of this zval that we store in the multihandle structure element "easyh" */ zval tmp_val; ZVAL_DUP(&tmp_val, &pz_ch); zend_llist_add_element(&mh->easyh, &tmp_val); } else { /* libcurl will free this easy handle, avoid double free */ ch->cp = NULL; } } return rval; }
static void php_midgard_closure_default_marshal(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data) { php_mgd_closure *mgdclosure = (php_mgd_closure *) closure; TSRMLS_FETCH(); if (MGDG(can_deliver_signals) == 0) return; // engine is not in sane state if (MGDG(midgard_memory_debug)) { printf("[%p] php_midgard_closure_default_marshal(args = %p)\n", closure, mgdclosure->args); } zval *params = NULL; MAKE_STD_ZVAL(params); array_init(params); // "10000" on next line is a HACK. Just took a number which is slightly above normal, but still doesn't look like invalid if (mgdclosure->zobject != NULL && Z_REFCOUNT_P(mgdclosure->zobject) < 10000) { if (MGDG(midgard_memory_debug)) { printf("[%p] ---> zobject (%p) refcount = %d\n", closure, mgdclosure->zobject, Z_REFCOUNT_P(mgdclosure->zobject)); } Z_ADDREF_P(mgdclosure->zobject); zend_hash_next_index_insert(Z_ARRVAL_P(params), &(mgdclosure->zobject), sizeof(zval *), NULL); } else { zval *dummy = NULL; MAKE_STD_ZVAL(dummy); ZVAL_NULL(dummy); zend_hash_next_index_insert(Z_ARRVAL_P(params), &dummy, sizeof(zval *), NULL); } if (mgdclosure->args != NULL) { // + params HashTable *args_hash = Z_ARRVAL_P(mgdclosure->args); zend_uint argc = 1 + zend_hash_num_elements(args_hash); zend_hash_internal_pointer_reset(args_hash); size_t i; for (i = 1; i < argc; i++) { zval **ptr; zend_hash_get_current_data(args_hash, (void **)&ptr); zend_hash_move_forward(args_hash); if (MGDG(midgard_memory_debug)) { printf("[%p] ----> got ptr = %p, *ptr = %p [refcount = %d]\n", closure, ptr, *ptr, Z_REFCOUNT_P(*ptr)); } Z_ADDREF_PP(ptr); zend_hash_next_index_insert(Z_ARRVAL_P(params), ptr, sizeof(zval *), NULL); } } zval *retval = NULL; zend_fcall_info_args(&(mgdclosure->fci), params TSRMLS_CC); mgdclosure->fci.retval_ptr_ptr = &retval; zend_call_function(&(mgdclosure->fci), &(mgdclosure->fci_cache) TSRMLS_CC); zend_fcall_info_args_clear(&(mgdclosure->fci), 1); if (retval) zval_ptr_dtor(&retval); zval_ptr_dtor(¶ms); }