Esempio n. 1
0
/* {{{ apc_lookup_class_hook */
int apc_lookup_class_hook(char *name, int len, ulong hash, zend_class_entry ***ce) {

    apc_class_t *cl;
    apc_context_t ctxt = {0,};
    TSRMLS_FETCH();

    if(zend_is_compiling(TSRMLS_C)) { return FAILURE; }

    if(zend_hash_quick_find(APCG(lazy_class_table), name, len, hash, (void**)&cl) == FAILURE) {
        return FAILURE;
    }

    ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
    ctxt.copy = APC_COPY_OUT_OPCODE;

    if(install_class(*cl, &ctxt, 0 TSRMLS_CC) == FAILURE) {
        apc_warning("apc_lookup_class_hook: could not install %s" TSRMLS_CC, name);
        return FAILURE;
    }

    if(zend_hash_quick_find(EG(class_table), name, len, hash, (void**)ce) == FAILURE) {
        apc_warning("apc_lookup_class_hook: known error trying to fetch class %s" TSRMLS_CC, name);
        return FAILURE;
    }

    return SUCCESS;

}
Esempio n. 2
0
static int32_t qb_transfer_value_from_import_source(qb_interpreter_context *cxt, qb_variable *ivar, qb_import_scope *scope) {
	int32_t result = TRUE;
	if(!(ivar->flags & QB_VARIABLE_IMPORTED)) {
		USE_TSRM
		zval *zvalue = NULL, **p_zvalue = NULL;
		switch(scope->type) {
			case QB_IMPORT_SCOPE_GLOBAL:
			case QB_IMPORT_SCOPE_LEXICAL: {
				// copy value from symbol table
				zend_hash_quick_find(scope->symbol_table, ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &p_zvalue);
			}	break;
			case QB_IMPORT_SCOPE_CLASS: {
				if(ivar->flags & QB_VARIABLE_CLASS_CONSTANT) {
					// static:: constants are treated like variables
					zend_class_entry *ce = scope->class_entry;
					zval **p_value;
					zend_hash_quick_find(&ce->constants_table, ivar->name, ivar->name_length + 1, ivar->hash_value, (void **) &p_value);
				} else {
					zend_class_entry *ce = scope->class_entry;
					p_zvalue = Z_CLASS_GET_PROP(ce, ivar->name, ivar->name_length);
				}
			}	break;
			case QB_IMPORT_SCOPE_OBJECT: {
				// copy value from class instance
				zval *name = qb_string_to_zval(ivar->name, ivar->name_length TSRMLS_CC);
				zval *container = scope->object;
				p_zvalue = Z_OBJ_GET_PROP_PTR_PTR(container, name);
				if(!p_zvalue) {
					if(Z_OBJ_HT_P(container)->read_property) {
						zvalue = Z_OBJ_READ_PROP(container, name);
					}
				}
			}	break;
			default: {
			}	break;
		}
		if(p_zvalue) {
			zvalue = *p_zvalue;
		}
		if(qb_transfer_value_from_zval(scope->storage, ivar->address, (zvalue) ? zvalue : &zval_used_for_init, QB_TRANSFER_CAN_BORROW_MEMORY | QB_TRANSFER_CAN_AUTOVIVIFICATE)) {
			ivar->flags |= QB_VARIABLE_IMPORTED;
			ivar->value_pointer = p_zvalue;
			ivar->value = zvalue;

			if(!p_zvalue && zvalue) {
				// we got the zval from a getter function
				// need to up the reference count
				Z_ADDREF_P(zvalue);
			}
		} else {
			uint32_t line_id = qb_get_zend_line_id(TSRMLS_C);
			qb_append_exception_variable_name(ivar TSRMLS_CC);
			qb_set_exception_line_id(line_id TSRMLS_CC);
			result = FALSE;
		}
	}
	return result;
}
Esempio n. 3
0
	KValueRef KPHPArrayObject::Get(const char *name)
	{
		if (KList::IsInt(name))
		{
			unsigned int index = (unsigned int) atoi(name);
			if (index >= 0)
				return this->At(index);
		}

		unsigned long hashval = zend_get_hash_value((char *) name, strlen(name));
		zval **copyval;

		if (zend_hash_quick_find(Z_ARRVAL_P(this->list),
					(char *) name,
					strlen(name),
					hashval,
					(void**)&copyval) == FAILURE)
		{
			return Value::Undefined;
		}

		TSRMLS_FETCH();
		KValueRef v = PHPUtils::ToKrollValue((zval *) copyval TSRMLS_CC);
		return v;
	}
