Esempio n. 1
0
static UBool enumCharNames_callback(enumCharNames_data *context,
                                    UChar32 code, UCharNameChoice nameChoice,
                                    const char *name, int32_t length) {
	zval retval;
	zval args[3];

	ZVAL_NULL(&retval);
	ZVAL_LONG(&args[0], code);
	ZVAL_LONG(&args[1], nameChoice);
	ZVAL_STRINGL(&args[2], name, length);

	context->fci.retval = &retval;
	context->fci.param_count = 3;
	context->fci.params = args;

	if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) {
		intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR);
		intl_error_set_custom_msg(NULL, "enumCharNames callback failed", 0);
		zval_ptr_dtor(&retval);
		zval_ptr_dtor_str(&args[2]);
		return 0;
	}
	zval_ptr_dtor(&retval);
	zval_ptr_dtor_str(&args[2]);
	return 1;
}
Esempio n. 2
0
ZEND_RESULT_CODE php_http_object_method_call(php_http_object_method_t *cb, zval *zobject, zval *retval_ptr, int argc, zval *args)
{
	ZEND_RESULT_CODE rv;
	zval retval;

	ZVAL_UNDEF(&retval);
	Z_ADDREF_P(zobject);
	cb->fci.object = Z_OBJ_P(zobject);
	cb->fcc.object = Z_OBJ_P(zobject);

	cb->fci.retval = retval_ptr ? retval_ptr : &retval;

	cb->fci.param_count = argc;
	cb->fci.params = args;

	if (cb->fcc.called_scope != Z_OBJCE_P(zobject)) {
		cb->fcc.called_scope = Z_OBJCE_P(zobject);
		cb->fcc.function_handler = Z_OBJ_HT_P(zobject)->get_method(&Z_OBJ_P(zobject), Z_STR(cb->fci.function_name), NULL);
	}

	rv = zend_call_function(&cb->fci, &cb->fcc);

	zval_ptr_dtor(zobject);
	if (!retval_ptr && !Z_ISUNDEF(retval)) {
		zval_ptr_dtor(&retval);
	}

	return rv;
}
Esempio n. 3
0
static UBool enumCharType_callback(enumCharType_data *context,
                                   UChar32 start, UChar32 limit,
                                   UCharCategory type) {
	zval retval;
	zval args[3];

	ZVAL_NULL(&retval);
	/* Note that $start is INclusive, whiel $limit is EXclusive
	 * Therefore (0, 32, 15) means CPs 0..31 are of type 15
	 */
	ZVAL_LONG(&args[0], start);
	ZVAL_LONG(&args[1], limit);
	ZVAL_LONG(&args[2], type);

	context->fci.retval = &retval;
	context->fci.param_count = 3;
	context->fci.params = args;

	if (zend_call_function(&context->fci, &context->fci_cache) == FAILURE) {
		intl_error_set_code(NULL, U_INTERNAL_PROGRAM_ERROR);
		intl_errors_set_custom_msg(NULL, "enumCharTypes callback failed", 0);
		zval_dtor(&retval);
		return 0;
	}
	zval_dtor(&retval);
	return 1;
}
Esempio n. 4
0
static ZEND_NAMED_FUNCTION(zend_closure_call_magic) /* {{{ */ {
	zend_fcall_info fci;
	zend_fcall_info_cache fcc;
	zval params[2];

	memset(&fci, 0, sizeof(zend_fcall_info));
	memset(&fci, 0, sizeof(zend_fcall_info_cache));

	fci.size = sizeof(zend_fcall_info);
	fci.retval = return_value;

	fcc.initialized = 1;
	fcc.function_handler = (zend_function *) EX(func)->common.arg_info;
	fci.params = params;
	fci.param_count = 2;
	ZVAL_STR(&fci.params[0], EX(func)->common.function_name);
	array_init(&fci.params[1]);
	zend_copy_parameters_array(ZEND_NUM_ARGS(), &fci.params[1]);

	fci.object = Z_OBJ(EX(This));
	fcc.object = Z_OBJ(EX(This));
	fcc.calling_scope = zend_get_executed_scope();

	zend_call_function(&fci, &fcc);

	zval_ptr_dtor(&fci.params[0]);
	zval_ptr_dtor(&fci.params[1]);
}
Esempio n. 5
0
static void
glib_source_callback_helper(zval *retval, zval *source_zval, const char *name, zval *params, uint32_t param_count)
{
	zend_fcall_info fci;
	zend_fcall_info_cache fci_cache;
	zval caller;

	array_init(&caller);
	add_index_zval(&caller, 0, source_zval);
	add_index_string(&caller, 1, name);

	char * callback_error;
	if(FAILURE == zend_fcall_info_init(&caller, IS_CALLABLE_STRICT, &fci, &fci_cache, NULL, &callback_error))
	{
		zend_throw_exception_ex(spl_ce_BadMethodCallException, 0,
			"Could not call %s source handler, %s", name, callback_error);
		zval_dtor(&caller);
		return;
	}

	/* Handle arguments if necessary */
	fci.param_count = param_count;
	if(param_count > 0) {
		fci.params = params;
	}

	fci.retval = retval;
	if(FAILURE == zend_call_function(&fci, &fci_cache)) {
		zend_throw_exception_ex(spl_ce_BadFunctionCallException, 0,
			"Could not call %s source handler", name);
	}
	zval_dtor(&caller);
}
Esempio n. 6
0
/* {{{ */
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));
		}
	}
}
Esempio n. 7
0
int php_print_r_zval_and_key(zval **val,int num_args,va_list args,zend_hash_key *hash_key)
{
    //重新copy一个zval,防止破坏原数据
    zval tmpcopy = **val;
    zval *tmpcopy_ptr = &tmpcopy;
    
    /* tsrm_ls is needed by output functions */
    TSRMLS_FETCH();
    zval_copy_ctor(&tmpcopy);
    INIT_PZVAL(&tmpcopy);
    
    //执行输出
    php_printf("The value of ");
    if (hash_key->nKeyLength){
        //如果是字符串类型的key
        PHPWRITE(hash_key->arKey, hash_key->nKeyLength);
    }else{
        //如果是数字类型的key
        php_printf("%ld", hash_key->h);
    }
    
    php_printf(" is: ");
    
    //调用print_r函数
    zval *function,*ret = NULL;
    //函数名
    MAKE_STD_ZVAL(function);
    ZVAL_STRING(function, "print_r", 0);
    
    //参数是一个zval* 数组
    zval **params[1] = {&tmpcopy_ptr};
    
    zend_fcall_info fci = {
        sizeof(fci),
        EG(function_table),
        function,
        NULL,
        &ret,
        1,
        (zval ***)params,
        NULL,
        1
    };
    zend_call_function(&fci, NULL TSRMLS_CC);
    
    php_printf("\n");
    zval_dtor(function);
    
    //毁尸灭迹
    zval_dtor(&tmpcopy);
    /* continue; */
    return ZEND_HASH_APPLY_KEEP;
}
Esempio n. 8
0
/* {{{ proto mixed Closure::call(object $to [, mixed $parameter] [, mixed $...] )
   Call closure, binding to a given object with its class as the scope */
