/* Struct for properties */
typedef struct _property_reference {
- zend_property_info prop;
+ zend_property_info *prop;
zend_string *unmangled_name;
- zend_bool dynamic;
} property_reference;
/* Struct for parameters */
static zend_object_handlers reflection_object_handlers;
+static uint32_t zend_always_inline prop_get_flags(property_reference *ref) {
+ return ref->prop ? ref->prop->flags : ZEND_ACC_PUBLIC;
+}
+
static inline zend_bool is_closure_invoke(zend_class_entry *ce, zend_string *lcname) {
return ce == zend_ce_closure
&& zend_string_equals_literal(lcname, ZEND_INVOKE_FUNC_NAME);
static void _const_string(smart_str *str, char *name, zval *value, char *indent);
static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, char* indent);
-static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent, zend_bool dynamic);
+static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent);
static void _class_const_string(smart_str *str, char *name, zend_class_constant *c, char* indent);
static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, char *indent);
static void _extension_string(smart_str *str, zend_module_entry *module, char *indent);
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
if ((prop->flags & ZEND_ACC_STATIC) && (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) {
- _property_string(str, prop, NULL, ZSTR_VAL(sub_indent), 0);
+ _property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
}
} ZEND_HASH_FOREACH_END();
}
ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop) {
if (!(prop->flags & ZEND_ACC_STATIC)
&& (!(prop->flags & ZEND_ACC_PRIVATE) || prop->ce == ce)) {
- _property_string(str, prop, NULL, ZSTR_VAL(sub_indent), 0);
+ _property_string(str, prop, NULL, ZSTR_VAL(sub_indent));
}
} ZEND_HASH_FOREACH_END();
}
if (prop_name && ZSTR_LEN(prop_name) && ZSTR_VAL(prop_name)[0]) { /* skip all private and protected properties */
if (!zend_hash_exists(&ce->properties_info, prop_name)) {
count++;
- _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent), 0);
+ _property_string(&prop_str, NULL, ZSTR_VAL(prop_name), ZSTR_VAL(sub_indent));
}
}
} ZEND_HASH_FOREACH_END();
/* }}} */
/* {{{ _property_string */
-static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent, zend_bool dynamic)
+static void _property_string(smart_str *str, zend_property_info *prop, const char *prop_name, char* indent)
{
smart_str_append_printf(str, "%sProperty [ ", indent);
if (!prop) {
smart_str_append_printf(str, "<dynamic> public $%s", prop_name);
} else {
if (!(prop->flags & ZEND_ACC_STATIC)) {
- if (dynamic) {
- smart_str_appends(str, "<implicit> ");
- } else {
- smart_str_appends(str, "<default> ");
- }
+ smart_str_appends(str, "<default> ");
}
/* These are mutually exclusive */
/* }}} */
/* {{{ reflection_property_factory */
-static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object, zend_bool dynamic)
+static void reflection_property_factory(zend_class_entry *ce, zend_string *name, zend_property_info *prop, zval *object)
{
reflection_object *intern;
property_reference *reference;
- if (!(prop->flags & ZEND_ACC_PRIVATE)) {
+ if (!prop || !(prop->flags & ZEND_ACC_PRIVATE)) {
/* we have to search the class hierarchy for this (implicit) public or protected property */
zend_class_entry *tmp_ce = ce, *store_ce = ce;
zend_property_info *tmp_info = NULL;
reflection_instantiate(reflection_property_ptr, object);
intern = Z_REFLECTION_P(object);
reference = (property_reference*) emalloc(sizeof(property_reference));
- reference->prop = *prop;
+ reference->prop = prop;
reference->unmangled_name = zend_string_copy(name);
- reference->dynamic = dynamic;
intern->ptr = reference;
intern->ref_type = REF_TYPE_PROPERTY;
intern->ce = ce;
intern->ignore_visibility = 0;
ZVAL_STR_COPY(reflection_prop_name(object), name);
- ZVAL_STR_COPY(reflection_prop_class(object), prop->ce->name);
+ ZVAL_STR_COPY(reflection_prop_class(object), prop ? prop->ce->name : ce->name);
}
/* }}} */
static void reflection_property_factory_str(zend_class_entry *ce, const char *name_str, size_t name_len, zend_property_info *prop, zval *object)
{
zend_string *name = zend_string_init(name_str, name_len, 0);
- reflection_property_factory(ce, name, prop, object, 0);
+ reflection_property_factory(ce, name, prop, object);
zend_string_release(name);
}
GET_REFLECTION_OBJECT_PTR(ce);
if ((property_info = zend_hash_find_ptr(&ce->properties_info, name)) != NULL) {
if (!(property_info->flags & ZEND_ACC_PRIVATE) || property_info->ce == ce) {
- reflection_property_factory(ce, name, property_info, return_value, 0);
+ reflection_property_factory(ce, name, property_info, return_value);
return;
}
} else if (Z_TYPE(intern->obj) != IS_UNDEF) {
/* Check for dynamic properties */
if (zend_hash_exists(Z_OBJ_HT(intern->obj)->get_properties(Z_OBJ(intern->obj)), name)) {
- zend_property_info property_info_tmp;
- property_info_tmp.flags = ZEND_ACC_PUBLIC;
- property_info_tmp.name = name;
- property_info_tmp.doc_comment = NULL;
- property_info_tmp.ce = ce;
-
- reflection_property_factory(ce, name, &property_info_tmp, return_value, 1);
+ reflection_property_factory(ce, name, NULL, return_value);
return;
}
}
if (pptr->flags & filter) {
zval property;
- reflection_property_factory(ce, key, pptr, &property, 0);
+ reflection_property_factory(ce, key, pptr, &property);
add_next_index_zval(retval, &property);
}
}
/* {{{ _adddynproperty */
static void _adddynproperty(zval *ptr, zend_string *key, zend_class_entry *ce, zval *retval)
{
- zend_property_info property_info;
zval property;
/* under some circumstances, the properties hash table may contain numeric
return;
}
- property_info.doc_comment = NULL;
- property_info.flags = ZEND_ACC_PUBLIC;
- property_info.name = key;
- property_info.ce = ce;
- property_info.offset = -1;
- reflection_property_factory(ce, key, &property_info, &property, 1);
+ reflection_property_factory(ce, key, NULL, &property);
add_next_index_zval(retval, &property);
}
/* }}} */
}
reference = (property_reference*) emalloc(sizeof(property_reference));
- if (dynam_prop) {
- reference->prop.flags = ZEND_ACC_PUBLIC;
- reference->prop.name = name;
- reference->prop.doc_comment = NULL;
- reference->prop.ce = ce;
- reference->dynamic = 1;
- } else {
- reference->prop = *property_info;
- reference->dynamic = 0;
- }
+ reference->prop = dynam_prop ? NULL : property_info;
reference->unmangled_name = zend_string_copy(name);
intern->ptr = reference;
intern->ref_type = REF_TYPE_PROPERTY;
return;
}
GET_REFLECTION_OBJECT_PTR(ref);
- _property_string(&str, &ref->prop, ZSTR_VAL(ref->unmangled_name), "", ref->dynamic);
+ _property_string(&str, ref->prop, ZSTR_VAL(ref->unmangled_name), "");
RETURN_STR(smart_str_extract(&str));
}
/* }}} */
return;
}
GET_REFLECTION_OBJECT_PTR(ref);
- RETURN_BOOL(ref->prop.flags & mask);
+ RETURN_BOOL(prop_get_flags(ref) & mask);
}
/* }}} */
return;
}
GET_REFLECTION_OBJECT_PTR(ref);
- RETURN_BOOL(!ref->dynamic);
+ RETURN_BOOL(ref->prop != NULL);
}
/* }}} */
}
GET_REFLECTION_OBJECT_PTR(ref);
- RETURN_LONG((ref->prop.flags & keep_flags));
+ RETURN_LONG(prop_get_flags(ref) & keep_flags);
}
/* }}} */
GET_REFLECTION_OBJECT_PTR(ref);
- if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
+ if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
name = _default_load_name(ZEND_THIS);
zend_throw_exception_ex(reflection_exception_ptr, 0,
"Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
return;
}
- if (ref->prop.flags & ZEND_ACC_STATIC) {
+ if (prop_get_flags(ref) & ZEND_ACC_STATIC) {
member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 0);
if (member_p) {
ZVAL_COPY_DEREF(return_value, member_p);
return;
}
- if (!instanceof_function(Z_OBJCE_P(object), ref->prop.ce)) {
+ /* TODO: Should this always use intern->ce? */
+ if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) {
_DO_THROW("Given object is not an instance of the class this property was declared in");
return;
}
GET_REFLECTION_OBJECT_PTR(ref);
- if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
+ if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
name = _default_load_name(ZEND_THIS);
zend_throw_exception_ex(reflection_exception_ptr, 0,
"Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
return;
}
- if (ref->prop.flags & ZEND_ACC_STATIC) {
+ if (prop_get_flags(ref) & ZEND_ACC_STATIC) {
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS(), "z", &value) == FAILURE) {
if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &tmp, &value) == FAILURE) {
return;
GET_REFLECTION_OBJECT_PTR(ref);
- if (!(ref->prop.flags & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
+ if (!(prop_get_flags(ref) & ZEND_ACC_PUBLIC) && intern->ignore_visibility == 0) {
name = _default_load_name(getThis());
zend_throw_exception_ex(reflection_exception_ptr, 0,
"Cannot access non-public member %s::$%s", ZSTR_VAL(intern->ce->name), Z_STRVAL_P(name));
return;
}
- if (ref->prop.flags & ZEND_ACC_STATIC) {
+ if (prop_get_flags(ref) & ZEND_ACC_STATIC) {
member_p = zend_read_static_property_ex(intern->ce, ref->unmangled_name, 1);
if (member_p) {
RETURN_BOOL(!Z_ISUNDEF_P(member_p));
return;
}
- if (!instanceof_function(Z_OBJCE_P(object), ref->prop.ce)) {
+ /* TODO: Should this always use intern->ce? */
+ if (!instanceof_function(Z_OBJCE_P(object), ref->prop ? ref->prop->ce : intern->ce)) {
_DO_THROW("Given object is not an instance of the class this property was declared in");
return;
}
return;
}
GET_REFLECTION_OBJECT_PTR(ref);
- if (ref->prop.doc_comment) {
- RETURN_STR_COPY(ref->prop.doc_comment);
+ if (ref->prop && ref->prop->doc_comment) {
+ RETURN_STR_COPY(ref->prop->doc_comment);
}
RETURN_FALSE;
}
GET_REFLECTION_OBJECT_PTR(ref);
- if (!ZEND_TYPE_IS_SET(ref->prop.type)) {
+ if (!ref->prop || !ZEND_TYPE_IS_SET(ref->prop->type)) {
RETURN_NULL();
}
- reflection_type_factory(ref->prop.type, return_value);
+ reflection_type_factory(ref->prop->type, return_value);
}
/* }}} */
GET_REFLECTION_OBJECT_PTR(ref);
- RETVAL_BOOL(ZEND_TYPE_IS_SET(ref->prop.type));
+ RETVAL_BOOL(ref->prop && ZEND_TYPE_IS_SET(ref->prop->type));
}
/* }}} */