Skip to content

Register Attributes Without Changes to ZEND APIs #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 4, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 12 additions & 13 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -3515,7 +3515,7 @@ static zend_always_inline zend_bool is_persistent_class(zend_class_entry *ce) {
&& ce->info.internal.module->type == MODULE_PERSISTENT;
}

ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes, zend_type type) /* {{{ */
ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type) /* {{{ */
{
zend_property_info *property_info, *property_info_ptr;

Expand Down Expand Up @@ -3608,13 +3608,13 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name
property_info->name = zend_new_interned_string(property_info->name);
property_info->flags = access_type;
property_info->doc_comment = doc_comment;
property_info->attributes = attributes;
property_info->attributes = NULL;
property_info->ce = ce;
property_info->type = type;

zend_hash_update_ptr(&ce->properties_info, name, property_info);

return SUCCESS;
return property_info;
}
/* }}} */

Expand Down Expand Up @@ -3745,16 +3745,17 @@ ZEND_API int zend_try_assign_typed_ref_zval_ex(zend_reference *ref, zval *zv, ze
}
/* }}} */

ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes) /* {{{ */
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
{
return zend_declare_typed_property(ce, name, property, access_type, doc_comment, attributes, (zend_type) ZEND_TYPE_INIT_NONE(0));
zend_declare_typed_property(ce, name, property, access_type, doc_comment, (zend_type) ZEND_TYPE_INIT_NONE(0));
return SUCCESS;
}
/* }}} */

ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type) /* {{{ */
{
zend_string *key = zend_string_init(name, name_length, is_persistent_class(ce));
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL, NULL);
int ret = zend_declare_property_ex(ce, key, property, access_type, NULL);
zend_string_release(key);
return ret;
}
Expand Down Expand Up @@ -3814,7 +3815,7 @@ ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *nam
}
/* }}} */

ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment, HashTable *attributes) /* {{{ */
ZEND_API zend_class_constant *zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment) /* {{{ */
{
zend_class_constant *c;

Expand All @@ -3841,7 +3842,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
ZVAL_COPY_VALUE(&c->value, value);
Z_ACCESS_FLAGS(c->value) = access_type;
c->doc_comment = doc_comment;
c->attributes = attributes;
c->attributes = NULL;
c->ce = ce;
if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
Expand All @@ -3852,24 +3853,22 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
"Cannot redefine class constant %s::%s", ZSTR_VAL(ce->name), ZSTR_VAL(name));
}

return SUCCESS;
return c;
}
/* }}} */

ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value) /* {{{ */
{
int ret;

zend_string *key;

if (ce->type == ZEND_INTERNAL_CLASS) {
key = zend_string_init_interned(name, name_length, 1);
} else {
key = zend_string_init(name, name_length, 0);
}
ret = zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL, NULL);
zend_declare_class_constant_ex(ce, key, value, ZEND_ACC_PUBLIC, NULL);
zend_string_release(key);
return ret;
return SUCCESS;
}
/* }}} */

Expand Down
6 changes: 3 additions & 3 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,9 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
ZEND_API const char *zend_get_module_version(const char *module_name);
ZEND_API int zend_get_module_started(const char *module_name);

ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes, zend_type type);
ZEND_API zend_property_info *zend_declare_typed_property(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, zend_type type);

ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment, HashTable *attributes);
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment);
ZEND_API int zend_declare_property(zend_class_entry *ce, const char *name, size_t name_length, zval *property, int access_type);
ZEND_API int zend_declare_property_null(zend_class_entry *ce, const char *name, size_t name_length, int access_type);
ZEND_API int zend_declare_property_bool(zend_class_entry *ce, const char *name, size_t name_length, zend_long value, int access_type);
Expand All @@ -362,7 +362,7 @@ ZEND_API int zend_declare_property_double(zend_class_entry *ce, const char *name
ZEND_API int zend_declare_property_string(zend_class_entry *ce, const char *name, size_t name_length, const char *value, int access_type);
ZEND_API int zend_declare_property_stringl(zend_class_entry *ce, const char *name, size_t name_length, const char *value, size_t value_len, int access_type);

ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment, HashTable *attributes);
ZEND_API zend_class_constant *zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *name, zval *value, int access_type, zend_string *doc_comment);
ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name, size_t name_length, zval *value);
ZEND_API int zend_declare_class_constant_null(zend_class_entry *ce, const char *name, size_t name_length);
ZEND_API int zend_declare_class_constant_long(zend_class_entry *ce, const char *name, size_t name_length, zend_long value);
Expand Down
75 changes: 46 additions & 29 deletions Zend/zend_attributes.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,6 @@ ZEND_API zend_attributes_internal_validator zend_attribute_get_validator(zend_st
return zend_hash_find_ptr(&internal_validators, lcname);
}

ZEND_API void zend_attribute_free(zend_attribute *attr, int persistent)
{
uint32_t i;

zend_string_release(attr->name);
zend_string_release(attr->lcname);

for (i = 0; i < attr->argc; i++) {
zval_ptr_dtor(&attr->argv[i]);
}

pefree(attr, persistent);
}