ZEND_METHOD(Closure, call)
{
	zval *zclosure, *newthis, closure_result;
	zend_closure *closure;
	zend_fcall_info fci;
	zend_fcall_info_cache fci_cache;
	zval *my_params;
	int my_param_count = 0;
	zend_function my_function;

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &my_params, &my_param_count) == FAILURE) {
		return;
	}

	zclosure = getThis();
	closure = (zend_closure *)Z_OBJ_P(zclosure);

	if (closure->func.common.fn_flags & ZEND_ACC_STATIC) {
		zend_error(E_WARNING, "Cannot bind an instance to a static closure");
		return;
	}

	if (closure->func.type == ZEND_INTERNAL_FUNCTION) {
		/* verify that we aren't binding internal function to a wrong object */
		if ((closure->func.common.fn_flags & ZEND_ACC_STATIC) == 0 &&
				!instanceof_function(Z_OBJCE_P(newthis), closure->func.common.scope)) {
			zend_error(E_WARNING, "Cannot bind function %s::%s to object of class %s", closure->func.common.scope->name->val, closure->func.common.function_name->val, Z_OBJCE_P(newthis)->name->val);
			return;
		}
	}

	/* This should never happen as closures will always be callable */
	if (zend_fcall_info_init(zclosure, 0, &fci, &fci_cache, NULL, NULL) != SUCCESS) {
		ZEND_ASSERT(0);
	}

	fci.retval = &closure_result;
	fci.params = my_params;
	fci.param_count = my_param_count;
	fci.object = fci_cache.object = Z_OBJ_P(newthis);
	fci_cache.initialized = 1;

	my_function = *fci_cache.function_handler;
	/* use scope of passed object */
	my_function.common.scope = Z_OBJCE_P(newthis);
	fci_cache.function_handler = &my_function;

	if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) {
		ZVAL_COPY_VALUE(return_value, &closure_result);
	}
}
Esempio n. 9
0
int static edge_register_autoload(zval *loader, const char *fname)
{
    zval *z_function;
    zval *arg;
    zval **args[1] = {&arg};
    zval *method;
    zval *ret = NULL;

    MAKE_STD_ZVAL(z_function);
    ZVAL_STRING(z_function, "spl_autoload_register", 0);
    
    MAKE_STD_ZVAL(method);
    ZVAL_STRING(method, fname, 1);

    MAKE_STD_ZVAL(arg);
    array_init(arg);

    zend_hash_next_index_insert(Z_ARRVAL_P(arg), &loader, sizeof(zval *), NULL);
    zend_hash_next_index_insert(Z_ARRVAL_P(arg), &method, sizeof(zval *), NULL);
    
    zend_fcall_info fci = { 
        sizeof(fci),
        EG(function_table),
        z_function,
        NULL,
        &ret,
        1,  
        (zval ***)args,
        NULL,
        1   
    }; 

    if(zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE)
    {
        if(ret)
        {
            zval_ptr_dtor(&ret);
        }
        zval_ptr_dtor(&z_function);   
        zval_ptr_dtor(&arg);
        return 0;
    }
    if(ret)
    {
        zval_ptr_dtor(&ret);
    }
    Z_ADDREF_P(loader);
    efree(z_function);   
    zval_ptr_dtor(&arg);
    return 1;
}
Esempio n. 10
0
zval * util_array_map_deep(zval* arr, zend_fcall_info* fci, zend_fcall_info_cache* fci_cache, zend_bool on_nonscalar) {
	zval *result, **zvalue;
	char *key;
	uint keylen;
	ulong idx;
	int type, value_type;
	HashTable* arr_hash;
	HashPosition pointer;
	zval **args[1];
	zval **arr_value;
	MAKE_STD_ZVAL(result);
	array_init(result);
	TSRMLS_FETCH();

	// Copy a temp array
	zval temp;
	temp = *arr;
	zval_copy_ctor(&temp);

	arr_hash = Z_ARRVAL_P(&temp);
	zend_hash_internal_pointer_reset_ex(arr_hash, &pointer);
	while (zend_hash_get_current_data_ex(arr_hash, (void**) &zvalue, &pointer) == SUCCESS) {
		type = zend_hash_get_current_key_ex(arr_hash, &key, &keylen, &idx, 0, &pointer);
		value_type = Z_TYPE_P(*zvalue);
		if (value_type == IS_ARRAY) {
			if (type == HASH_KEY_IS_LONG) {
				add_index_zval(result, idx, util_array_map_deep(*zvalue, fci, fci_cache, on_nonscalar));
			} else {
				add_assoc_zval(result, key, util_array_map_deep(*zvalue, fci, fci_cache, on_nonscalar));
			}
		} else if (value_type == IS_BOOL || value_type == IS_LONG || value_type == IS_DOUBLE || value_type == IS_STRING || on_nonscalar) {
			zval *retval_ptr = NULL;
			args[0] = zvalue;
			(*fci).retval_ptr_ptr = &retval_ptr;
			(*fci).params = args;
			if (zend_call_function(fci, fci_cache TSRMLS_CC) == SUCCESS && retval_ptr) {
				if (type == HASH_KEY_IS_LONG) {
					add_index_zval(result, idx, retval_ptr);
				} else {
					add_assoc_zval(result, key, retval_ptr);
				}
			}
		}
		zend_hash_move_forward_ex(arr_hash, &pointer);
	}
	return result;
}
Esempio n. 11
0
VALUE php_value_call(int argc, VALUE *argv, VALUE self) {
    char *is_callable_error;
    zend_fcall_info fci;
    zend_fcall_info_cache fcc;
    zval ***call_args;
    zval **zval_array;
    zval *retval_ptr = NULL;
    int i, call_result;
    VALUE args, retval;

    rb_scan_args(argc, argv, "*", &args);

    if (zend_fcall_info_init(get_zval(self), 0, &fci, &fcc, NULL, &is_callable_error TSRMLS_CC) == FAILURE) {
        VALUE err = rb_str_new2(is_callable_error);
        efree(is_callable_error);
        rb_raise(rb_eRuntimeError, "no callable: %s", err);
    }

    zval_array = (zval**)malloc(sizeof(zval*) * argc);
    call_args = (zval***)malloc(sizeof(zval**) * argc);
    for(i=0; i<argc; ++i) {
        zval_array[i] = value_to_zval(RARRAY_PTR(args)[i]);
        call_args[i] = &zval_array[i];
    }

    fci.retval_ptr_ptr = &retval_ptr;
    fci.param_count = argc;
    fci.params = call_args;

    call_result = zend_call_function(&fci, &fcc TSRMLS_CC);
    retval = new_php_embed_value(retval_ptr);

    free(call_args);

    for(i=0; i<argc-1; ++i) {
        zval_dtor(zval_array[i]);
        FREE_ZVAL(zval_array[i]);
    }
    free(zval_array);

    if (FAILURE == call_result) {
        rb_raise(rb_eRuntimeError, "function call fairure");
    }

    return retval;
}
Esempio n. 12
0
/* {{{ proto lmDB\\Env::tnx_begin(parent, flags)
  Create a transaction for use with the environment. */