Esempio n. 4
0
/**
 * Reads an item from an array using a string as index
 */
int phalcon_array_fetch_quick_string(zval **return_value, zval *arr, char *index, uint index_length, unsigned long key, int silent TSRMLS_DC){

	zval **zv;
	int result = FAILURE;

	if (unlikely(Z_TYPE_P(arr) != IS_ARRAY)) {

		if (silent == PH_NOISY) {
			php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Cannot use a scalar value as an array");
		}

		ALLOC_INIT_ZVAL(*return_value);
		ZVAL_NULL(*return_value);

		return FAILURE;
	}

	if ((result = zend_hash_quick_find(Z_ARRVAL_P(arr), index, index_length, key, (void**) &zv)) == SUCCESS) {
		*return_value = *zv;
		Z_ADDREF_PP(return_value);
		return SUCCESS;
	}

	if (silent == PH_NOISY) {
		php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Undefined index: %s", index);
	}

	ALLOC_INIT_ZVAL(*return_value);
	ZVAL_NULL(*return_value);

	return FAILURE;

}
Esempio n. 5
0
RedisArray*
ra_load_hosts(RedisArray *ra, HashTable *hosts, long retry_interval TSRMLS_DC)
{
	int i, host_len, id;
	int count = zend_hash_num_elements(hosts);
	char *host, *p;
	short port;
	zval **zpData, z_cons, z_ret;
	RedisSock *redis_sock  = NULL;

	/* function calls on the Redis object */
	ZVAL_STRING(&z_cons, "__construct", 0);

	/* init connections */
	for(i = 0; i < count; ++i) {
		if(FAILURE == zend_hash_quick_find(hosts, NULL, 0, i, (void**)&zpData)) {
			efree(ra);
			return NULL;
		}

		ra->hosts[i] = estrdup(Z_STRVAL_PP(zpData));

		/* default values */
		host = Z_STRVAL_PP(zpData);
		host_len = Z_STRLEN_PP(zpData);
		port = 6379;

		if((p = strchr(host, ':'))) { /* found port */
			host_len = p - host;
			port = (short)atoi(p+1);
		}

		/* create Redis object */
		MAKE_STD_ZVAL(ra->redis[i]);
		object_init_ex(ra->redis[i], redis_ce);
		INIT_PZVAL(ra->redis[i]);
		call_user_function(&redis_ce->function_table, &ra->redis[i], &z_cons, &z_ret, 0, NULL TSRMLS_CC);

		/* create socket */
		redis_sock = redis_sock_create(host, host_len, port, 0, 0, NULL, retry_interval); /* TODO: persistence? */

		/* connect */
		redis_sock_server_open(redis_sock, 1 TSRMLS_CC);

		/* attach */
#if PHP_VERSION_ID >= 50400
		id = zend_list_insert(redis_sock, le_redis_sock TSRMLS_CC);
#else
		id = zend_list_insert(redis_sock, le_redis_sock);
#endif
		add_property_resource(ra->redis[i], "socket", id);
	}

	return ra;
}
Esempio n. 6
0
/* {{{ apc_lookup_function_hook */
int apc_lookup_function_hook(char *name, int len, ulong hash, zend_function **fe) {
    apc_function_t *fn;
    int status = FAILURE;
    apc_context_t ctxt = {0,};
    TSRMLS_FETCH();

    ctxt.pool = apc_pool_create(APC_UNPOOL, apc_php_malloc, apc_php_free, apc_sma_protect, apc_sma_unprotect TSRMLS_CC);
    ctxt.copy = APC_COPY_OUT_OPCODE;

    if(zend_hash_quick_find(APCG(lazy_function_table), name, len, hash, (void**)&fn) == SUCCESS) {
        *fe = apc_copy_function_for_execution(fn->function, &ctxt TSRMLS_CC);
        if (fe == NULL)
            return FAILURE;
        status = zend_hash_add(EG(function_table),
                                  fn->name,
                                  fn->name_len+1,
                                  *fe,
                                  sizeof(zend_function),
                                  NULL);
    }

    return status;
}
Esempio n. 7
0
/**
 * Applies a format to a message before sending it to the log
 *
 * @param string $message
 * @param int $type
 * @param int $timestamp
 * @param array $context
 * @return string
 */
