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;
}
Beispiel #4
0
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");