PHP_METHOD(lmdb_env, tnx_begin)
{
	printf("lmdb_env,tnx_begin\n");
	zval *zptr = 0;
	zval **params[3];
	zval z_fname;
	ZVAL_STRING(&z_fname, "__construct",1);
	long p_flags = 0;
	unsigned int flags = 0;
	zend_fcall_info fci;

	lmdb_txn_object * txn;
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!l", &zptr, &p_flags) == FAILURE) {
                return;
        }

	params[0] = &getThis();
	if(zptr == NULL) printf("NULL...***\n");
	params[1] = &zptr;
	//flags = (unsigned int) p_flags;
	//ZVAL_LONG(params[2], p_flags);

	object_init_ex(return_value, php_lmdb_txn_class_entry);

	fci.size = sizeof(fci);
        fci.function_table = php_lmdb_txn_class_entry;
        fci.object_ptr = return_value;
        fci.function_name = &z_fname;
        fci.retval_ptr_ptr = &return_value;
        fci.param_count = 2;
	fci.params = params;

        fci.no_separation = 1;
        fci.symbol_table = NULL;

	if(zend_call_function(&fci, NULL TSRMLS_CC) == FAILURE){
		//TODO: throw a new Exception
		printf("Error .... \n");
	}else{
		printf("OK! .... \n");
	}

	//TODO : return the function's result or throw an exception if return non-zero.
}
Esempio n. 13
0
static int php_sqlite3_collation_callback(void *context,
	int string1_len, const void *string1,
	int string2_len, const void *string2)
{
	int ret;
	zval zargs[2];
	zval retval;
	struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;

	collation->fc.fci.size = sizeof(collation->fc.fci);
	collation->fc.fci.function_table = EG(function_table);
	ZVAL_COPY_VALUE(&collation->fc.fci.function_name, &collation->callback);
	collation->fc.fci.symbol_table = NULL;
	collation->fc.fci.object = NULL;
	collation->fc.fci.retval = &retval;

	// Prepare the arguments.
	ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
	ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
	collation->fc.fci.param_count = 2;
	collation->fc.fci.params = zargs;

	if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc)) == FAILURE) {
		php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
	} else if (!Z_ISUNDEF(retval)) {
		if (Z_TYPE(retval) != IS_LONG) {
			convert_to_long_ex(&retval);
		}
		ret = 0;
		if (Z_LVAL(retval) > 0) {
			ret = 1;
		} else if (Z_LVAL(retval) < 0) {
			ret = -1;
		}
		zval_ptr_dtor(&retval);
	}

	zval_ptr_dtor(&zargs[0]);
	zval_ptr_dtor(&zargs[1]);

	return ret;
}
Esempio n. 14
0
int yaf_loader_register(yaf_loader_t *loader) /* {{{ */ {
	zval autoload, function, method, ret;

	array_init(&autoload);

    ZVAL_STRING(&method, YAF_AUTOLOAD_FUNC_NAME);
	zend_hash_next_index_insert(Z_ARRVAL(autoload), loader);
	zend_hash_next_index_insert(Z_ARRVAL(autoload), &method);

	ZVAL_STRING(&function, YAF_SPL_AUTOLOAD_REGISTER_NAME);

	do {
		zend_fcall_info fci = {
			sizeof(fci),
#if PHP_VERSION_ID < 70100
			EG(function_table),
#endif
			function,
#if PHP_VERSION_ID < 70100
			NULL,
#endif
			&ret,
			&autoload,
			NULL,
			1,
			1
		};

		if (zend_call_function(&fci, NULL) == FAILURE) {
			zval_ptr_dtor(&function);
			zval_ptr_dtor(&autoload);
			php_error_docref(NULL,
					E_WARNING,
					"Unable to register autoload function %s",
					YAF_AUTOLOAD_FUNC_NAME);
			return 0;
		}
		zval_ptr_dtor(&function);
		zval_ptr_dtor(&autoload);
	} while (0);
	return 1;
}
Esempio n. 15
0
/* {{{ wingdi_window_construction_wrapper
       wraps around the constructor to make sure parent::__construct is always called  */
