Skip to content

Commit

Permalink
Fix #1879 (#1881)
Browse files Browse the repository at this point in the history
  • Loading branch information
dreamsxin authored Jun 28, 2019
1 parent 765f726 commit f5f8f2a
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 137 deletions.
92 changes: 33 additions & 59 deletions ext/kernel/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,16 +832,12 @@ int zephir_array_key_exists(zval *arr, zval *key)
*/
void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int types_length, int types_count, va_list ap)
{
long old_l[ZEPHIR_MAX_ARRAY_LEVELS], old_ll[ZEPHIR_MAX_ARRAY_LEVELS];
char *s, *old_s[ZEPHIR_MAX_ARRAY_LEVELS], old_type[ZEPHIR_MAX_ARRAY_LEVELS];
zval *item, *old_item[ZEPHIR_MAX_ARRAY_LEVELS];
char *s;
zval *item;
zval pzv;
zend_array *p, *old_p[ZEPHIR_MAX_ARRAY_LEVELS];
zval tmp;
zend_array *p;
int i, j, l, ll, re_update, must_continue, wrap_tmp;

assert(types_length < ZEPHIR_MAX_ARRAY_LEVELS);
ZVAL_UNDEF(&tmp);
ZVAL_UNDEF(&pzv);

if (Z_TYPE_P(arr) != IS_ARRAY) {
Expand All @@ -851,31 +847,35 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int
p = Z_ARRVAL_P(arr);

for (i = 0; i < types_length; ++i) {
zval tmp;
zval fetched;
ZVAL_UNDEF(&fetched);

re_update = 0;
must_continue = 0;
wrap_tmp = 0;

old_p[i] = p;
ZVAL_ARR(&pzv, p);
switch (types[i]) {

case 's':
s = va_arg(ap, char*);
l = va_arg(ap, int);
old_s[i] = s;
old_l[i] = l;
if (zephir_array_isset_string_fetch(&fetched, &pzv, s, l, 1)) {
if (Z_TYPE(fetched) == IS_ARRAY) {
if (i == (types_length - 1)) {
re_update = !Z_REFCOUNTED(pzv) || (Z_REFCOUNT(pzv) > 1 && !Z_ISREF(pzv));
zephir_array_update_string(&pzv, s, l, value, PH_COPY | PH_SEPARATE);
p = Z_ARRVAL(pzv);
} else {
p = Z_ARRVAL(fetched);
Z_TRY_ADDREF(fetched);
re_update = !Z_REFCOUNTED(fetched) || (Z_REFCOUNT(fetched) > 1 && !Z_ISREF(fetched));
if (re_update) {
ZVAL_DUP(&tmp, &fetched);
zephir_array_update_string(&pzv, s, l, &tmp, 0);
p = Z_ARRVAL(tmp);
} else {
p = Z_ARRVAL(fetched);
}
}
must_continue = 1;
}
Expand All @@ -902,16 +902,21 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int

case 'l':
ll = va_arg(ap, long);
old_ll[i] = ll;
if (zephir_array_isset_long_fetch(&fetched, &pzv, ll, 1)) {
if (Z_TYPE(fetched) == IS_ARRAY) {
if (i == (types_length - 1)) {
re_update = !Z_REFCOUNTED(pzv) || (Z_REFCOUNT(pzv) > 1 && !Z_ISREF(pzv));
zephir_array_update_long(&pzv, ll, value, PH_COPY | PH_SEPARATE ZEPHIR_DEBUG_PARAMS_DUMMY);
p = Z_ARRVAL(pzv);
} else {
p = Z_ARRVAL(fetched);
Z_TRY_ADDREF(fetched);
re_update = !Z_REFCOUNTED(fetched) || (Z_REFCOUNT(fetched) > 1 && !Z_ISREF(fetched));
if (re_update) {
ZVAL_DUP(&tmp, &fetched);
zephir_array_update_long(&pzv, ll, &tmp, 0 ZEPHIR_DEBUG_PARAMS_DUMMY);
p = Z_ARRVAL(tmp);
} else {
p = Z_ARRVAL(fetched);
}
}
must_continue = 1;
}
Expand All @@ -938,16 +943,21 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int

case 'z':
item = va_arg(ap, zval*);
old_item[i] = item;
if (zephir_array_isset_fetch(&fetched, &pzv, item, 1)) {
if (Z_TYPE(fetched) == IS_ARRAY) {
if (i == (types_length - 1)) {
re_update = !Z_REFCOUNTED(pzv) || (Z_REFCOUNT(pzv) > 1 && !Z_ISREF(pzv));
zephir_array_update_zval(&pzv, item, value, PH_COPY | PH_SEPARATE);
p = Z_ARRVAL(pzv);
} else {
p = Z_ARRVAL(fetched);
Z_TRY_ADDREF(fetched);
re_update = !Z_REFCOUNTED(fetched) || (Z_REFCOUNT(fetched) > 1 && !Z_ISREF(fetched));
if (re_update) {
ZVAL_DUP(&tmp, &fetched);
zephir_array_update_zval(&pzv, item, &tmp, 0);
p = Z_ARRVAL(tmp);
} else {
p = Z_ARRVAL(fetched);
}
}
must_continue = 1;
}
Expand All @@ -974,50 +984,14 @@ void zephir_array_update_multi_ex(zval *arr, zval *value, const char *types, int

case 'a':
re_update = !Z_REFCOUNTED(pzv) || (Z_REFCOUNT(pzv) > 1 && !Z_ISREF(pzv));
zephir_array_append(&pzv, value, PH_SEPARATE ZEPHIR_DEBUG_PARAMS_DUMMY);
p = Z_ARRVAL(pzv);
break;
}

if (re_update) {
for (j = i - 1; j >= 0; j--) {
zval old_pzv;

if (!re_update) {
break;
}

ZVAL_ARR(&pzv, old_p[j]);
re_update = !Z_REFCOUNTED(pzv) || (Z_REFCOUNT(pzv) > 1 && !Z_ISREF(pzv));

if (j == i - 1) {
ZVAL_ARR(&old_pzv, p);
if (re_update) {
zephir_array_append(&pzv, value, PH_COPY | PH_SEPARATE ZEPHIR_DEBUG_PARAMS_DUMMY);
} else {
ZVAL_ARR(&old_pzv, old_p[j + 1]);
}

switch (old_type[j])
{
case 's':
zephir_array_update_string(&pzv, old_s[j], old_l[j], &old_pzv, PH_SEPARATE);
break;
case 'l':
zephir_array_update_long(&pzv, old_ll[j], &old_pzv, PH_SEPARATE ZEPHIR_DEBUG_PARAMS_DUMMY);
break;
case 'z':
zephir_array_update_zval(&pzv, old_item[j], &old_pzv, PH_SEPARATE);
break;
}
old_p[j] = Z_ARRVAL(pzv);
if (wrap_tmp) {
p = Z_ARRVAL(tmp);
wrap_tmp = 0;
zephir_array_append(&pzv, value, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
}
}
}

if (i != (types_length - 1)) {
old_type[i] = types[i];
p = Z_ARRVAL(pzv);
break;
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion ext/kernel/memory.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void ZEPHIR_FASTCALL zephir_memory_grow_stack(zephir_method_globals *g, const ch
#endif
}

void zephir_memory_restore_stack(zephir_method_globals *g, const char *func)
void ZEPHIR_FASTCALL zephir_memory_restore_stack(zephir_method_globals *g, const char *func)
{
size_t i;
zephir_memory_entry *prev, *active_memory;
Expand Down
16 changes: 15 additions & 1 deletion ext/kernel/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,16 @@ int zephir_clone(zval *destination, zval *obj)
int zephir_isset_property(zval *object, const char *property_name, unsigned int property_length)
{
if (Z_TYPE_P(object) == IS_OBJECT) {
/*
if (Z_OBJ_HANDLER_P(object, has_property)) {
zval member;
int retval;
ZVAL_STRINGL(&member, property_name, property_length);
retval = Z_OBJ_HT_P(object)->has_property(object, &member, 2, NULL);
zval_ptr_dtor(&member);
return retval;
}
*/
if (EXPECTED(zend_hash_str_exists(&Z_OBJCE_P(object)->properties_info, property_name, property_length))) {
return 1;
}
Expand All @@ -385,7 +395,11 @@ int zephir_isset_property_zval(zval *object, const zval *property)
{
if (Z_TYPE_P(object) == IS_OBJECT) {
if (Z_TYPE_P(property) == IS_STRING) {

/*
if (Z_OBJ_HANDLER_P(object, has_property)) {
return Z_OBJ_HT_P(object)->has_property(object, property, 2, NULL);
}
*/
if (EXPECTED(zend_hash_str_exists(&Z_OBJCE_P(object)->properties_info, Z_STRVAL_P(property), Z_STRLEN_P(property)))) {
return 1;
} else {
Expand Down
70 changes: 58 additions & 12 deletions ext/test/vars.zep.c

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion ext/test/vars.zep.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f5f8f2a

Please sign in to comment.