ZEND_API int zend_get_parameters_array(int ht, int param_count, zval **argument_array) { void **p; int arg_count; zval *param_ptr; ELS_FETCH(); p = EG(argument_stack).top_element-2; arg_count = (ulong) *p; if (param_count>arg_count) { return FAILURE; } while (param_count-->0) { param_ptr = *(p-arg_count); if (!PZVAL_IS_REF(param_ptr) && param_ptr->refcount>1) { zval *new_tmp; ALLOC_ZVAL(new_tmp); *new_tmp = *param_ptr; zval_copy_ctor(new_tmp); INIT_PZVAL(new_tmp); param_ptr = new_tmp; ((zval *) *(p-arg_count))->refcount--; *(p-arg_count) = param_ptr; } *(argument_array++) = param_ptr; arg_count--; } return SUCCESS; }
ZEND_API int ParameterPassedByReference(int ht, uint n) { void **p; ulong arg_count; zval *arg; ELS_FETCH(); p = EG(argument_stack).elements+EG(argument_stack).top-2; arg_count = (ulong) *p; if (n>arg_count) { return FAILURE; } arg = (zval *) *(p-arg_count+n-1); return PZVAL_IS_REF(arg); }
/* this function doesn't check for too many parameters */ ZEND_API int zend_get_parameters(int ht, int param_count, ...) { void **p; int arg_count; va_list ptr; zval **param, *param_ptr; ELS_FETCH(); p = EG(argument_stack).top_element-2; arg_count = (ulong) *p; if (param_count>arg_count) { return FAILURE; } va_start(ptr, param_count); while (param_count-->0) { param = va_arg(ptr, zval **); param_ptr = *(p-arg_count); if (!PZVAL_IS_REF(param_ptr) && param_ptr->refcount>1) { zval *new_tmp; ALLOC_ZVAL(new_tmp); *new_tmp = *param_ptr; zval_copy_ctor(new_tmp); INIT_PZVAL(new_tmp); param_ptr = new_tmp; ((zval *) *(p-arg_count))->refcount--; *(p-arg_count) = param_ptr; } *param = param_ptr; arg_count--; } va_end(ptr); return SUCCESS; }
PHP_METHOD(air_view, render){ AIR_INIT_THIS; char *tpl_str; int tpl_len = 0; zend_bool ret_res = 0; if(zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sb", &tpl_str, &tpl_len, &ret_res) == FAILURE) { RETURN_FALSE; } smart_str ss_path = {0}; if(tpl_str[0] != '/'){ zval *root_path = NULL; MAKE_STD_ZVAL(root_path); if(zend_get_constant(ZEND_STRL("ROOT_PATH"), root_path) == FAILURE){ php_error_docref(NULL TSRMLS_CC, E_ERROR, "ROOT_PATH not defined"); } smart_str_appendl(&ss_path, Z_STRVAL_P(root_path), Z_STRLEN_P(root_path)); smart_str_appendc(&ss_path, '/'); if(root_path != NULL){ zval_ptr_dtor(&root_path); } zval *tmp = NULL; zval **tmp_pp; zval *config = zend_read_property(air_view_ce, getThis(), ZEND_STRL("_config"), 0 TSRMLS_CC); if(config != NULL && Z_TYPE_P(config) == IS_ARRAY && zend_hash_find(Z_ARRVAL_P(config), ZEND_STRL("path"), (void **)&tmp_pp) == SUCCESS){ smart_str_appendl(&ss_path, Z_STRVAL_PP(tmp_pp), Z_STRLEN_PP(tmp_pp)); }else{ zval *app_conf; zval *view_conf; if(air_config_get(NULL, ZEND_STRS("app"), &app_conf TSRMLS_CC) == FAILURE){ AIR_NEW_EXCEPTION(1, "@error config: app"); } zval *app_path = NULL; if(air_config_get(app_conf, ZEND_STRS("path"), &app_path) == FAILURE){ AIR_NEW_EXCEPTION(1, "@error config: app.path"); } zval *view_path = NULL; if(air_config_get_path(app_conf, ZEND_STRS("view.path"), &view_path) == FAILURE){ AIR_NEW_EXCEPTION(1, "@view config not found"); } smart_str_appendl(&ss_path, Z_STRVAL_P(app_path), Z_STRLEN_P(app_path)); smart_str_appendc(&ss_path, '/'); smart_str_appendl(&ss_path, Z_STRVAL_P(view_path), Z_STRLEN_P(view_path)); } smart_str_appendc(&ss_path, '/'); } smart_str_appendl(&ss_path, tpl_str, tpl_len); smart_str_0(&ss_path); //php_printf("full view path: %s\n", ss_path.c); //构造运行时所需基本变量 HashTable *origin_symbol_table = NULL; zval *output_handler = NULL; long chunk_size = 0; long flags = PHP_OUTPUT_HANDLER_STDFLAGS; zval *view_ret = NULL; //尝试缓存当前符号表 if(EG(active_symbol_table)){ origin_symbol_table = EG(active_symbol_table); } if (ret_res) { MAKE_STD_ZVAL(view_ret); if(php_output_start_user(output_handler, chunk_size, flags TSRMLS_CC) == FAILURE) { php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to create buffer"); RETURN_FALSE; } } ALLOC_HASHTABLE(EG(active_symbol_table)); zval *data = zend_read_property(air_view_ce, getThis(), ZEND_STRL("_data"), 0 TSRMLS_CC); zend_hash_init(EG(active_symbol_table), 0, NULL, ZVAL_PTR_DTOR, 0); //将当前的模板变量放到符号表去 ZEND_SET_SYMBOL_WITH_LENGTH(EG(active_symbol_table), "var", 4, data, Z_REFCOUNT_P(data) + 1, PZVAL_IS_REF(data)); if(air_loader_include_file(ss_path.c TSRMLS_CC) == FAILURE){ air_throw_exception_ex(1, "tpl %s render failed!\n", ss_path.c); return ; } if(ret_res){ php_output_get_contents(view_ret TSRMLS_CC); php_output_discard(TSRMLS_C); RETVAL_ZVAL(view_ret, 1, 0); zval_ptr_dtor(&view_ret); } zend_hash_destroy(EG(active_symbol_table)); FREE_HASHTABLE(EG(active_symbol_table)); EG(active_symbol_table) = origin_symbol_table; smart_str_free(&ss_path); }
static void swoole_corountine_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache, zval **return_value_ptr, zend_bool use_array, int return_value_used) { SWOOLE_GET_TSRMLS; int i; zval **origin_return_ptr_ptr; zend_op **origin_opline_ptr; zend_op_array *origin_active_op_array; zend_op_array *op_array = (zend_op_array *)fci_cache->function_handler; zend_execute_data *current = EG(current_execute_data); void **start, **end, **allocated_params, **old_arguments; if (use_array) { start = (void **)emalloc(sizeof(zval **) * (fci->param_count + 1)); allocated_params = start; end = start + fci->param_count; old_arguments = current->function_state.arguments; current->function_state.arguments = end; for (i = 0; i < fci->param_count; ++i) { *start = *fci->params[i]; ++start; } *start = (void*)(zend_uintptr_t)fci->param_count; } else { end = EG(argument_stack)->top - 1; start = end - (int)(zend_uintptr_t)(*end); zval_ptr_dtor((zval **)(start)); for (i = 0; i < fci->param_count; ++i) { *start = *(start + 1); ++start; } *start = (void*)(zend_uintptr_t)fci->param_count; EG(argument_stack)->top = start + 1; current->function_state.arguments = start; } origin_return_ptr_ptr = EG(return_value_ptr_ptr); if (current->opline->result_type & EXT_TYPE_UNUSED) { EG(return_value_ptr_ptr) = NULL; } else { EG(return_value_ptr_ptr) = return_value_ptr; } origin_active_op_array = EG(active_op_array); origin_opline_ptr = EG(opline_ptr); EG(active_op_array) = op_array; EG(active_symbol_table) = NULL; EG(scope) = fci_cache->calling_scope; if (fci_cache->called_scope) { EG(called_scope) = fci_cache->called_scope; } else { EG(called_scope) = NULL; } if (fci_cache->object_ptr) { EG(This) = fci_cache->object_ptr; if (!PZVAL_IS_REF(EG(This))) { Z_ADDREF_P(EG(This)); } else { zval *this_ptr; ALLOC_ZVAL(this_ptr); *this_ptr = *EG(This); INIT_PZVAL(this_ptr); zval_copy_ctor(this_ptr); EG(This) = this_ptr; } } else { EG(This) = NULL; } zend_execute_data *next = zend_create_execute_data_from_op_array(op_array, 0 TSRMLS_CC); jmp_buf *prev_checkpoint = swReactorCheckPoint; swReactorCheckPoint = emalloc(sizeof(jmp_buf)); if (!setjmp(*swReactorCheckPoint)) { zend_execute_ex(next TSRMLS_CC); if (fci->params) { efree(fci->params); if (use_array) { for (i = 0; i < fci->param_count; ++i) { zval *tmp = (zval *) *(--start); zval_ptr_dtor(&tmp); } efree(allocated_params); } } efree(swReactorCheckPoint); swReactorCheckPoint = prev_checkpoint; EG(active_op_array) = origin_active_op_array; EG(return_value_ptr_ptr) = origin_return_ptr_ptr; EG(opline_ptr) = origin_opline_ptr; } else { current->original_return_value = origin_return_ptr_ptr; next->nested = 1; efree(swReactorCheckPoint); swReactorCheckPoint = prev_checkpoint; if (!return_value_used && return_value_ptr) zval_ptr_dtor(return_value_ptr); if (fci->params) { efree(fci->params); if (use_array) { efree(allocated_params); current->function_state.arguments = old_arguments; } } longjmp(*swReactorCheckPoint, 1); } }
ZEND_BEGIN_ARG_INFO_EX(arginfo_protocolbuffers_helper_zigzag_encode64, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_protocolbuffers_helper_zigzag_decode64, 0, 0, 1) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() static void php_protocolbuffers_helper_debug_zval(zval **value TSRMLS_DC) { zval *val = *value; php_printf("{\n"); php_printf(" address: 0x%x,\n", (unsigned int)val); php_printf(" type: %d,\n", val->type); php_printf(" is_ref: %d,\n", PZVAL_IS_REF(val)); php_printf(" refcount: %d,\n", Z_REFCOUNT_PP(value)); php_printf(" value: {\n"); php_printf(" lval: %ld,\n", val->value.lval); php_printf(" double: %f,\n", val->value.dval); if (val->type == 4) { php_printf(" ht: {\n"); php_printf(" address: 0x%x,\n", (unsigned int)val->value.ht); php_printf(" num_of_elements: %d,\n", (unsigned int)val->value.ht->nNumOfElements); php_printf(" next_free_elements: %d,\n", (unsigned int)val->value.ht->nNextFreeElement); php_printf(" },\n"); } php_printf(" object: {\n"); php_printf(" handle: 0x%x,\n", val->value.obj.handle); php_printf(" handlers: 0x%x,\n", (unsigned int)val->value.obj.handlers); php_printf(" },\n");