static void wingdi_window_construction_wrapper(INTERNAL_FUNCTION_PARAMETERS) {
    zval *this = getThis();
    wingdi_window_object *tobj;
    zend_class_entry *this_ce;
    zend_function *zf;
    zend_fcall_info fci = {0};
    zend_fcall_info_cache fci_cache = {0};
    zval *retval_ptr = NULL;
    unsigned i;
 
    tobj = zend_object_store_get_object(this TSRMLS_CC);
    zf = zend_get_std_object_handlers()->get_constructor(this TSRMLS_CC);
    this_ce = Z_OBJCE_P(this);
 
    fci.size = sizeof(fci);
    fci.function_table = &this_ce->function_table;
    fci.object_ptr = this;
    /* fci.function_name = ; not necessary to bother */
    fci.retval_ptr_ptr = &retval_ptr;
    fci.param_count = ZEND_NUM_ARGS();
    fci.params = emalloc(fci.param_count * sizeof *fci.params);
    /* Or use _zend_get_parameters_array_ex instead of loop: */
    for (i = 0; i < fci.param_count; i++) {
        fci.params[i] = (zval **) (zend_vm_stack_top(TSRMLS_C) - 1 -
            (fci.param_count - i));
    }
    fci.object_ptr = this;
    fci.no_separation = 0;
 
    fci_cache.initialized = 1;
    fci_cache.called_scope = EG(current_execute_data)->called_scope;
    fci_cache.calling_scope = EG(current_execute_data)->current_scope;
    fci_cache.function_handler = zf;
    fci_cache.object_ptr = this;
 
    zend_call_function(&fci, &fci_cache TSRMLS_CC);
    if (!EG(exception) && tobj->is_constructed == 0)
		zend_throw_exception_ex(NULL, 0 TSRMLS_CC,
			"parent::__construct() must be called in %s::__construct()", this_ce->name);
    efree(fci.params);
    zval_ptr_dtor(&retval_ptr);
}
Esempio n. 16
0
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);
Esempio n. 17
0
static void oop_indirection_func(INTERNAL_FUNCTION_PARAMETERS)
{
    indirection_function *ind = (indirection_function *) execute_data->func;
    zval *obj = &ind->obj;
    zval *params = safe_emalloc(sizeof(zval), ZEND_NUM_ARGS() + 1, 0);
    zval result;

    zend_class_entry *ce = ind->fn.scope;
    zend_fcall_info fci;
    zend_fcall_info_cache fcc;

    fci.size = sizeof(fci);
    fci.param_count = ZEND_NUM_ARGS() + 1;
    fci.params = params;
    fci.no_separation = 1;

    fcc.initialized = 1;
    fcc.calling_scope = ce;
    fcc.function_handler = ind->fbc;

    zend_get_parameters_array_ex(ZEND_NUM_ARGS(), &params[1]);

    ZVAL_COPY_VALUE(&params[0], obj);
    ZVAL_STR(&fci.function_name, ind->fn.function_name);
    fci.retval = &result;
    fci.object = NULL;

    fcc.object = NULL;
    fcc.called_scope = ce;

    if (zend_call_function(&fci, &fcc TSRMLS_CC) == SUCCESS && !Z_ISUNDEF(result)) {
        ZVAL_COPY_VALUE(return_value, &result);
    }
    zval_ptr_dtor(obj);
    execute_data->func = NULL;

    zval_ptr_dtor(&fci.function_name);
    efree(params);
    efree(ind);
}
Esempio n. 18
0
/* {{{ xml_call_handler() */
static void xml_call_handler(xml_parser *parser, zval *handler, zend_function *function_ptr, int argc, zval *argv, zval *retval)
{
	int i;	

	ZVAL_UNDEF(retval);
	if (parser && handler && !EG(exception)) {
		int result;
		zend_fcall_info fci;

		fci.size = sizeof(fci);
		fci.function_table = EG(function_table);
		ZVAL_COPY_VALUE(&fci.function_name, handler);
		fci.symbol_table = NULL;
		fci.object = Z_OBJ(parser->object);
		fci.retval = retval;
		fci.param_count = argc;
		fci.params = argv;
		fci.no_separation = 0;
		/*fci.function_handler_cache = &function_ptr;*/

		result = zend_call_function(&fci, NULL);
		if (result == FAILURE) {
			zval *method;
			zval *obj;

			if (Z_TYPE_P(handler) == IS_STRING) {
				php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL_P(handler));
			} else if ((obj = zend_hash_index_find(Z_ARRVAL_P(handler), 0)) != NULL &&
					   (method = zend_hash_index_find(Z_ARRVAL_P(handler), 1)) != NULL &&
					   Z_TYPE_P(obj) == IS_OBJECT &&
					   Z_TYPE_P(method) == IS_STRING) {
				php_error_docref(NULL, E_WARNING, "Unable to call handler %s::%s()", Z_OBJCE_P(obj)->name->val, Z_STRVAL_P(method));
			} else 
				php_error_docref(NULL, E_WARNING, "Unable to call handler");
		}
	} 
	for (i = 0; i < argc; i++) {
		zval_ptr_dtor(&argv[i]);
	}
}
Esempio n. 19
0
/* {{{ */
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;
}
Esempio n. 20
0
ZEND_METHOD(myclass_ce, call_self){
    zval *this,*ret = NULL;
    this = getThis();
    
    zval *function_name;
//    //函数名
    MAKE_STD_ZVAL(function_name);
    ZVAL_STRING(function_name, "public_method", 1);
    
    zend_fcall_info fci;
//    zend_fcall_info fci = {
//        sizeof(fci),
//        &Z_OBJCE_P(this)->function_table,
//        function_name,
//        NULL,
//        &ret,
//        0,
//        NULL,
//        this,
//        1
//    };
    
    fci.size =sizeof(fci);
    fci.function_table = &Z_OBJCE_P(this)->function_table;
    fci.function_name = function_name;
    fci.symbol_table = NULL;
    fci.retval_ptr_ptr = &ret;
    fci.param_count = 0;
    fci.params = NULL;
    fci.object_ptr = this;
    fci.no_separation =1;
    
    zend_call_function(&fci, NULL TSRMLS_CC);
    
    zval_dtor(function_name);
    efree(function_name);
    efree(ret);
}
Esempio n. 21
0
void call_user_watch_callback(int watch_index)
{
    Watch *watch_ret;

    watch_ret = &FSEVENTS_GLOBAL(watches)[watch_index];

    zval *retval = NULL;
    zval params[1];
    zval *event_array;

    ZVAL_NEW_ARR(retval);
    ZVAL_NEW_ARR(event_array);
    array_init(event_array);

    params[0] = *event_array;

    watch_ret->fci.params         = params;
    watch_ret->fci.param_count    = 1;
    watch_ret->fci.retval         = retval;
    watch_ret->fci.no_separation  = 0;

    zend_call_function(&watch_ret->fci, NULL TSRMLS_CC);
}
Esempio n. 22
0
PHP_METHOD(Searcher,search)
{
	char *str = NULL;
	int str_len,level;
	zval *cvalue, *self ,*retval_ptr,*arg1,*arg2,*arg3,*arg4;
	zval **params[4];
	zend_fcall_info callback;
    	zend_fcall_info_cache callback_cache;
	void* c = NULL;
	long ret = 0;
 
	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl|f", &str,&str_len, &level,&callback,&callback_cache, &callback.params, &callback.param_count) == FAILURE) {
		WRONG_PARAM_COUNT;
	}
 	
//if(Z_TYPE_P(rulefile_zval) != IS_NULL){}
	callback.retval_ptr_ptr = &retval_ptr;
 
    	
 	