static zend_attribute *get_attribute(HashTable *attributes, zend_string *lcname, uint32_t offset)
{
if (attributes) {
Expand Down Expand Up @@ -84,9 +70,52 @@ ZEND_API zend_attribute *zend_get_parameter_attribute_str(HashTable *attributes,
return get_attribute_str(attributes, str, len, offset + 1);
}

static void attribute_ptr_dtor(zval *v)
static zend_always_inline void free_attribute(zend_attribute *attr, int persistent)
{
zend_attribute_free((zend_attribute *) Z_PTR_P(v), 1);
uint32_t i;

zend_string_release(attr->name);
zend_string_release(attr->lcname);

for (i = 0; i < attr->argc; i++) {
zval_ptr_dtor(&attr->argv[i]);
}

pefree(attr, persistent);
}

static void attr_free(zval *v)
{
free_attribute((zend_attribute *) Z_PTR_P(v), 0);
}

static void attr_pfree(zval *v)
{
free_attribute((zend_attribute *) Z_PTR_P(v), 1);
}

ZEND_API zend_attribute *zend_add_attribute(HashTable **attributes, zend_bool persistent, uint32_t offset, zend_string *name, uint32_t argc)
{
if (*attributes == NULL) {
*attributes = pemalloc(sizeof(HashTable), persistent);
zend_hash_init(*attributes, 8, NULL, persistent ? attr_pfree : attr_free, persistent);
}

zend_attribute *attr = pemalloc(ZEND_ATTRIBUTE_SIZE(argc), persistent);

if (persistent == ((GC_FLAGS(name) & IS_STR_PERSISTENT) != 0)) {
attr->name = zend_string_copy(name);
} else {
attr->name = zend_string_dup(name, persistent);
}

attr->lcname = zend_string_tolower_ex(attr->name, persistent);
attr->offset = offset;
attr->argc = argc;

zend_hash_next_index_insert_ptr(*attributes, attr);

return attr;
}

ZEND_API void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator validator)
Expand All @@ -100,19 +129,7 @@ ZEND_API void zend_compiler_attribute_register(zend_class_entry *ce, zend_attrib
zend_hash_update_ptr(&internal_validators, lcname, validator);
zend_string_release(lcname);

if (ce->attributes == NULL) {
ce->attributes = pemalloc(sizeof(HashTable), 1);
zend_hash_init(ce->attributes, 8, NULL, attribute_ptr_dtor, 1);
}

zend_attribute *attr = pemalloc(ZEND_ATTRIBUTE_SIZE(0), 1);

attr->name = zend_string_copy(zend_ce_php_attribute->name);
attr->lcname = zend_string_tolower_ex(attr->name, 1);
attr->offset = 0;
attr->argc = 0;

zend_hash_next_index_insert_ptr(ce->attributes, attr);
zend_add_class_attribute(ce, zend_ce_php_attribute->name, 0);
}

void zend_register_attribute_ce(void)
Expand Down
31 changes: 28 additions & 3 deletions Zend/zend_attributes.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ typedef struct _zend_attribute {

typedef void (*zend_attributes_internal_validator)(zend_attribute *attr, int target);

ZEND_API void zend_attribute_free(zend_attribute *attr, int persistent);

ZEND_API zend_attribute *zend_get_attribute(HashTable *attributes, zend_string *lcname);
ZEND_API zend_attribute *zend_get_attribute_str(HashTable *attributes, const char *str, size_t len);

Expand All @@ -37,8 +35,35 @@ ZEND_API zend_attribute *zend_get_parameter_attribute_str(HashTable *attributes,
ZEND_API void zend_compiler_attribute_register(zend_class_entry *ce, zend_attributes_internal_validator validator);
ZEND_API zend_attributes_internal_validator zend_attribute_get_validator(zend_string *lcname);

void zend_register_attribute_ce(void);
ZEND_API zend_attribute *zend_add_attribute(HashTable **attributes, zend_bool persistent, uint32_t offset, zend_string *name, uint32_t argc);

END_EXTERN_C()

static zend_always_inline zend_attribute *zend_add_class_attribute(zend_class_entry *ce, zend_string *name, uint32_t argc)
{
return zend_add_attribute(&ce->attributes, ce->type != ZEND_USER_CLASS, 0, name, argc);
}

static zend_always_inline zend_attribute *zend_add_function_attribute(zend_function *func, zend_string *name, uint32_t argc)
{
return zend_add_attribute(&func->common.attributes, func->common.type != ZEND_USER_FUNCTION, 0, name, argc);
}

static zend_always_inline zend_attribute *zend_add_parameter_attribute(zend_function *func, uint32_t offset, zend_string *name, uint32_t argc)
{
return zend_add_attribute(&func->common.attributes, func->common.type != ZEND_USER_FUNCTION, offset + 1, name, argc);
}

static zend_always_inline zend_attribute *zend_add_property_attribute(zend_class_entry *ce, zend_property_info *info, zend_string *name, uint32_t argc)
{
return zend_add_attribute(&info->attributes, ce->type != ZEND_USER_CLASS, 0, name, argc);
}

static zend_always_inline zend_attribute *zend_add_class_constant_attribute(zend_class_entry *ce, zend_class_constant *c, zend_string *name, uint32_t argc)
{
return zend_add_attribute(&c->attributes, ce->type != ZEND_USER_CLASS, 0, name, argc);
}

void zend_register_attribute_ce(void);

#endif
Loading