PHP_METHOD(Phalcon_Logger_Formatter_Firephp, format) {

	zval *message, *type, *type_str = NULL, *timestamp, *context, *interpolated = NULL;
	zval *payload, *body, *backtrace = NULL, *meta, *encoded;
	zval *show_backtrace, *enable_labels;
	int i_show_backtrace, i_enable_labels;
	smart_str result = { NULL, 0, 0 };
	uint i;
	Bucket *p;

	phalcon_fetch_params(0, 4, 0, &message, &type, &timestamp, &context);

	/*
	 * We intentionally do not use Phalcon's MM for better performance.
	 * All variables allocated with ALLOC_INIT_ZVAL() will have
	 * their reference count set to 1 and therefore they can be nicely
	 * put into the result array; when that array will be destroyed,
	 * all inserted variables will be automatically destroyed, too
	 * and we will just save some time by not using Z_ADDREF_P and Z_DELREF_P
	 */

	if (Z_TYPE_P(context) == IS_ARRAY) {
		PHALCON_CALL_METHODW(&interpolated, this_ptr, "interpolate", message, context);
	}
	else {
		interpolated = message;
		Z_ADDREF_P(interpolated);
	}

	{
		zval *params[] = { type };
		if (FAILURE == phalcon_call_method(&type_str, this_ptr, "gettypestring", 1, params TSRMLS_CC)) {
			zval_ptr_dtor(&interpolated);
			return;
		}
	}

	show_backtrace   = phalcon_fetch_nproperty_this(getThis(), SL("_showBacktrace"), PH_NOISY TSRMLS_CC);
	enable_labels    = phalcon_fetch_nproperty_this(getThis(), SL("_enableLabels"), PH_NOISY TSRMLS_CC);
	i_show_backtrace = zend_is_true(show_backtrace);
	i_enable_labels  = zend_is_true(enable_labels);

	/*
	 * Get the backtrace. This differs for different PHP versions.
	 * 5.3.6+ allows us to skip the function arguments which will save some memory
	 * For 5.4+ there is an extra argument.
	 */
	if (i_show_backtrace) {
		ALLOC_INIT_ZVAL(backtrace);

#if PHP_VERSION_ID < 50306
		zend_fetch_debug_backtrace(backtrace, 1, 0 TSRMLS_CC);
#elif PHP_VERSION_ID < 50400
		zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS TSRMLS_CC);
#else
		zend_fetch_debug_backtrace(backtrace, 1, DEBUG_BACKTRACE_IGNORE_ARGS, 0 TSRMLS_CC);
#endif

		if (Z_TYPE_P(backtrace) == IS_ARRAY) {
			HashPosition pos;
			HashTable *ht = Z_ARRVAL_P(backtrace);
			zval **ppzval;
			int found = 0;
			ulong idx;
			char *key;
			uint key_len;

			/*
			 * At this point we know that the backtrace is the array.
			 * Again, we intentionally do not use Phalcon's API because we know
			 * that we are working with the array / hash table and thus we can
			 * save some time by omitting Z_TYPE_P(x) == IS_ARRAY checks
			 */

			for (
				zend_hash_internal_pointer_reset_ex(ht, &pos);
				zend_hash_has_more_elements_ex(ht, &pos) == SUCCESS;
			) {
				zend_hash_get_current_data_ex(ht, (void**)&ppzval, &pos);
				zend_hash_get_current_key_ex(ht, &key, &key_len, &idx, 0, &pos);
				zend_hash_move_forward_ex(ht, &pos);

				if (Z_TYPE_PP(ppzval) == IS_ARRAY) {
					/*
					 * Here we need to skip the latest calls into Phalcon's core.
					 * Calls to Zend internal functions will have "file" index not set.
					 * We remove these entries from the array.
					 */
					if (!found && !zend_hash_quick_exists(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")))) {
						zend_hash_index_del(ht, idx);
					}
					else {
						/*
						 * Remove args and object indices. They usually give
						 * too much information; this is not suitable to send
						 * in the HTTP headers
						 */
						zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "args", sizeof("args"), zend_inline_hash_func(SS("args")));
						zend_hash_quick_del(Z_ARRVAL_PP(ppzval), "object", sizeof("object"), zend_inline_hash_func(SS("object")));
						found = 1;
					}
				}
			}

			/*
			 * Now we need to renumber the hash table because we removed several
			 * heading elements. If we don't do this, json_encode() will convert
			 * this array to a JavaScript object which is an unwanted side effect
			 */
			p = ht->pListHead;
			i = 0;
			while (p != NULL) {
				p->nKeyLength = 0;
				p->h = i++;
				p = p->pListNext;
			}

			ht->nNextFreeElement = i;
			zend_hash_rehash(ht);
		}
	}

	/*
	 * The result will looks like this:
	 *
	 * array(
	 *     array('Type' => 'message type', 'Label' => 'message'),
	 *     array('backtrace' => array(backtrace goes here)
	 * )
	 */
	MAKE_STD_ZVAL(payload);
	array_init_size(payload, 2);

	MAKE_STD_ZVAL(meta);
	array_init_size(meta, 4);
	add_assoc_zval_ex(meta, SS("Type"), type_str);

	if (i_show_backtrace && Z_TYPE_P(backtrace) == IS_ARRAY) {
		zval **ppzval;

		if (likely(SUCCESS == zend_hash_index_find(Z_ARRVAL_P(backtrace), 0, (void**)&ppzval)) && likely(Z_TYPE_PP(ppzval) == IS_ARRAY)) {
			zval **file = NULL, **line = NULL;

			zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("file"), zend_inline_hash_func(SS("file")), (void**)&file);
			zend_hash_quick_find(Z_ARRVAL_PP(ppzval), SS("line"), zend_inline_hash_func(SS("line")), (void**)&line);

			if (likely(file != NULL)) {
				Z_ADDREF_PP(file);
				add_assoc_zval_ex(meta, SS("File"), *file);
			}

			if (likely(line != NULL)) {
				Z_ADDREF_PP(line);
				add_assoc_zval_ex(meta, SS("Line"), *line);
			}
		}
	}

	if (i_enable_labels) {
		add_assoc_zval_ex(meta, SS("Label"), interpolated);
	}

	if (!i_enable_labels && !i_show_backtrace) {
		body = interpolated;
	}
	else if (i_enable_labels && !i_show_backtrace) {
		MAKE_STD_ZVAL(body);
		ZVAL_EMPTY_STRING(body);
	}
	else {
		MAKE_STD_ZVAL(body);
		array_init_size(body, 2);

		if (i_show_backtrace) {
			add_assoc_zval_ex(body, SS("backtrace"), backtrace);
		}

		if (!i_enable_labels) {
			add_assoc_zval_ex(body, SS("message"), interpolated);
		}
	}

	add_next_index_zval(payload, meta);
	add_next_index_zval(payload, body);

	/* Convert everything to JSON */
	ALLOC_INIT_ZVAL(encoded);
	if (FAILURE == phalcon_json_encode(encoded, payload, 0 TSRMLS_CC)) {
		zval_ptr_dtor(&payload);
		zval_ptr_dtor(&encoded);
		return;
	}

	/* As promised, kill the payload and all associated elements */
	zval_ptr_dtor(&payload);

	/*
	 * We don't want to use Phalcon's concatenation API because it
	 * requires the memory manager. Therefore we fall back to using smart strings.
	 * smart_str_alloc4() will allocate all required memory amount (plus some more)
	 * in one go and this allows us to avoid performance penalties due to
	 * memory reallocations.
	 */
	if (Z_TYPE_P(encoded) == IS_STRING && Z_STRVAL_P(encoded) != NULL) {
		smart_str_alloc4(&result, (uint)(Z_STRLEN_P(encoded) + 2 + 5), 0, i);

		/*
		 * The format is:
		 *
		 * <size>|[meta,body]|
		 *
		 * Meta and body are contained in encoded inside the array, as required
		 * by the protocol specification
		 * @see http://www.firephp.org/Wiki/Reference/Protocol
		 */
		smart_str_append_long(&result, Z_STRLEN_P(encoded));
		smart_str_appendc(&result, '|');
		smart_str_appendl(&result, Z_STRVAL_P(encoded), Z_STRLEN_P(encoded));
		smart_str_appendc(&result, '|');
		smart_str_0(&result);
	}

	/* We don't need the JSON message anymore */
	zval_ptr_dtor(&encoded);
	/* Do not free the smart string because we steal its data for zval */
	RETURN_STRINGL(result.c, result.len, 0);
}
Esempio n. 8
0
static void luasandbox_timer_profiler_hook(lua_State *L, lua_Debug *ar)
{
	lua_sethook(L, luasandbox_timer_profiler_hook, 0, 0);

	php_luasandbox_obj * sandbox = luasandbox_get_php_obj(L);
	lua_Debug debug;
	memset(&debug, 0, sizeof(debug));

	// Get and zero the signal count
	// If a signal occurs within this critical section, be careful not to lose the overrun count
	long signal_count = sandbox->timer.profiler_signal_count;
	sandbox->timer.profiler_signal_count -= signal_count;

	lua_getinfo(L, "Snlf", ar);
	const char * name = NULL;
	if (ar->what[0] == 'C') {
		name = luasandbox_timer_get_cfunction_name(L);
	}
	if (!name) {
		if (ar->namewhat[0] != '\0') {
			name = ar->name;
		} else if (ar->what[0] == 'm') {
			name = "[main chunk]";
		}
	}
	size_t prof_name_size = strlen(ar->short_src)
		+ sizeof(ar->linedefined) * 4 + sizeof("  <:>");
	if (name) {
		prof_name_size += strlen(name);
	}
	char prof_name[prof_name_size];
	if (!name) {
		if (ar->linedefined > 0) {
			snprintf(prof_name, prof_name_size, "<%s:%d>", ar->short_src, ar->linedefined);
		} else {
			strcpy(prof_name, "?");
		}
	} else {
		if (ar->what[0] == 'm') {
			snprintf(prof_name, prof_name_size, "%s <%s>", name, ar->short_src);
		} else if (ar->linedefined > 0) {
			snprintf(prof_name, prof_name_size, "%s <%s:%d>", name, ar->short_src, ar->linedefined);
		} else {
			snprintf(prof_name, prof_name_size, "%s", name);
		}
	}
	// Key length in zend_hash conventionally includes the null byte
	uint key_length = (uint)strlen(prof_name) + 1;
	ulong h = zend_inline_hash_func(prof_name, key_length);
	luasandbox_timer_set * lts = &sandbox->timer;
	HashTable * ht = lts->function_counts;
	size_t * elt;
	if (SUCCESS == zend_hash_quick_find(ht, prof_name, key_length, h, (void**)&elt)) {
		(*elt) += signal_count;
	} else {
		size_t init = signal_count;
		zend_hash_quick_add(ht, prof_name, key_length, h, (void**)&init, sizeof(size_t), NULL);
	}

	lts->total_count += signal_count;
}
Esempio n. 9
0
static void dic_optimizer_get_handler(INTERNAL_FUNCTION_PARAMETERS)
{
	char *id, should_free = 1;
	zend_ulong id_hash;
	int id_len, i;
	long oninvalid, exception_on_invalid_reference_const;
	zval **found_service, **alias, **method_in_map = NULL, *this_services, *this_aliases, *this_methodMap, *this_loading;
	zend_function *method = NULL;

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &id, &id_len, &oninvalid) == FAILURE) {
		return;
	}

	if (strcasecmp(id, "service_container") == 0) {
		RETURN_THIS;
	}

	this_services  = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_SERVICES_KEY, sizeof(SYMFONY_DIC_TOKEN_SERVICES_KEY) - 1, 0 TSRMLS_CC);
	this_aliases   = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_ALIASES_KEY, sizeof(SYMFONY_DIC_TOKEN_ALIASES_KEY) - 1, 0 TSRMLS_CC);
	this_loading   = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_LOADING_KEY, sizeof(SYMFONY_DIC_TOKEN_LOADING_KEY) - 1, 0 TSRMLS_CC);
	this_methodMap = zend_read_property(Z_OBJCE_P(getThis()), getThis(), SYMFONY_DIC_TOKEN_METHODMAP_KEY, sizeof(SYMFONY_DIC_TOKEN_METHODMAP_KEY) - 1, 0 TSRMLS_CC);

	if (!SYMFONY_DIC_G(cache_done)) {
		zval invalidBehavior;
		zend_class_entry **exception_ce;

		zend_get_constant_ex("self::EXCEPTION_ON_INVALID_REFERENCE", sizeof("self::EXCEPTION_ON_INVALID_REFERENCE") - 1, &invalidBehavior, Z_OBJCE_P(getThis()), 0  TSRMLS_CC);
		SYMFONY_DIC_G(invalid_behavior) = Z_LVAL(invalidBehavior);

		if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) {
			zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_SERVICE_CIRCULAR_REFERENCE_EXCEPTION_KEY_UP);
		}
		SYMFONY_DIC_G(ServiceCircularReferenceException) = *exception_ce;
		if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) {
			zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_SERVICE_NOT_FOUND_EXCEPTION_KEY_UP);
		}
		SYMFONY_DIC_G(ServiceNotFoundException) = *exception_ce;
		if (FAILURE == zend_lookup_class(SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP, sizeof(SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP) - 1, &exception_ce TSRMLS_CC)) {
			zend_error_noreturn(E_ERROR, "Class %s not found", SYMFONY_DIC_TOKEN_INACTIVE_SCOPE_EXCEPTION_KEY_UP);
		}
		SYMFONY_DIC_G(InactiveScopeException) = *exception_ce;

		SYMFONY_DIC_G(cache_done) = 1;
	}

	exception_on_invalid_reference_const = SYMFONY_DIC_G(invalid_behavior);

	if (ZEND_NUM_ARGS() <= 1) {
		oninvalid = exception_on_invalid_reference_const;
	}

	if (IS_INTERNED(id)) {
		id_hash = INTERNED_HASH(id);
	} else {
		id_hash = zend_inline_hash_func(id, id_len + 1);
	}

	id = estrndup(id, id_len); /* zend_str_tolower will change it otherwise */

	for (i = 0; i <= 1; i++, zend_str_tolower(id, id_len), id_hash = zend_inline_hash_func(id, id_len + 1)) {
		if (zend_hash_quick_find(Z_ARRVAL_P(this_aliases), id, id_len + 1, id_hash, (void **)&alias) == SUCCESS) {
			should_free = 0;
			efree(id);
			id      = Z_STRVAL_PP(alias);
			id_len  = Z_STRLEN_PP(alias);
			id_hash = zend_inline_hash_func(id, id_len + 1);
		}
		if (zend_hash_quick_find(Z_ARRVAL_P(this_services), id, id_len + 1, id_hash, (void **)&found_service) == SUCCESS) {
			RETVAL_ZVAL_FAST(*found_service);
			goto free_and_return;
		}
	}

	if (zend_hash_quick_exists(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash)) {
		zval *ServiceCircularReferenceException;
		ALLOC_INIT_ZVAL(ServiceCircularReferenceException); /* ctor_args */
		object_init_ex(ServiceCircularReferenceException, SYMFONY_DIC_G(ServiceCircularReferenceException));
		zend_throw_exception_object(ServiceCircularReferenceException TSRMLS_CC);
		goto free_and_return;
	}

	zend_hash_quick_find(Z_ARRVAL_P(this_methodMap), id, id_len + 1, id_hash, (void **)&method_in_map);

	if (!method_in_map) {
		char *new_id;

		for (i=0; i < id_len; i++) {
			if (id[i] == '_') {
				memmove(&id[i], &id[i + 1], --id_len);
			}
		}
		php_strtr(id, id_len, ".\\", "__", 2);
		id_len = spprintf(&new_id, 0, "get%sservice", id);
		efree(id);
		id      = new_id;
		id_hash = zend_inline_hash_func(id, id_len + 1);

		zend_hash_quick_find(&Z_OBJCE_P(getThis())->function_table, id, id_len + 1, id_hash, (void **)&method);
		if (!method) {
			if (oninvalid == exception_on_invalid_reference_const) {
				zval *ServiceNotFoundException;
				ALLOC_INIT_ZVAL(ServiceNotFoundException);
				object_init_ex(ServiceNotFoundException, SYMFONY_DIC_G(ServiceNotFoundException));
				zend_throw_exception_object(ServiceNotFoundException TSRMLS_CC); /* ctor_args */
			}
			goto free_and_return;
		}
	} else {
		char *method_name_lc;
		method_name_lc = zend_str_tolower_dup(Z_STRVAL_PP(method_in_map), Z_STRLEN_PP(method_in_map));
		zend_hash_find(&Z_OBJCE_P(getThis())->function_table, method_name_lc, Z_STRLEN_PP(method_in_map) + 1, (void **)&method);
		efree(method_name_lc);
	}

	zend_fcall_info fci = {0};
	zend_fcall_info_cache fcic = {0};
	zval *loading, *result;

	ALLOC_INIT_ZVAL(loading); ZVAL_BOOL(loading, 1);
	zend_hash_quick_add(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash, &loading, sizeof(zval *), NULL);

	fcic.called_scope = Z_OBJCE_P(getThis());
	fcic.calling_scope = Z_OBJCE_P(getThis());
	fcic.function_handler = method;
	fcic.initialized = 1;
	fcic.object_ptr = getThis();

	fci.retval_ptr_ptr = &result;
	fci.size = sizeof(zend_fcall_info);

	zend_call_function(&fci, &fcic TSRMLS_CC);

	zend_hash_quick_del(Z_ARRVAL_P(this_loading), id, id_len + 1, id_hash);

	if (!EG(exception)) {
		RETVAL_ZVAL_FAST(result);
	} else {
		zend_hash_quick_del(Z_ARRVAL_P(this_services), id, id_len, id_hash);

		if (instanceof_function(Z_OBJCE_P(EG(exception)), SYMFONY_DIC_G(InactiveScopeException) TSRMLS_CC) && oninvalid == exception_on_invalid_reference_const) {
			EG(exception) = NULL;
		}
	}
	zval_ptr_dtor(&result);
free_and_return:
	if (should_free) { efree(id); }
	return;
}