void callback_embed(unsigned char* s,int start,int end,int level){
	MAKE_STD_ZVAL(arg1);
	ZVAL_STRING(arg1, s, strlen(s));
	params[0] = &arg1;
	MAKE_STD_ZVAL(arg2);
	ZVAL_LONG(arg2, start);
	params[0] = &arg2;
	MAKE_STD_ZVAL(arg3);
	ZVAL_LONG(arg3, end);
	params[0] = &arg3;
	MAKE_STD_ZVAL(arg4);
	ZVAL_LONG(arg4,level);
	params[0] = &arg4;
	callback.params = params;
	zend_call_function(&callback, &callback_cache TSRMLS_CC);
}
Esempio n. 23
0
/* {{{ */
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){
			
		}
	}
}
Esempio n. 24
0
static int ds_zval_user_compare_func(const void *a, const void *b)
{
    zval params[2];
    zval retval;

    zval *x = (zval*) a;
    zval *y = (zval*) b;

    ZVAL_COPY_VALUE(&params[0], x);
    ZVAL_COPY_VALUE(&params[1], y);

    DSG(user_compare_fci).param_count = 2;
    DSG(user_compare_fci).params      = params;
    DSG(user_compare_fci).retval      = &retval;

    if (zend_call_function(
            &DSG(user_compare_fci),
            &DSG(user_compare_fci_cache)) == SUCCESS) {

        return (int) zval_get_long(&retval);
    }

    return 0;
}
Esempio n. 25
0
int msgpack_convert_object(zval *return_value, zval *tpl, zval **value)
{
    zend_class_entry *ce, **pce;
    TSRMLS_FETCH();

    switch (Z_TYPE_P(tpl))
    {
        case IS_STRING:
            if (zend_lookup_class(
                    Z_STRVAL_P(tpl), Z_STRLEN_P(tpl),
                    &pce TSRMLS_CC) != SUCCESS)
            {
                MSGPACK_ERROR("[msgpack] (%s) Class '%s' not found",
                              __FUNCTION__, Z_STRVAL_P(tpl));
                return FAILURE;
            }
            ce = *pce;
            break;
        case IS_OBJECT:
            ce = zend_get_class_entry(tpl TSRMLS_CC);
            break;
        default:
            MSGPACK_ERROR("[msgpack] (%s) object type is unsupported",
                          __FUNCTION__);
            return FAILURE;
    }

    if (Z_TYPE_PP(value) == IS_OBJECT)
    {
        zend_class_entry *vce;

        vce = zend_get_class_entry(*value TSRMLS_CC);
        if (strcmp(ce->name, vce->name) == 0)
        {
            *return_value = **value;
            zval_copy_ctor(return_value);
            zval_ptr_dtor(value);
            return SUCCESS;
        }
    }

    object_init_ex(return_value, ce);

    /* Run the constructor if there is one */
    if (ce->constructor
        && (ce->constructor->common.fn_flags & ZEND_ACC_PUBLIC))
    {
        zval *retval_ptr = NULL;
        zval ***params = NULL;
        int num_args = 0;
        zend_fcall_info fci;
        zend_fcall_info_cache fcc;

#if ZEND_MODULE_API_NO >= 20090626
        fci.size = sizeof(fci);
        fci.function_table = EG(function_table);
        fci.function_name = NULL;
        fci.symbol_table = NULL;
        fci.object_ptr = return_value;
        fci.retval_ptr_ptr = &retval_ptr;
        fci.param_count = num_args;
        fci.params = params;
        fci.no_separation = 1;

        fcc.initialized = 1;
        fcc.function_handler = ce->constructor;
        fcc.calling_scope = EG(scope);
        fcc.called_scope = Z_OBJCE_P(return_value);
        fcc.object_ptr = return_value;
#else
        fci.size = sizeof(fci);
        fci.function_table = EG(function_table);
        fci.function_name = NULL;
        fci.symbol_table = NULL;
        fci.object_pp = &return_value;
        fci.retval_ptr_ptr = &retval_ptr;
        fci.param_count = num_args;
        fci.params = params;
        fci.no_separation = 1;

        fcc.initialized = 1;
        fcc.function_handler = ce->constructor;
        fcc.calling_scope = EG(scope);
        fcc.object_pp = &return_value;
#endif

        if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE)
        {
            if (params)
            {
                efree(params);
            }
            if (retval_ptr)
            {
                zval_ptr_dtor(&retval_ptr);
            }

            MSGPACK_WARNING(
                "[msgpack] (%s) Invocation of %s's constructor failed",
                __FUNCTION__, ce->name);

            return FAILURE;
        }
        if (retval_ptr)
        {
            zval_ptr_dtor(&retval_ptr);
        }
        if (params)
        {
            efree(params);
        }
    }

    switch (Z_TYPE_PP(value))
    {
        case IS_ARRAY:
        {
            char *key;
            uint key_len;
            int key_type;
            ulong key_index;
            zval **data;
            HashPosition pos;
            HashTable *ht, *ret;
            HashTable *var = NULL;
            int num;

            ht = HASH_OF(*value);
            ret = HASH_OF(return_value);

            num = zend_hash_num_elements(ht);
            if (num <= 0)
            {
                zval_ptr_dtor(value);
                break;
            }

            /* string - php_only mode? */
            if (ht->nNumOfElements != ht->nNextFreeElement
                || ht->nNumOfElements != ret->nNumOfElements)
            {
                HashTable *properties = NULL;
                HashPosition prop_pos;

                ALLOC_HASHTABLE(var);
                zend_hash_init(var, num, NULL, NULL, 0);

                zend_hash_internal_pointer_reset_ex(ht, &pos);
                for (;; zend_hash_move_forward_ex(ht, &pos))
                {
                    key_type = zend_hash_get_current_key_ex(
                        ht, &key, &key_len, &key_index, 0, &pos);

                    if (key_type == HASH_KEY_NON_EXISTANT)
                    {
                        break;
                    }

                    if (zend_hash_get_current_data_ex(
                            ht, (void *)&data, &pos) != SUCCESS)
                    {
                        continue;
                    }

                    if (key_type == HASH_KEY_IS_STRING)
                    {
                        zval *val;
                        MSGPACK_CONVERT_COPY_ZVAL(val, data);
                        if (msgpack_convert_string_to_properties(
                                return_value, key, key_len, val, var) != SUCCESS)
                        {
                            zval_ptr_dtor(&val);
                            MSGPACK_WARNING(
                                "[msgpack] (%s) "
                                "illegal offset type, skip this decoding",
                                __FUNCTION__);
                        }
                    }
                }

                /* index */
                properties = Z_OBJ_HT_P(return_value)->get_properties(
                    return_value TSRMLS_CC);

                if (HASH_OF(tpl))
                {
                    properties = HASH_OF(tpl);
                }
                zend_hash_internal_pointer_reset_ex(properties, &prop_pos);

                zend_hash_internal_pointer_reset_ex(ht, &pos);
                for (;; zend_hash_move_forward_ex(ht, &pos))
                {
                    key_type = zend_hash_get_current_key_ex(
                        ht, &key, &key_len, &key_index, 0, &pos);

                    if (key_type == HASH_KEY_NON_EXISTANT)
                    {
                        break;
                    }

                    if (zend_hash_get_current_data_ex(
                            ht, (void *)&data, &pos) != SUCCESS)
                    {
                        continue;
                    }

                    switch (key_type)
                    {
                        case HASH_KEY_IS_LONG:
                        {
                            zval *val;
                            MSGPACK_CONVERT_COPY_ZVAL(val, data);
                            if (msgpack_convert_long_to_properties(
                                    ret, &properties, &prop_pos,
                                    key_index, val, var) != SUCCESS)
                            {
                                zval_ptr_dtor(&val);
                                MSGPACK_WARNING(
                                    "[msgpack] (%s) "
                                    "illegal offset type, skip this decoding",
                                    __FUNCTION__);
                            }
                            break;
                        }
                        case HASH_KEY_IS_STRING:
                            break;
                        default:
                            MSGPACK_WARNING(
                                "[msgpack] (%s) key is not string nor array",
                                __FUNCTION__);
                            break;
                    }
                }

                zend_hash_destroy(var);
                FREE_HASHTABLE(var);
            }
            else
            {
                HashPosition valpos;
                int (*convert_function)(zval *, zval *, zval **) = NULL;
                zval **arydata, *aryval;

                /* index */
                zend_hash_internal_pointer_reset_ex(ret, &pos);
                zend_hash_internal_pointer_reset_ex(ht, &valpos);
                for (;; zend_hash_move_forward_ex(ret, &pos),
                        zend_hash_move_forward_ex(ht, &valpos))
                {
                    key_type = zend_hash_get_current_key_ex(
                        ret, &key, &key_len, &key_index, 0, &pos);

                    if (key_type == HASH_KEY_NON_EXISTANT)
                    {
                        break;
                    }

                    if (zend_hash_get_current_data_ex(
                            ret, (void *)&data, &pos) != SUCCESS)
                    {
                        continue;
                    }

                    switch (Z_TYPE_PP(data))
                    {
                        case IS_ARRAY:
                            convert_function = msgpack_convert_array;
                            break;
                        case IS_OBJECT:
                        //case IS_STRING: -- may have default values of
                        // class members, so it's not wise to allow
                            convert_function = msgpack_convert_object;
                            break;
                        default:
                            break;
                    }

                    if (zend_hash_get_current_data_ex(
                            ht, (void *)&arydata, &valpos) != SUCCESS)
                    {
                        MSGPACK_WARNING(
                            "[msgpack] (%s) can't get data value by index",
                            __FUNCTION__);
                        return FAILURE;
                    }

                    MSGPACK_CONVERT_COPY_ZVAL(aryval, arydata);

                    if (convert_function)
                    {
                        zval *rv;
                        ALLOC_INIT_ZVAL(rv);

                        if (convert_function(rv, *data, &aryval) != SUCCESS)
                        {
                            zval_ptr_dtor(&aryval);
                            MSGPACK_WARNING(
                                "[msgpack] (%s) "
                                "convert failure in convert_object",
                                __FUNCTION__);
                            return FAILURE;
                        }

                        zend_symtable_update(
                            ret, key, key_len, &rv, sizeof(rv), NULL);
                    }
                    else
                    {
                        zend_symtable_update(
                            ret, key, key_len, &aryval, sizeof(aryval), NULL);
                    }
                }
            }

            zval_ptr_dtor(value);
            break;
        }
        default:
        {
            HashTable *properties = NULL;
            HashPosition prop_pos;

            properties = Z_OBJ_HT_P(return_value)->get_properties(
                return_value TSRMLS_CC);
            zend_hash_internal_pointer_reset_ex(properties, &prop_pos);

            if (msgpack_convert_long_to_properties(
                    HASH_OF(return_value), &properties, &prop_pos,
                    0, *value, NULL) != SUCCESS)
            {
                MSGPACK_WARNING(
                    "[msgpack] (%s) illegal offset type, skip this decoding",
                    __FUNCTION__);
            }
            break;
        }
    }

    return SUCCESS;
}
Esempio n. 26
0
/* {{{ proto mixed Closure::call(object to [, mixed parameter] [, mixed ...] )
   Call closure, binding to a given object with its class as the scope */
ZEND_METHOD(Closure, call)
{
	zval *zclosure, *newthis, closure_result;
	zend_closure *closure;
	zend_fcall_info fci;
	zend_fcall_info_cache fci_cache;
	zend_function my_function;
	zend_object *newobj;

	fci.param_count = 0;
	fci.params = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &fci.params, &fci.param_count) == FAILURE) {
		return;
	}

	zclosure = getThis();
	closure = (zend_closure *) Z_OBJ_P(zclosure);

	newobj = Z_OBJ_P(newthis);

	if (!zend_valid_closure_binding(closure, newthis, Z_OBJCE_P(newthis))) {
		return;
	}

	if (closure->func.common.fn_flags & ZEND_ACC_GENERATOR) {
		zval new_closure;
		zend_create_closure(&new_closure, &closure->func, Z_OBJCE_P(newthis), closure->called_scope, newthis);
		closure = (zend_closure *) Z_OBJ(new_closure);
		fci_cache.function_handler = &closure->func;
	} else {
		memcpy(&my_function, &closure->func, closure->func.type == ZEND_USER_FUNCTION ? sizeof(zend_op_array) : sizeof(zend_internal_function));
		my_function.common.fn_flags &= ~ZEND_ACC_CLOSURE;
		/* use scope of passed object */
		my_function.common.scope = Z_OBJCE_P(newthis);
		fci_cache.function_handler = &my_function;

		/* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */
		if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) {
			my_function.op_array.run_time_cache = emalloc(my_function.op_array.cache_size);
			memset(my_function.op_array.run_time_cache, 0, my_function.op_array.cache_size);
		}
	}

	fci_cache.called_scope = newobj->ce;
	fci_cache.object = fci.object = newobj;

	fci.size = sizeof(fci);
	ZVAL_COPY_VALUE(&fci.function_name, zclosure);
	fci.retval = &closure_result;
	fci.no_separation = 1;

	if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) {
		if (Z_ISREF(closure_result)) {
			zend_unwrap_reference(&closure_result);
		}
		ZVAL_COPY_VALUE(return_value, &closure_result);
	}

	if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) {
		/* copied upon generator creation */
		GC_DELREF(&closure->std);
	} else if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) {
		efree(my_function.op_array.run_time_cache);
	}
}
Esempio n. 27
0
static void xsl_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	xsltTransformContextPtr tctxt;
	zval *args;
	zval retval;
	int result, i;
	int error = 0;
	zend_fcall_info fci;
	zval handler;
	xmlXPathObjectPtr obj;
	char *str;
	xsl_object *intern;
	zend_string *callable = NULL;


	if (! zend_is_executing()) {
		xsltGenericError(xsltGenericErrorContext,
		"xsltExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		tctxt = xsltXPathGetTransformContext(ctxt);
		if (tctxt == NULL) {
			xsltGenericError(xsltGenericErrorContext,
			"xsltExtFunctionTest: failed to get the transformation context\n");
			error = 1;
		} else {
			intern = (xsl_object*)tctxt->_private;
			if (intern == NULL) {
				xsltGenericError(xsltGenericErrorContext,
				"xsltExtFunctionTest: failed to get the internal object\n");
				error = 1;
			}
			else if (intern->registerPhpFunctions == 0) {
				xsltGenericError(xsltGenericErrorContext,
				"xsltExtFunctionTest: PHP Object did not register PHP functions\n");
				error = 1;
			}
		}
	}

	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}

	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		args = safe_emalloc(fci.param_count, sizeof(zval), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(&args[i], (char *)obj->stringval);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(&args[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(&args[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char*)xmlXPathCastToString(obj);
					ZVAL_STRING(&args[i], str);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					dom_object *domintern = (dom_object *)intern->doc;
					array_init(&args[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval child;
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;

								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((char *)node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (char *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (const xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							} else {
								node = xmlDocCopyNodeList(domintern->document->ptr, node);
							}

							php_dom_create_object(node, &child, domintern);
							add_next_index_zval(&args[i], &child);
						}
					}
				}
				break;
			default:
				str = (char *) xmlXPathCastToString(obj);
				ZVAL_STRING(&args[i], str);
				xmlFree(str);
		}
		xmlXPathFreeObject(obj);
	}

	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);
	if (fci.param_count > 0) {
		fci.params = args;
	} else {
		fci.params = NULL;
	}


	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&args[i]);
			}
			efree(args);
		}
		return;
	}
	ZVAL_STRING(&handler, (char *) obj->stringval);
	xmlXPathFreeObject(obj);

	ZVAL_COPY_VALUE(&fci.function_name, &handler);
	fci.symbol_table = NULL;
	fci.object = NULL;
	fci.retval = &retval;
	fci.no_separation = 0;
	/*fci.function_handler_cache = &function_ptr;*/
	if (!zend_make_callable(&handler, &callable)) {
		php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", ZSTR_VAL(callable));
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
	} else if ( intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) {
		php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'", ZSTR_VAL(callable));
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
	} else {
		result = zend_call_function(&fci, NULL);
		if (result == FAILURE) {
			if (Z_TYPE(handler) == IS_STRING) {
				php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", Z_STRVAL(handler));
				valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
			}
		/* retval is == NULL, when an exception occurred, don't report anything, because PHP itself will handle that */
		} else if (Z_ISUNDEF(retval)) {
		} else {
			if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				Z_ADDREF(retval);
				zend_hash_next_index_insert(intern->node_list, &retval);
				obj = Z_DOMOBJ_P(&retval);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (Z_TYPE(retval) == IS_TRUE || Z_TYPE(retval) == IS_FALSE) {
				valuePush(ctxt, xmlXPathNewBoolean(Z_LVAL(retval)));
			} else if (Z_TYPE(retval) == IS_OBJECT) {
				php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((const xmlChar *) ""));
			} else {
				convert_to_string_ex(&retval);
				valuePush(ctxt, xmlXPathNewString((xmlChar *) Z_STRVAL(retval)));
			}
			zval_ptr_dtor(&retval);
		}
	}
	zend_string_release(callable);
	zval_ptr_dtor(&handler);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&args[i]);
		}
		efree(args);
	}
}
Esempio n. 28
0
/* {{{ proto mixed Closure::call(object to [, mixed parameter] [, mixed ...] )
   Call closure, binding to a given object with its class as the scope */
ZEND_METHOD(Closure, call)
{
	zval *zclosure, *newthis, closure_result;
	zend_closure *closure;
	zend_fcall_info fci;
	zend_fcall_info_cache fci_cache;
	zval *my_params;
	int my_param_count = 0;
	zend_function my_function;
	zend_object *newobj;

	if (zend_parse_parameters(ZEND_NUM_ARGS(), "o*", &newthis, &my_params, &my_param_count) == FAILURE) {
		return;
	}

	zclosure = getThis();
	closure = (zend_closure *) Z_OBJ_P(zclosure);

	newobj = Z_OBJ_P(newthis);

	if (!zend_valid_closure_binding(closure, newthis, Z_OBJCE_P(newthis))) {
		return;
	}

	/* This should never happen as closures will always be callable */
	if (zend_fcall_info_init(zclosure, 0, &fci, &fci_cache, NULL, NULL) != SUCCESS) {
		ZEND_ASSERT(0);
	}

	fci.retval = &closure_result;
	fci.params = my_params;
	fci.param_count = my_param_count;
	fci.object = fci_cache.object = newobj;
	fci_cache.initialized = 1;
	fci_cache.called_scope = Z_OBJCE_P(newthis);

	if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) {
		zval new_closure;
		zend_create_closure(&new_closure, fci_cache.function_handler, Z_OBJCE_P(newthis), closure->called_scope, newthis);
		closure = (zend_closure *) Z_OBJ(new_closure);
		fci_cache.function_handler = &closure->func;
	} else {
		memcpy(&my_function, fci_cache.function_handler, fci_cache.function_handler->type == ZEND_USER_FUNCTION ? sizeof(zend_op_array) : sizeof(zend_internal_function));
		/* use scope of passed object */
		my_function.common.scope = Z_OBJCE_P(newthis);
		fci_cache.function_handler = &my_function;

		/* Runtime cache relies on bound scope to be immutable, hence we need a separate rt cache in case scope changed */
		if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) {
			my_function.op_array.run_time_cache = emalloc(my_function.op_array.cache_size);
			memset(my_function.op_array.run_time_cache, 0, my_function.op_array.cache_size);
		}
	}

	if (zend_call_function(&fci, &fci_cache) == SUCCESS && Z_TYPE(closure_result) != IS_UNDEF) {
		ZVAL_COPY_VALUE(return_value, &closure_result);
	}

	if (fci_cache.function_handler->common.fn_flags & ZEND_ACC_GENERATOR) {
		/* copied upon generator creation */
		--GC_REFCOUNT(&closure->std);
	} else if (ZEND_USER_CODE(my_function.type) && closure->func.common.scope != Z_OBJCE_P(newthis)) {
		efree(my_function.op_array.run_time_cache);
	}
}
Esempio n. 29
0
static void dom_xpath_ext_function_php(xmlXPathParserContextPtr ctxt, int nargs, int type) /* {{{ */
{
	zval retval;
	int result, i;
	int error = 0;
	zend_fcall_info fci;
	xmlXPathObjectPtr obj;
	char *str;
	zend_string *callable = NULL;
	dom_xpath_object *intern;


	if (! zend_is_executing()) {
		xmlGenericError(xmlGenericErrorContext,
		"xmlExtFunctionTest: Function called from outside of PHP\n");
		error = 1;
	} else {
		intern = (dom_xpath_object *) ctxt->context->userData;
		if (intern == NULL) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: failed to get the internal object\n");
			error = 1;
		}
		else if (intern->registerPhpFunctions == 0) {
			xmlGenericError(xmlGenericErrorContext,
			"xmlExtFunctionTest: PHP Object did not register PHP functions\n");
			error = 1;
		}
	}

	if (error == 1) {
		for (i = nargs - 1; i >= 0; i--) {
			obj = valuePop(ctxt);
			xmlXPathFreeObject(obj);
		}
		return;
	}

	fci.param_count = nargs - 1;
	if (fci.param_count > 0) {
		fci.params = safe_emalloc(fci.param_count, sizeof(zval), 0);
	}
	/* Reverse order to pop values off ctxt stack */
	for (i = nargs - 2; i >= 0; i--) {
		obj = valuePop(ctxt);
		switch (obj->type) {
			case XPATH_STRING:
				ZVAL_STRING(&fci.params[i],  (char *)obj->stringval);
				break;
			case XPATH_BOOLEAN:
				ZVAL_BOOL(&fci.params[i],  obj->boolval);
				break;
			case XPATH_NUMBER:
				ZVAL_DOUBLE(&fci.params[i], obj->floatval);
				break;
			case XPATH_NODESET:
				if (type == 1) {
					str = (char *)xmlXPathCastToString(obj);
					ZVAL_STRING(&fci.params[i], str);
					xmlFree(str);
				} else if (type == 2) {
					int j;
					array_init(&fci.params[i]);
					if (obj->nodesetval && obj->nodesetval->nodeNr > 0) {
						for (j = 0; j < obj->nodesetval->nodeNr; j++) {
							xmlNodePtr node = obj->nodesetval->nodeTab[j];
							zval child;
							/* not sure, if we need this... it's copied from xpath.c */
							if (node->type == XML_NAMESPACE_DECL) {
								xmlNsPtr curns;
								xmlNodePtr nsparent;

								nsparent = node->_private;
								curns = xmlNewNs(NULL, node->name, NULL);
								if (node->children) {
									curns->prefix = xmlStrdup((xmlChar *) node->children);
								}
								if (node->children) {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) node->children, node->name);
								} else {
									node = xmlNewDocNode(node->doc, NULL, (xmlChar *) "xmlns", node->name);
								}
								node->type = XML_NAMESPACE_DECL;
								node->parent = nsparent;
								node->ns = curns;
							}
							php_dom_create_object(node, &child, &intern->dom);
							add_next_index_zval(&fci.params[i], &child);
						}
					}
				}
				break;
			default:
			ZVAL_STRING(&fci.params[i], (char *)xmlXPathCastToString(obj));
		}
		xmlXPathFreeObject(obj);
	}

	fci.size = sizeof(fci);
	fci.function_table = EG(function_table);

	obj = valuePop(ctxt);
	if (obj->stringval == NULL) {
		php_error_docref(NULL, E_WARNING, "Handler name must be a string");
		xmlXPathFreeObject(obj);
		if (fci.param_count > 0) {
			for (i = 0; i < nargs - 1; i++) {
				zval_ptr_dtor(&fci.params[i]);
			}
			efree(fci.params);
		}
		return;
	}
	ZVAL_STRING(&fci.function_name, (char *) obj->stringval);
	xmlXPathFreeObject(obj);

	fci.symbol_table = NULL;
	fci.object = NULL;
	fci.retval = &retval;
	fci.no_separation = 0;

	if (!zend_make_callable(&fci.function_name, &callable)) {
		php_error_docref(NULL, E_WARNING, "Unable to call handler %s()", callable->val);
	} else if (intern->registerPhpFunctions == 2 && zend_hash_exists(intern->registered_phpfunctions, callable) == 0) {
		php_error_docref(NULL, E_WARNING, "Not allowed to call handler '%s()'.", callable->val);
		/* Push an empty string, so that we at least have an xslt result... */
		valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
	} else {
		result = zend_call_function(&fci, NULL);
		if (result == SUCCESS && Z_TYPE(retval) != IS_UNDEF) {
			if (Z_TYPE(retval) == IS_OBJECT && instanceof_function(Z_OBJCE(retval), dom_node_class_entry)) {
				xmlNode *nodep;
				dom_object *obj;
				if (intern->node_list == NULL) {
					ALLOC_HASHTABLE(intern->node_list);
					zend_hash_init(intern->node_list, 0, NULL, ZVAL_PTR_DTOR, 0);
				}
				GC_REFCOUNT(&retval)++;
				zend_hash_next_index_insert(intern->node_list, &retval);
				obj = Z_DOMOBJ_P(&retval);
				nodep = dom_object_get_node(obj);
				valuePush(ctxt, xmlXPathNewNodeSet(nodep));
			} else if (Z_TYPE(retval) == IS_FALSE || Z_TYPE(retval) == IS_TRUE) {
				valuePush(ctxt, xmlXPathNewBoolean(Z_TYPE(retval) == IS_TRUE));
			} else if (Z_TYPE(retval) == IS_OBJECT) {
				php_error_docref(NULL, E_WARNING, "A PHP Object cannot be converted to a XPath-string");
				valuePush(ctxt, xmlXPathNewString((xmlChar *)""));
			} else {
				zend_string *str = zval_get_string(&retval);
				valuePush(ctxt, xmlXPathNewString((xmlChar *) str->val));
				zend_string_release(str);
			}
			zval_ptr_dtor(&retval);
		}
	}
	zend_string_release(callable);
	zval_dtor(&fci.function_name);
	if (fci.param_count > 0) {
		for (i = 0; i < nargs - 1; i++) {
			zval_ptr_dtor(&fci.params[i]);
		}
		efree(fci.params);
	}
}
Esempio n. 30
0
/* {{{ zend_call_method
 Only returns the returned zval if retval_ptr != NULL */
ZEND_API zval* zend_call_method(zval *object, zend_class_entry *obj_ce, zend_function **fn_proxy, const char *function_name, size_t function_name_len, zval *retval_ptr, int param_count, zval* arg1, zval* arg2)
{
	int result;
	zend_fcall_info fci;
	zval retval;
	HashTable *function_table;

	zval params[2];

	if (param_count > 0) {
		ZVAL_COPY_VALUE(&params[0], arg1);
	}
	if (param_count > 1) {
		ZVAL_COPY_VALUE(&params[1], arg2);
	}

	fci.size = sizeof(fci);
	/*fci.function_table = NULL; will be read form zend_class_entry of object if needed */
	fci.object = (object && Z_TYPE_P(object) == IS_OBJECT) ? Z_OBJ_P(object) : NULL;
	ZVAL_STRINGL(&fci.function_name, function_name, function_name_len);
	fci.retval = retval_ptr ? retval_ptr : &retval;
	fci.param_count = param_count;
	fci.params = params;
	fci.no_separation = 1;
	fci.symbol_table = NULL;

	if (!fn_proxy && !obj_ce) {
		/* no interest in caching and no information already present that is
		 * needed later inside zend_call_function. */
		fci.function_table = !object ? EG(function_table) : NULL;
		result = zend_call_function(&fci, NULL);
		zval_ptr_dtor(&fci.function_name);
	} else {
		zend_fcall_info_cache fcic;

		fcic.initialized = 1;
		if (!obj_ce) {
			obj_ce = object ? Z_OBJCE_P(object) : NULL;
		}
		if (obj_ce) {
			function_table = &obj_ce->function_table;
		} else {
			function_table = EG(function_table);
		}
		if (!fn_proxy || !*fn_proxy) {
			if ((fcic.function_handler = zend_hash_find_ptr(function_table, Z_STR(fci.function_name))) == NULL) {
				/* error at c-level */
				zend_error_noreturn(E_CORE_ERROR, "Couldn't find implementation for method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
			}
			if (fn_proxy) {
				*fn_proxy = fcic.function_handler;
			}
		} else {
			fcic.function_handler = *fn_proxy;
		}
		fcic.calling_scope = obj_ce;
		if (object) {
			fcic.called_scope = Z_OBJCE_P(object);
		} else {
			zend_class_entry *called_scope = zend_get_called_scope(EG(current_execute_data));

			if (obj_ce &&
			    (!called_scope ||
			     !instanceof_function(called_scope, obj_ce))) {
				fcic.called_scope = obj_ce;
			} else {
				fcic.called_scope = called_scope;
			}
		}
		fcic.object = object ? Z_OBJ_P(object) : NULL;
		result = zend_call_function(&fci, &fcic);
		zval_ptr_dtor(&fci.function_name);
	}
	if (result == FAILURE) {
		/* error at c-level */
		if (!obj_ce) {
			obj_ce = object ? Z_OBJCE_P(object) : NULL;
		}
		if (!EG(exception)) {
			zend_error_noreturn(E_CORE_ERROR, "Couldn't execute method %s%s%s", obj_ce ? obj_ce->name->val : "", obj_ce ? "::" : "", function_name);
		}
	}
	/* copy arguments back, they might be changed by references */
	if (param_count > 0 && Z_ISREF(params[0]) && !Z_ISREF_P(arg1)) {
		ZVAL_COPY_VALUE(arg1, &params[0]);
	}
	if (param_count > 1 && Z_ISREF(params[1]) && !Z_ISREF_P(arg2)) {
		ZVAL_COPY_VALUE(arg2, &params[1]);
	}
	if (!retval_ptr) {
		zval_ptr_dtor(&retval);
		return NULL;
	}
	return retval_ptr;
}