summaryrefslogtreecommitdiff
path: root/Zend/zend_API.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend_API.c')
-rw-r--r--Zend/zend_API.c752
1 files changed, 387 insertions, 365 deletions
diff --git a/Zend/zend_API.c b/Zend/zend_API.c
index fedef6f574..87d6272980 100644
--- a/Zend/zend_API.c
+++ b/Zend/zend_API.c
@@ -19,8 +19,6 @@
+----------------------------------------------------------------------+
*/
-/* $Id$ */
-
#include "zend.h"
#include "zend_execute.h"
#include "zend_API.h"
@@ -45,67 +43,6 @@ static zend_module_entry **module_post_deactivate_handlers;
static zend_class_entry **class_cleanup_handlers;
-/* this function doesn't check for too many parameters */
-ZEND_API int zend_get_parameters(int ht, int param_count, ...) /* {{{ */
-{
- int arg_count;
- va_list ptr;
- zval **param, *param_ptr;
-
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
- arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
-
- if (param_count>arg_count) {
- return FAILURE;
- }
-
- va_start(ptr, param_count);
-
- while (param_count-->0) {
- param = va_arg(ptr, zval **);
- if (!Z_ISREF_P(param_ptr) && Z_REFCOUNT_P(param_ptr) > 1) {
- zval new_tmp;
-
- ZVAL_DUP(&new_tmp, param_ptr);
- Z_DELREF_P(param_ptr);
- ZVAL_COPY_VALUE(param_ptr, &new_tmp);
- }
- *param = param_ptr;
- param_ptr++;
- }
- va_end(ptr);
-
- return SUCCESS;
-}
-/* }}} */
-
-/* Zend-optimized Extended functions */
-/* this function doesn't check for too many parameters */
-ZEND_API int zend_get_parameters_ex(int param_count, ...) /* {{{ */
-{
- int arg_count;
- va_list ptr;
- zval **param, *param_ptr;
-
- param_ptr = ZEND_CALL_ARG(EG(current_execute_data), 1);
- arg_count = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
-
- if (param_count>arg_count) {
- return FAILURE;
- }
-
- va_start(ptr, param_count);
- while (param_count-->0) {
- param = va_arg(ptr, zval **);
- *param = param_ptr;
- param_ptr++;
- }
- va_end(ptr);
-
- return SUCCESS;
-}
-/* }}} */
-
ZEND_API int _zend_get_parameters_array_ex(int param_count, zval *argument_array) /* {{{ */
{
zval *param_ptr;
@@ -141,9 +78,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array) /
}
while (param_count-->0) {
- if (Z_REFCOUNTED_P(param_ptr)) {
- Z_ADDREF_P(param_ptr);
- }
+ Z_TRY_ADDREF_P(param_ptr);
zend_hash_next_index_insert_new(Z_ARRVAL_P(argument_array), param_ptr);
param_ptr++;
}
@@ -168,9 +103,9 @@ ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
case IS_FALSE:
case IS_TRUE:
case _IS_BOOL:
- return "boolean";
+ return "bool";
case IS_LONG:
- return "integer";
+ return "int";
case IS_DOUBLE:
return "float";
case IS_STRING:
@@ -189,6 +124,8 @@ ZEND_API char *zend_get_type_by_const(int type) /* {{{ */
return "array";
case IS_VOID:
return "void";
+ case _IS_NUMBER:
+ return "number";
default:
return "unknown";
}
@@ -232,14 +169,74 @@ ZEND_API zend_string *zend_zval_get_type(const zval *arg) /* {{{ */
}
/* }}} */
-ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_bool throw_, int num_args, int min_num_args, int max_num_args) /* {{{ */
+ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_error(void) /* {{{ */
+{
+ int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
+ zend_function *active_function = EG(current_execute_data)->func;
+ const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
+
+ zend_internal_argument_count_error(
+ ZEND_ARG_USES_STRICT_TYPES(),
+ "%s%s%s() expects %s %d parameter%s, %d given",
+ class_name, \
+ class_name[0] ? "::" : "", \
+ ZSTR_VAL(active_function->common.function_name),
+ "exactly",
+ 0,
+ "s",
+ num_args);
+ return FAILURE;
+}
+/* }}} */
+
+ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_exception(void) /* {{{ */
+{
+ int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
+ zend_function *active_function = EG(current_execute_data)->func;
+ const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
+
+ zend_internal_argument_count_error(
+ 1,
+ "%s%s%s() expects %s %d parameter%s, %d given",
+ class_name, \
+ class_name[0] ? "::" : "", \
+ ZSTR_VAL(active_function->common.function_name),
+ "exactly",
+ 0,
+ "s",
+ num_args);
+ return FAILURE;
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int min_num_args, int max_num_args) /* {{{ */
+{
+ int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
+ zend_function *active_function = EG(current_execute_data)->func;
+ const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
+
+ zend_internal_argument_count_error(
+ ZEND_ARG_USES_STRICT_TYPES(),
+ "%s%s%s() expects %s %d parameter%s, %d given",
+ class_name, \
+ class_name[0] ? "::" : "", \
+ ZSTR_VAL(active_function->common.function_name),
+ min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most",
+ num_args < min_num_args ? min_num_args : max_num_args,
+ (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s",
+ num_args);
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_exception(int min_num_args, int max_num_args) /* {{{ */
{
+ int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data));
zend_function *active_function = EG(current_execute_data)->func;
const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : "";
zend_internal_argument_count_error(
- throw_ || ZEND_ARG_USES_STRICT_TYPES(),
- "%s%s%s() expects %s %d parameter%s, %d given",
+ 1,
+ "%s%s%s() expects %s %d parameter%s, %d given",
class_name, \
class_name[0] ? "::" : "", \
ZSTR_VAL(active_function->common.function_name),
@@ -250,7 +247,21 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_boo
}
/* }}} */
-ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(zend_bool throw_, int num, zend_expected_type expected_type, zval *arg) /* {{{ */
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */
+{
+ const char *space;
+ const char *class_name = get_active_class_name(&space);
+ static const char * const expected_error[] = {
+ Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_STR)
+ NULL
+ };
+
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
+ class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_exception(int num, zend_expected_type expected_type, zval *arg) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
@@ -259,36 +270,60 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(zend_bool
NULL
};
- zend_internal_type_error(throw_ || ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
+ zend_internal_type_error(1, "%s%s%s() expects parameter %d to be %s, %s given",
class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg));
}
/* }}} */
-ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(zend_bool throw_, int num, char *name, zval *arg) /* {{{ */
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
- zend_internal_type_error(throw_ || ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given",
class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
}
/* }}} */
-ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_, int severity, int num, char *error) /* {{{ */
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_exception(int num, char *name, zval *arg) /* {{{ */
{
const char *space;
const char *class_name = get_active_class_name(&space);
- if (severity == E_WARNING) {
- zend_internal_type_error(throw_ || ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s",
- class_name, space, get_active_function_name(), num, error);
- } else if (severity == E_ERROR) {
- zend_throw_error(zend_ce_type_error, "%s%s%s() expects parameter %d to be a valid callback, %s",
- class_name, space, get_active_function_name(), num, error);
- } else {
- zend_error(severity, "%s%s%s() expects parameter %d to be a valid callback, %s",
- class_name, space, get_active_function_name(), num, error);
- }
+ zend_internal_type_error(1, "%s%s%s() expects parameter %d to be %s, %s given",
+ class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg));
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error) /* {{{ */
+{
+ const char *space;
+ const char *class_name = get_active_class_name(&space);
+
+ zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s",
+ class_name, space, get_active_function_name(), num, error);
+ efree(error);
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_exception(int num, char *error) /* {{{ */
+{
+ const char *space;
+ const char *class_name = get_active_class_name(&space);
+
+ zend_internal_type_error(1, "%s%s%s() expects parameter %d to be a valid callback, %s",
+ class_name, space, get_active_function_name(), num, error);
+ efree(error);
+}
+/* }}} */
+
+ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_deprecated(int num, char *error) /* {{{ */
+{
+ const char *space;
+ const char *class_name = get_active_class_name(&space);
+
+ zend_error(E_DEPRECATED, "%s%s%s() expects parameter %d to be a valid callback, %s",
+ class_name, space, get_active_function_name(), num, error);
efree(error);
}
/* }}} */
@@ -494,12 +529,13 @@ ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest
zval rv;
zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv);
- Z_ADDREF_P(z);
if (Z_TYPE_P(z) != IS_OBJECT) {
- zval_dtor(arg);
- ZVAL_NULL(arg);
- if (!zend_make_printable_zval(z, arg)) {
+ zval_ptr_dtor(arg);
+ if (Z_TYPE_P(z) == IS_STRING) {
ZVAL_COPY_VALUE(arg, z);
+ } else {
+ ZVAL_STR(arg, zval_get_string_func(z));
+ zval_ptr_dtor(z);
}
*dest = Z_STR_P(arg);
return 1;
@@ -558,7 +594,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
}
if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L')) {
- return "integer";
+ return "int";
}
}
break;
@@ -626,7 +662,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
}
if (!zend_parse_arg_bool(arg, p, is_null, check_null)) {
- return "boolean";
+ return "bool";
}
}
break;
@@ -729,7 +765,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons
if (check_null && Z_TYPE_P(arg) == IS_NULL) {
fci->size = 0;
- fcc->initialized = 0;
+ fcc->function_handler = 0;
break;
}
@@ -1084,15 +1120,6 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this
}
/* }}} */
-/* Argument parsing API -- andrei */
-ZEND_API int _array_init(zval *arg, uint32_t size ZEND_FILE_LINE_DC) /* {{{ */
-{
- ZVAL_NEW_ARR(arg);
- _zend_hash_init(Z_ARRVAL_P(arg), size, ZVAL_PTR_DTOR, 0 ZEND_FILE_LINE_RELAY_CC);
- return SUCCESS;
-}
-/* }}} */
-
/* This function should be called after the constructor has been called
* because it may call __set from the uninitialized object otherwise. */
ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
@@ -1118,74 +1145,46 @@ ZEND_API void zend_merge_properties(zval *obj, HashTable *properties) /* {{{ */
ZEND_API int zend_update_class_constants(zend_class_entry *class_type) /* {{{ */
{
if (!(class_type->ce_flags & ZEND_ACC_CONSTANTS_UPDATED)) {
+ zend_class_entry *ce;
+ zend_class_constant *c;
+ zval *val;
+ zend_property_info *prop_info;
+
if (class_type->parent) {
if (UNEXPECTED(zend_update_class_constants(class_type->parent) != SUCCESS)) {
return FAILURE;
}
}
- if (!CE_STATIC_MEMBERS(class_type) && class_type->default_static_members_count) {
- /* initialize static members of internal class */
- int i;
- zval *p;
-
-#if ZTS
- CG(static_members_table)[(zend_intptr_t)(class_type->static_members_table)] = emalloc(sizeof(zval) * class_type->default_static_members_count);
-#else
- class_type->static_members_table = emalloc(sizeof(zval) * class_type->default_static_members_count);
-#endif
- for (i = 0; i < class_type->default_static_members_count; i++) {
- p = &class_type->default_static_members_table[i];
- if (Z_ISREF_P(p) &&
- class_type->parent &&
- i < class_type->parent->default_static_members_count &&
- p == &class_type->parent->default_static_members_table[i] &&
- Z_TYPE(CE_STATIC_MEMBERS(class_type->parent)[i]) != IS_UNDEF
- ) {
- zval *q = &CE_STATIC_MEMBERS(class_type->parent)[i];
-
- ZVAL_NEW_REF(q, q);
- ZVAL_COPY_VALUE(&CE_STATIC_MEMBERS(class_type)[i], q);
- Z_ADDREF_P(q);
- } else {
- ZVAL_DUP(&CE_STATIC_MEMBERS(class_type)[i], p);
+ ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) {
+ val = &c->value;
+ if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
+ if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) {
+ return FAILURE;
}
}
- } else {
- zend_class_entry *ce;
- zend_class_constant *c;
- zval *val;
- zend_property_info *prop_info;
-
- ZEND_HASH_FOREACH_PTR(&class_type->constants_table, c) {
- val = &c->value;
- if (Z_CONSTANT_P(val)) {
- if (UNEXPECTED(zval_update_constant_ex(val, c->ce) != SUCCESS)) {
- return FAILURE;
- }
- }
- } ZEND_HASH_FOREACH_END();
+ } ZEND_HASH_FOREACH_END();
- ce = class_type;
- while (ce) {
- ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
- if (prop_info->ce == ce) {
- if (prop_info->flags & ZEND_ACC_STATIC) {
- val = CE_STATIC_MEMBERS(class_type) + prop_info->offset;
- } else {
- val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0));
- }
- ZVAL_DEREF(val);
- if (Z_CONSTANT_P(val)) {
- if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
- return FAILURE;
- }
+ ce = class_type;
+ while (ce) {
+ ZEND_HASH_FOREACH_PTR(&ce->properties_info, prop_info) {
+ if (prop_info->ce == ce) {
+ if (prop_info->flags & ZEND_ACC_STATIC) {
+ val = CE_STATIC_MEMBERS(class_type) + prop_info->offset;
+ } else {
+ val = (zval*)((char*)class_type->default_properties_table + prop_info->offset - OBJ_PROP_TO_OFFSET(0));
+ }
+ ZVAL_DEREF(val);
+ if (Z_TYPE_P(val) == IS_CONSTANT_AST) {
+ if (UNEXPECTED(zval_update_constant_ex(val, ce) != SUCCESS)) {
+ return FAILURE;
}
}
- } ZEND_HASH_FOREACH_END();
- ce = ce->parent;
- }
+ }
+ } ZEND_HASH_FOREACH_END();
+ ce = ce->parent;
}
+
class_type->ce_flags |= ZEND_ACC_CONSTANTS_UPDATED;
}
@@ -1200,15 +1199,19 @@ ZEND_API void object_properties_init(zend_object *object, zend_class_entry *clas
zval *dst = object->properties_table;
zval *end = src + class_type->default_properties_count;
- do {
-#if ZTS
- ZVAL_DUP(dst, src);
-#else
- ZVAL_COPY(dst, src);
-#endif
- src++;
- dst++;
- } while (src != end);
+ if (UNEXPECTED(class_type->type == ZEND_INTERNAL_CLASS)) {
+ do {
+ ZVAL_COPY_OR_DUP(dst, src);
+ src++;
+ dst++;
+ } while (src != end);
+ } else {
+ do {
+ ZVAL_COPY(dst, src);
+ src++;
+ dst++;
+ } while (src != end);
+ }
object->properties = NULL;
}
}
@@ -1254,10 +1257,10 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
if (class_name && class_name[0] != '*') {
zend_string *cname = zend_string_init(class_name, strlen(class_name), 0);
EG(fake_scope) = zend_lookup_class(cname);
- zend_string_release(cname);
+ zend_string_release_ex(cname, 0);
}
property_info = zend_get_property_info(object->ce, pname, 1);
- zend_string_release(pname);
+ zend_string_release_ex(pname, 0);
EG(fake_scope) = prev_scope;
} else {
property_info = ZEND_WRONG_PROPERTY_INFO;
@@ -1298,7 +1301,7 @@ ZEND_API void object_properties_load(zend_object *object, HashTable *properties)
* class and all props being public. If only a subset is given or the class
* has protected members then you need to merge the properties separately by
* calling zend_merge_properties(). */
-ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties ZEND_FILE_LINE_DC) /* {{{ */
+ZEND_API int object_and_properties_init(zval *arg, zend_class_entry *class_type, HashTable *properties) /* {{{ */
{
if (UNEXPECTED(class_type->ce_flags & (ZEND_ACC_INTERFACE|ZEND_ACC_TRAIT|ZEND_ACC_IMPLICIT_ABSTRACT_CLASS|ZEND_ACC_EXPLICIT_ABSTRACT_CLASS))) {
if (class_type->ce_flags & ZEND_ACC_INTERFACE) {
@@ -1335,104 +1338,103 @@ ZEND_API int _object_and_properties_init(zval *arg, zend_class_entry *class_type
}
/* }}} */
-ZEND_API int _object_init_ex(zval *arg, zend_class_entry *class_type ZEND_FILE_LINE_DC) /* {{{ */
+ZEND_API int object_init_ex(zval *arg, zend_class_entry *class_type) /* {{{ */
{
- return _object_and_properties_init(arg, class_type, 0 ZEND_FILE_LINE_RELAY_CC);
+ return object_and_properties_init(arg, class_type, 0);
}
/* }}} */
-ZEND_API int _object_init(zval *arg ZEND_FILE_LINE_DC) /* {{{ */
+ZEND_API int object_init(zval *arg) /* {{{ */
{
- return _object_init_ex(arg, zend_standard_class_def ZEND_FILE_LINE_RELAY_CC);
+ ZVAL_OBJ(arg, zend_objects_new(zend_standard_class_def));
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_long_ex(zval *arg, const char *key, size_t key_len, zend_long n) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_LONG(&tmp, n);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_null_ex(zval *arg, const char *key, size_t key_len) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_NULL(&tmp);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_bool_ex(zval *arg, const char *key, size_t key_len, int b) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_BOOL(&tmp, b);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_resource_ex(zval *arg, const char *key, size_t key_len, zend_resource *r) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_RES(&tmp, r);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_double_ex(zval *arg, const char *key, size_t key_len, double d) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_DOUBLE(&tmp, d);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_str_ex(zval *arg, const char *key, size_t key_len, zend_string *str) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_STR(&tmp, str);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_string_ex(zval *arg, const char *key, size_t key_len, const char *str) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_STRING(&tmp, str);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_stringl_ex(zval *arg, const char *key, size_t key_len, const char *str, size_t length) /* {{{ */
{
- zval *ret, tmp;
+ zval tmp;
ZVAL_STRINGL(&tmp, str, length);
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_assoc_zval_ex(zval *arg, const char *key, size_t key_len, zval *value) /* {{{ */
{
- zval *ret;
-
- ret = zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, value);
- return ret ? SUCCESS : FAILURE;
+ zend_symtable_str_update(Z_ARRVAL_P(arg), key, key_len, value);
+ return SUCCESS;
}
/* }}} */
@@ -1441,7 +1443,8 @@ ZEND_API int add_index_long(zval *arg, zend_ulong index, zend_long n) /* {{{ */
zval tmp;
ZVAL_LONG(&tmp, n);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1450,7 +1453,8 @@ ZEND_API int add_index_null(zval *arg, zend_ulong index) /* {{{ */
zval tmp;
ZVAL_NULL(&tmp);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1459,7 +1463,8 @@ ZEND_API int add_index_bool(zval *arg, zend_ulong index, int b) /* {{{ */
zval tmp;
ZVAL_BOOL(&tmp, b);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1468,7 +1473,8 @@ ZEND_API int add_index_resource(zval *arg, zend_ulong index, zend_resource *r) /
zval tmp;
ZVAL_RES(&tmp, r);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1477,7 +1483,8 @@ ZEND_API int add_index_double(zval *arg, zend_ulong index, double d) /* {{{ */
zval tmp;
ZVAL_DOUBLE(&tmp, d);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1486,7 +1493,8 @@ ZEND_API int add_index_str(zval *arg, zend_ulong index, zend_string *str) /* {{{
zval tmp;
ZVAL_STR(&tmp, str);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1495,7 +1503,8 @@ ZEND_API int add_index_string(zval *arg, zend_ulong index, const char *str) /* {
zval tmp;
ZVAL_STRING(&tmp, str);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
@@ -1504,13 +1513,15 @@ ZEND_API int add_index_stringl(zval *arg, zend_ulong index, const char *str, siz
zval tmp;
ZVAL_STRINGL(&tmp, str, length);
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, &tmp);
+ return SUCCESS;
}
/* }}} */
ZEND_API int add_index_zval(zval *arg, zend_ulong index, zval *value) /* {{{ */
{
- return zend_hash_index_update(Z_ARRVAL_P(arg), index, value) ? SUCCESS : FAILURE;
+ zend_hash_index_update(Z_ARRVAL_P(arg), index, value);
+ return SUCCESS;
}
/* }}} */
@@ -1690,9 +1701,7 @@ ZEND_API int array_set_zval_key(HashTable *ht, zval *key, zval *value) /* {{{ */
}
if (result) {
- if (Z_REFCOUNTED_P(result)) {
- Z_ADDREF_P(result);
- }
+ Z_TRY_ADDREF_P(result);
return SUCCESS;
} else {
return FAILURE;
@@ -1708,7 +1717,6 @@ ZEND_API int add_property_long_ex(zval *arg, const char *key, size_t key_len, ze
ZVAL_LONG(&tmp, n);
ZVAL_STRINGL(&z_key, key, key_len);
Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
- zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
}
@@ -1722,7 +1730,6 @@ ZEND_API int add_property_bool_ex(zval *arg, const char *key, size_t key_len, ze
ZVAL_BOOL(&tmp, b);
ZVAL_STRINGL(&z_key, key, key_len);
Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
- zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
}
@@ -1736,7 +1743,6 @@ ZEND_API int add_property_null_ex(zval *arg, const char *key, size_t key_len) /*
ZVAL_NULL(&tmp);
ZVAL_STRINGL(&z_key, key, key_len);
Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
- zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
}
@@ -1764,7 +1770,6 @@ ZEND_API int add_property_double_ex(zval *arg, const char *key, size_t key_len,
ZVAL_DOUBLE(&tmp, d);
ZVAL_STRINGL(&z_key, key, key_len);
Z_OBJ_HANDLER_P(arg, write_property)(arg, &z_key, &tmp, NULL);
- zval_ptr_dtor(&tmp); /* write_property will add 1 to refcount */
zval_ptr_dtor(&z_key);
return SUCCESS;
}
@@ -1846,13 +1851,13 @@ ZEND_API int zend_startup_module_ex(zend_module_entry *module) /* {{{ */
zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);
if ((req_mod = zend_hash_find_ptr(&module_registry, lcname)) == NULL || !req_mod->module_started) {
- zend_string_free(lcname);
+ zend_string_efree(lcname);
/* TODO: Check version relationship */
zend_error(E_CORE_WARNING, "Cannot load module '%s' because required module '%s' is not loaded", module->name, dep->name);
module->module_started = 0;
return FAILURE;
}
- zend_string_free(lcname);
+ zend_string_efree(lcname);
}
++dep;
}
@@ -2034,12 +2039,12 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);
if (zend_hash_exists(&module_registry, lcname) || zend_get_extension(dep->name)) {
- zend_string_free(lcname);
+ zend_string_efree(lcname);
/* TODO: Check version relationship */
zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
return NULL;
}
- zend_string_free(lcname);
+ zend_string_efree(lcname);
}
++dep;
}
@@ -2052,7 +2057,7 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
lcname = zend_new_interned_string(lcname);
if ((module_ptr = zend_hash_add_mem(&module_registry, lcname, module, sizeof(zend_module_entry))) == NULL) {
zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name);
- zend_string_release(lcname);
+ zend_string_release_ex(lcname, 1);
return NULL;
}
module = module_ptr;
@@ -2060,14 +2065,14 @@ ZEND_API zend_module_entry* zend_register_module_ex(zend_module_entry *module) /
if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {
zend_hash_del(&module_registry, lcname);
- zend_string_release(lcname);
+ zend_string_release_ex(lcname, 1);
EG(current_module) = NULL;
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
return NULL;
}
EG(current_module) = NULL;
- zend_string_release(lcname);
+ zend_string_release_ex(lcname, 1);
return module;
}
/* }}} */
@@ -2085,6 +2090,11 @@ ZEND_API void zend_check_magic_method_implementation(const zend_class_entry *ce,
char lcname[16];
size_t name_len;
+ if (ZSTR_VAL(fptr->common.function_name)[0] != '_'
+ || ZSTR_VAL(fptr->common.function_name)[1] != '_') {
+ return;
+ }
+
/* we don't care if the function name is longer, in fact lowercasing only
* the beginning of the name speeds up the check process */
name_len = ZSTR_LEN(fptr->common.function_name);
@@ -2186,7 +2196,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
while (ptr->fname) {
fname_len = strlen(ptr->fname);
internal_function->handler = ptr->handler;
- internal_function->function_name = zend_new_interned_string(zend_string_init(ptr->fname, fname_len, 1));
+ internal_function->function_name = zend_string_init_interned(ptr->fname, fname_len, 1);
internal_function->scope = scope;
internal_function->prototype = NULL;
if (ptr->flags) {
@@ -2269,15 +2279,14 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
return FAILURE;
}
}
- lowercase_name = zend_string_alloc(fname_len, 1);
- zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len);
+ lowercase_name = zend_string_tolower_ex(internal_function->function_name, 1);
lowercase_name = zend_new_interned_string(lowercase_name);
reg_function = malloc(sizeof(zend_internal_function));
memcpy(reg_function, &function, sizeof(zend_internal_function));
if (zend_hash_add_ptr(target_function_table, lowercase_name, reg_function) == NULL) {
unload=1;
free(reg_function);
- zend_string_release(lowercase_name);
+ zend_string_release_ex(lowercase_name, 1);
break;
}
@@ -2293,7 +2302,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
if (reg_function->common.arg_info &&
- (reg_function->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))) {
+ (reg_function->common.fn_flags & (ZEND_ACC_HAS_RETURN_TYPE|ZEND_ACC_HAS_TYPE_HINTS))) {
/* convert "const char*" class type names into "zend_string*" */
uint32_t i;
uint32_t num_args = reg_function->common.num_args + 1;
@@ -2316,7 +2325,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
class_name++;
allow_null = 1;
}
- str = zend_new_interned_string(zend_string_init(class_name, strlen(class_name), 1));
+ str = zend_string_init_interned(class_name, strlen(class_name), 1);
new_arg_info[i].type = ZEND_TYPE_ENCODE_CLASS(str, allow_null);
}
}
@@ -2329,6 +2338,8 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
*/
if ((fname_len == class_name_len) && !ctor && !memcmp(ZSTR_VAL(lowercase_name), lc_class_name, class_name_len+1)) {
ctor = reg_function;
+ } else if (ZSTR_VAL(lowercase_name)[0] != '_' || ZSTR_VAL(lowercase_name)[1] != '_') {
+ reg_function = NULL;
} else if (zend_string_equals_literal(lowercase_name, ZEND_CONSTRUCTOR_FUNC_NAME)) {
ctor = reg_function;
} else if (zend_string_equals_literal(lowercase_name, ZEND_DESTRUCTOR_FUNC_NAME)) {
@@ -2367,7 +2378,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
}
ptr++;
count++;
- zend_string_release(lowercase_name);
+ zend_string_release_ex(lowercase_name, 1);
}
if (unload) { /* before unloading, display all remaining bad function in the module */
if (scope) {
@@ -2380,7 +2391,7 @@ ZEND_API int zend_register_functions(zend_class_entry *scope, const zend_functio
if (zend_hash_exists(target_function_table, lowercase_name)) {
zend_error(error_type, "Function registration failed - duplicate name - %s%s%s", scope ? ZSTR_VAL(scope->name) : "", scope ? "::" : "", ptr->fname);
}
- zend_string_free(lowercase_name);
+ zend_string_efree(lowercase_name);
ptr++;
}
zend_unregister_functions(functions, count, target_function_table);
@@ -2505,7 +2516,7 @@ ZEND_API void zend_unregister_functions(const zend_function_entry *functions, in
lowercase_name = zend_string_alloc(fname_len, 0);
zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ptr->fname, fname_len);
zend_hash_del(target_function_table, lowercase_name);
- zend_string_free(lowercase_name);
+ zend_string_efree(lowercase_name);
ptr++;
i++;
}
@@ -2578,7 +2589,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */
}
module->module_started=0;
- if (module->functions) {
+ if (module->type == MODULE_TEMPORARY && module->functions) {
zend_unregister_functions(module->functions, -1, NULL);
}
@@ -2704,7 +2715,7 @@ ZEND_API int zend_next_free_module(void) /* {{{ */
static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class_entry, uint32_t ce_flags) /* {{{ */
{
zend_class_entry *class_entry = malloc(sizeof(zend_class_entry));
- zend_string *lowercase_name = zend_string_alloc(ZSTR_LEN(orig_class_entry->name), 1);
+ zend_string *lowercase_name;
*class_entry = *orig_class_entry;
class_entry->type = ZEND_INTERNAL_CLASS;
@@ -2716,10 +2727,10 @@ static zend_class_entry *do_register_internal_class(zend_class_entry *orig_class
zend_register_functions(class_entry, class_entry->info.internal.builtin_functions, &class_entry->function_table, MODULE_PERSISTENT);
}
- zend_str_tolower_copy(ZSTR_VAL(lowercase_name), ZSTR_VAL(orig_class_entry->name), ZSTR_LEN(class_entry->name));
+ lowercase_name = zend_string_tolower_ex(orig_class_entry->name, 1);
lowercase_name = zend_new_interned_string(lowercase_name);
zend_hash_update_ptr(CG(class_table), lowercase_name, class_entry);
- zend_string_release(lowercase_name);
+ zend_string_release_ex(lowercase_name, 1);
return class_entry;
}
/* }}} */
@@ -2771,15 +2782,15 @@ ZEND_API zend_class_entry *zend_register_internal_interface(zend_class_entry *or
}
/* }}} */
-ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce) /* {{{ */
+ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zend_class_entry *ce, int persistent) /* {{{ */
{
zend_string *lcname;
if (name[0] == '\\') {
- lcname = zend_string_alloc(name_len-1, 1);
+ lcname = zend_string_alloc(name_len-1, persistent);
zend_str_tolower_copy(ZSTR_VAL(lcname), name+1, name_len-1);
} else {
- lcname = zend_string_alloc(name_len, 1);
+ lcname = zend_string_alloc(name_len, persistent);
zend_str_tolower_copy(ZSTR_VAL(lcname), name, name_len);
}
@@ -2787,7 +2798,7 @@ ZEND_API int zend_register_class_alias_ex(const char *name, size_t name_len, zen
lcname = zend_new_interned_string(lcname);
ce = zend_hash_add_ptr(CG(class_table), lcname, ce);
- zend_string_release(lcname);
+ zend_string_release_ex(lcname, 0);
if (ce) {
ce->refcount++;
return SUCCESS;
@@ -2811,9 +2822,7 @@ ZEND_API int zend_set_hash_symbol(zval *symbol, const char *name, int name_lengt
while (num_symbol_tables-- > 0) {
symbol_table = va_arg(symbol_table_list, HashTable *);
zend_hash_str_update(symbol_table, name, name_length, symbol);
- if (Z_REFCOUNTED_P(symbol)) {
- Z_ADDREF_P(symbol);
- }
+ Z_TRY_ADDREF_P(symbol);
}
va_end(symbol_table_list);
return SUCCESS;
@@ -2872,11 +2881,11 @@ ZEND_API int zend_disable_class(char *class_name, size_t class_name_length) /* {
key = zend_string_alloc(class_name_length, 0);
zend_str_tolower_copy(ZSTR_VAL(key), class_name, class_name_length);
disabled_class = zend_hash_find_ptr(CG(class_table), key);
- zend_string_release(key);
+ zend_string_release_ex(key, 0);
if (!disabled_class) {
return FAILURE;
}
- INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new, NULL, NULL, NULL, NULL, NULL);
+ INIT_CLASS_ENTRY_INIT_METHODS((*disabled_class), disabled_class_new);
disabled_class->create_object = display_disabled_class;
zend_hash_clean(&disabled_class->function_table);
return SUCCESS;
@@ -2948,14 +2957,14 @@ static int zend_is_callable_check_class(zend_string *name, zend_class_entry *sco
if (object &&
instanceof_function(object->ce, scope) &&
- instanceof_function(scope, fcc->calling_scope)) {
+ instanceof_function(scope, ce)) {
fcc->object = object;
fcc->called_scope = object->ce;
} else {
- fcc->called_scope = fcc->calling_scope;
+ fcc->called_scope = ce;
}
} else {
- fcc->called_scope = fcc->object ? fcc->object->ce : fcc->calling_scope;
+ fcc->called_scope = fcc->object ? fcc->object->ce : ce;
}
*strict_class = 1;
ret = 1;
@@ -2967,7 +2976,7 @@ static int zend_is_callable_check_class(zend_string *name, zend_class_entry *sco
}
/* }}} */
-static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, int strict_class, char **error) /* {{{ */
+static zend_always_inline int zend_is_callable_check_func(int check_flags, zval *callable, zend_fcall_info_cache *fcc, int strict_class, char **error) /* {{{ */
{
zend_class_entry *ce_org = fcc->calling_scope;
int retval = 0;
@@ -2978,47 +2987,36 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
HashTable *ftable;
int call_via_handler = 0;
zend_class_entry *scope;
+ zval *zv;
ALLOCA_FLAG(use_heap)
- if (error) {
- *error = NULL;
- }
-
fcc->calling_scope = NULL;
- fcc->function_handler = NULL;
if (!ce_org) {
+ zend_function *func;
zend_string *lmname;
- /* Skip leading \ */
- if (UNEXPECTED(Z_STRVAL_P(callable)[0] == '\\')) {
- ZSTR_ALLOCA_INIT(lmname, Z_STRVAL_P(callable) + 1, Z_STRLEN_P(callable) - 1, use_heap);
- } else {
- lmname = Z_STR_P(callable);
- }
/* Check if function with given name exists.
* This may be a compound name that includes namespace name */
- if (EXPECTED((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL)) {
- if (lmname != Z_STR_P(callable)) {
- ZSTR_ALLOCA_FREE(lmname, use_heap);
- }
- fcc->initialized = 1;
- return 1;
+ if (UNEXPECTED(Z_STRVAL_P(callable)[0] == '\\')) {
+ /* Skip leading \ */
+ ZSTR_ALLOCA_ALLOC(lmname, Z_STRLEN_P(callable) - 1, use_heap);
+ zend_str_tolower_copy(ZSTR_VAL(lmname), Z_STRVAL_P(callable) + 1, Z_STRLEN_P(callable) - 1);
+ func = zend_fetch_function(lmname);
+ ZSTR_ALLOCA_FREE(lmname, use_heap);
} else {
- if (lmname == Z_STR_P(callable)) {
- ZSTR_ALLOCA_INIT(lmname, Z_STRVAL_P(callable), Z_STRLEN_P(callable), use_heap);
- } else {
- zend_string_forget_hash_val(lmname);
- }
- zend_str_tolower(ZSTR_VAL(lmname), ZSTR_LEN(lmname));
- if ((fcc->function_handler = zend_hash_find_ptr(EG(function_table), lmname)) != NULL) {
+ lmname = Z_STR_P(callable);
+ func = zend_fetch_function(lmname);
+ if (!func) {
+ ZSTR_ALLOCA_ALLOC(lmname, Z_STRLEN_P(callable), use_heap);
+ zend_str_tolower_copy(ZSTR_VAL(lmname), Z_STRVAL_P(callable), Z_STRLEN_P(callable));
+ func = zend_fetch_function(lmname);
ZSTR_ALLOCA_FREE(lmname, use_heap);
- fcc->initialized = 1;
- return 1;
}
}
- if (lmname != Z_STR_P(callable)) {
- ZSTR_ALLOCA_FREE(lmname, use_heap);
+ if (EXPECTED(func != NULL)) {
+ fcc->function_handler = func;
+ return 1;
}
}
@@ -3034,7 +3032,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
mlen = Z_STRLEN_P(callable) - clen - 2;
if (colon == Z_STRVAL_P(callable)) {
- if (error) zend_spprintf(error, 0, "invalid function name");
+ if (error) *error = estrdup("invalid function name");
return 0;
}
@@ -3048,10 +3046,10 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
cname = zend_string_init(Z_STRVAL_P(callable), clen, 0);
if (!zend_is_callable_check_class(cname, scope, fcc, &strict_class, error)) {
- zend_string_release(cname);
+ zend_string_release_ex(cname, 0);
return 0;
}
- zend_string_release(cname);
+ zend_string_release_ex(cname, 0);
ftable = &fcc->calling_scope->function_table;
if (ce_org && !instanceof_function(ce_org, fcc->calling_scope)) {
@@ -3081,19 +3079,23 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca
if (fcc->function_handler) {
retval = 1;
}
- } else if ((fcc->function_handler = zend_hash_find_ptr(ftable, lmname)) != NULL) {
+ } else if ((zv = zend_hash_find(ftable, lmname)) != NULL) {
+ fcc->function_handler = Z_PTR_P(zv);
retval = 1;
if ((fcc->function_handler->op_array.fn_flags & ZEND_ACC_CHANGED) &&
!strict_class) {
scope = zend_get_executed_scope();
if (scope &&
instanceof_function(fcc->function_handler->common.scope, scope)) {
- zend_function *priv_fbc;
- if ((priv_fbc = zend_hash_find_ptr(&scope->function_table, lmname)) != NULL
- && priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
- && priv_fbc->common.scope == scope) {
- fcc->function_handler = priv_fbc;
+ zv = zend_hash_find(&scope->function_table, lmname);
+ if (zv != NULL) {
+ zend_function *priv_fbc = Z_PTR_P(zv);
+
+ if (priv_fbc->common.fn_flags & ZEND_ACC_PRIVATE
+ && priv_fbc->common.scope == scope) {
+ fcc->function_handler = priv_fbc;
+ }
}
}
}
@@ -3131,9 +3133,9 @@ get_function_via_handler:
(!fcc->function_handler->common.scope ||
!instanceof_function(ce_org, fcc->function_handler->common.scope))) {
if (fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
- if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION &&
+ if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION &&
fcc->function_handler->common.function_name) {
- zend_string_release(fcc->function_handler->common.function_name);
+ zend_string_release_ex(fcc->function_handler->common.function_name, 0);
}
zend_free_trampoline(fcc->function_handler);
}
@@ -3233,15 +3235,12 @@ get_function_via_handler:
if (error) zend_spprintf(error, 0, "function '%s' does not exist", ZSTR_VAL(mname));
}
}
- zend_string_release(lmname);
- zend_string_release(mname);
+ zend_string_release_ex(lmname, 0);
+ zend_string_release_ex(mname, 0);
if (fcc->object) {
fcc->called_scope = fcc->object->ce;
}
- if (retval) {
- fcc->initialized = 1;
- }
return retval;
}
/* }}} */
@@ -3310,7 +3309,7 @@ try_again:
callable = Z_REFVAL_P(callable);
goto try_again;
default:
- return zval_get_string(callable);
+ return zval_get_string_func(callable);
}
}
/* }}} */
@@ -3321,10 +3320,11 @@ ZEND_API zend_string *zend_get_callable_name(zval *callable) /* {{{ */
}
/* }}} */
-static zend_bool zend_is_callable_impl(zval *callable, zend_object *object, uint32_t check_flags, zend_fcall_info_cache *fcc, char **error) /* {{{ */
+static zend_always_inline zend_bool zend_is_callable_impl(zval *callable, zend_object *object, uint32_t check_flags, zend_fcall_info_cache *fcc, char **error) /* {{{ */
{
zend_bool ret;
zend_fcall_info_cache fcc_local;
+ int strict_class = 0;
if (fcc == NULL) {
fcc = &fcc_local;
@@ -3333,7 +3333,6 @@ static zend_bool zend_is_callable_impl(zval *callable, zend_object *object, uint
*error = NULL;
}
- fcc->initialized = 0;
fcc->calling_scope = NULL;
fcc->called_scope = NULL;
fcc->function_handler = NULL;
@@ -3352,15 +3351,16 @@ again:
return 1;
}
- ret = zend_is_callable_check_func(check_flags, callable, fcc, 0, error);
+check_func:
+ ret = zend_is_callable_check_func(check_flags, callable, fcc, strict_class, error);
if (fcc == &fcc_local &&
fcc->function_handler &&
((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
- if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION &&
+ if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION &&
fcc->function_handler->common.function_name) {
- zend_string_release(fcc->function_handler->common.function_name);
+ zend_string_release_ex(fcc->function_handler->common.function_name, 0);
}
zend_free_trampoline(fcc->function_handler);
}
@@ -3370,7 +3370,6 @@ again:
{
zval *method = NULL;
zval *obj = NULL;
- int strict_class = 0;
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
obj = zend_hash_index_find(Z_ARRVAL_P(callable), 0);
@@ -3411,47 +3410,35 @@ again:
break;
}
- ret = zend_is_callable_check_func(check_flags, method, fcc, strict_class, error);
- if (fcc == &fcc_local &&
- fcc->function_handler &&
- ((fcc->function_handler->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) ||
- fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
- fcc->function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
- if (fcc->function_handler->type != ZEND_OVERLOADED_FUNCTION &&
- fcc->function_handler->common.function_name) {
- zend_string_release(fcc->function_handler->common.function_name);
- }
- zend_free_trampoline(fcc->function_handler);
- }
- return ret;
+ callable = method;
+ goto check_func;
} while (0);
if (zend_hash_num_elements(Z_ARRVAL_P(callable)) == 2) {
if (!obj || (!Z_ISREF_P(obj)?
(Z_TYPE_P(obj) != IS_STRING && Z_TYPE_P(obj) != IS_OBJECT) :
(Z_TYPE_P(Z_REFVAL_P(obj)) != IS_STRING && Z_TYPE_P(Z_REFVAL_P(obj)) != IS_OBJECT))) {
- if (error) zend_spprintf(error, 0, "first array member is not a valid class name or object");
+ if (error) *error = estrdup("first array member is not a valid class name or object");
} else {
- if (error) zend_spprintf(error, 0, "second array member is not a valid method");
+ if (error) *error = estrdup("second array member is not a valid method");
}
} else {
- if (error) zend_spprintf(error, 0, "array must have exactly two members");
+ if (error) *error = estrdup("array must have exactly two members");
}
}
return 0;
case IS_OBJECT:
if (Z_OBJ_HANDLER_P(callable, get_closure) && Z_OBJ_HANDLER_P(callable, get_closure)(callable, &fcc->calling_scope, &fcc->function_handler, &fcc->object) == SUCCESS) {
fcc->called_scope = fcc->calling_scope;
- fcc->initialized = 1;
return 1;
}
- if (error) zend_spprintf(error, 0, "no array or string given");
+ if (error) *error = estrdup("no array or string given");
return 0;
case IS_REFERENCE:
callable = Z_REFVAL_P(callable);
goto again;
default:
- if (error) zend_spprintf(error, 0, "no array or string given");
+ if (error) *error = estrdup("no array or string given");
return 0;
}
}
@@ -3478,7 +3465,7 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
if (zend_is_callable_ex(callable, NULL, IS_CALLABLE_STRICT, callable_name, &fcc, NULL)) {
if (Z_TYPE_P(callable) == IS_STRING && fcc.calling_scope) {
- zval_dtor(callable);
+ zval_ptr_dtor_str(callable);
array_init(callable);
add_next_index_str(callable, zend_string_copy(fcc.calling_scope->name));
add_next_index_str(callable, zend_string_copy(fcc.function_handler->common.function_name));
@@ -3488,7 +3475,7 @@ ZEND_API zend_bool zend_make_callable(zval *callable, zend_string **callable_nam
fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION_TEMPORARY ||
fcc.function_handler->type == ZEND_OVERLOADED_FUNCTION)) {
if (fcc.function_handler->type != ZEND_OVERLOADED_FUNCTION) {
- zend_string_release(fcc.function_handler->common.function_name);
+ zend_string_release_ex(fcc.function_handler->common.function_name, 0);
}
zend_free_trampoline(fcc.function_handler);
}
@@ -3573,9 +3560,7 @@ ZEND_API int zend_fcall_info_args_ex(zend_fcall_info *fci, zend_function *func,
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(args), arg) {
if (func && !Z_ISREF_P(arg) && ARG_SHOULD_BE_SENT_BY_REF(func, n)) {
ZVAL_NEW_REF(params, arg);
- if (Z_REFCOUNTED_P(arg)) {
- Z_ADDREF_P(arg);
- }
+ Z_TRY_ADDREF_P(arg);
} else {
ZVAL_COPY(params, arg);
}
@@ -3685,27 +3670,38 @@ ZEND_API const char *zend_get_module_version(const char *module_name) /* {{{ */
lname = zend_string_alloc(name_len, 0);
zend_str_tolower_copy(ZSTR_VAL(lname), module_name, name_len);
module = zend_hash_find_ptr(&module_registry, lname);
- zend_string_free(lname);
+ zend_string_efree(lname);
return module ? module->version : NULL;
}
/* }}} */
+static inline zend_string *zval_make_interned_string(zval *zv) /* {{{ */
+{
+ ZEND_ASSERT(Z_TYPE_P(zv) == IS_STRING);
+ Z_STR_P(zv) = zend_new_interned_string(Z_STR_P(zv));
+ if (ZSTR_IS_INTERNED(Z_STR_P(zv))) {
+ Z_TYPE_FLAGS_P(zv) = 0;
+ }
+ return Z_STR_P(zv);
+}
+
ZEND_API int zend_declare_property_ex(zend_class_entry *ce, zend_string *name, zval *property, int access_type, zend_string *doc_comment) /* {{{ */
{
zend_property_info *property_info, *property_info_ptr;
if (ce->type == ZEND_INTERNAL_CLASS) {
property_info = pemalloc(sizeof(zend_property_info), 1);
- if ((access_type & ZEND_ACC_STATIC) || Z_CONSTANT_P(property)) {
- ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
- }
} else {
property_info = zend_arena_alloc(&CG(arena), sizeof(zend_property_info));
- if (Z_CONSTANT_P(property)) {
+ if (Z_TYPE_P(property) == IS_CONSTANT_AST) {
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
}
}
+ if (Z_TYPE_P(property) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(property))) {
+ zval_make_interned_string(property);
+ }
+
if (!(access_type & ZEND_ACC_PPP_MASK)) {
access_type |= ZEND_ACC_PUBLIC;
}
@@ -3848,6 +3844,10 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
"A class constant must not be called 'class'; it is reserved for class name fetching");
}
+ if (Z_TYPE_P(value) == IS_STRING && !ZSTR_IS_INTERNED(Z_STR_P(value))) {
+ zval_make_interned_string(value);
+ }
+
if (ce->type == ZEND_INTERNAL_CLASS) {
c = pemalloc(sizeof(zend_class_constant), 1);
} else {
@@ -3857,7 +3857,7 @@ ZEND_API int zend_declare_class_constant_ex(zend_class_entry *ce, zend_string *n
Z_ACCESS_FLAGS(c->value) = access_type;
c->doc_comment = doc_comment;
c->ce = ce;
- if (Z_CONSTANT_P(value)) {
+ if (Z_TYPE_P(value) == IS_CONSTANT_AST) {
ce->ce_flags &= ~ZEND_ACC_CONSTANTS_UPDATED;
}
@@ -3874,9 +3874,12 @@ ZEND_API int zend_declare_class_constant(zend_class_entry *ce, const char *name,
{
int ret;
- zend_string *key = zend_string_init(name, name_length, ce->type & ZEND_INTERNAL_CLASS);
+ zend_string *key;
+
if (ce->type == ZEND_INTERNAL_CLASS) {
- key = zend_new_interned_string(key);
+ 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);
zend_string_release(key);
@@ -4053,42 +4056,37 @@ ZEND_API void zend_update_property_stringl(zend_class_entry *scope, zval *object
}
/* }}} */
-ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value) /* {{{ */
+ZEND_API int zend_update_static_property_ex(zend_class_entry *scope, zend_string *name, zval *value) /* {{{ */
{
zval *property;
zend_class_entry *old_scope = EG(fake_scope);
- zend_string *key = zend_string_init(name, name_length, 0);
EG(fake_scope) = scope;
- property = zend_std_get_static_property(scope, key, 0);
+ property = zend_std_get_static_property(scope, name, 0);
EG(fake_scope) = old_scope;
- zend_string_free(key);
+
if (!property) {
return FAILURE;
- } else {
- if (property != value) {
- if (Z_ISREF_P(property)) {
- zval_dtor(property);
- ZVAL_COPY_VALUE(property, value);
- if (Z_REFCOUNTED_P(value) && Z_REFCOUNT_P(value) > 0) {
- zval_opt_copy_ctor(property);
- }
- } else {
- zval garbage;
+ }
- ZVAL_COPY_VALUE(&garbage, property);
- if (Z_REFCOUNTED_P(value)) {
- Z_ADDREF_P(value);
- if (Z_ISREF_P(value)) {
- SEPARATE_ZVAL(value);
- }
- }
- ZVAL_COPY_VALUE(property, value);
- zval_ptr_dtor(&garbage);
- }
- }
- return SUCCESS;
+ if (property != value) {
+ zval garbage;
+ ZVAL_DEREF(property);
+ ZVAL_DEREF(value);
+ ZVAL_COPY_VALUE(&garbage, property);
+ ZVAL_COPY(property, value);
+ zval_ptr_dtor(&garbage);
}
+ return SUCCESS;
+}
+/* }}} */
+
+ZEND_API int zend_update_static_property(zend_class_entry *scope, const char *name, size_t name_length, zval *value) /* {{{ */
+{
+ zend_string *key = zend_string_init(name, name_length, 0);
+ int retval = zend_update_static_property_ex(scope, key, value);
+ zend_string_efree(key);
+ return retval;
}
/* }}} */
@@ -4174,26 +4172,33 @@ ZEND_API zval *zend_read_property(zend_class_entry *scope, zval *object, const c
str = zend_string_init(name, name_length, 0);
value = zend_read_property_ex(scope, object, str, silent, rv);
- zend_string_release(str);
+ zend_string_release_ex(str, 0);
return value;
}
/* }}} */
-ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent) /* {{{ */
+ZEND_API zval *zend_read_static_property_ex(zend_class_entry *scope, zend_string *name, zend_bool silent) /* {{{ */
{
zval *property;
zend_class_entry *old_scope = EG(fake_scope);
- zend_string *key = zend_string_init(name, name_length, 0);
EG(fake_scope) = scope;
- property = zend_std_get_static_property(scope, key, silent);
+ property = zend_std_get_static_property(scope, name, silent);
EG(fake_scope) = old_scope;
- zend_string_free(key);
return property;
}
/* }}} */
+ZEND_API zval *zend_read_static_property(zend_class_entry *scope, const char *name, size_t name_length, zend_bool silent) /* {{{ */
+{
+ zend_string *key = zend_string_init(name, name_length, 0);
+ zval *property = zend_read_static_property_ex(scope, key, silent);
+ zend_string_efree(key);
+ return property;
+}
+/* }}} */
+
ZEND_API void zend_save_error_handling(zend_error_handling *current) /* {{{ */
{
current->handling = EG(error_handling);
@@ -4331,6 +4336,23 @@ ZEND_API zend_bool zend_is_iterable(zval *iterable) /* {{{ */
}
/* }}} */
+ZEND_API zend_bool zend_is_countable(zval *countable) /* {{{ */
+{
+ switch (Z_TYPE_P(countable)) {
+ case IS_ARRAY:
+ return 1;
+ case IS_OBJECT:
+ if (Z_OBJ_HT_P(countable)->count_elements) {
+ return 1;
+ }
+
+ return instanceof_function(Z_OBJCE_P(countable), zend_ce_countable);
+ default:
+ return 0;
+ }
+}
+/* }}} */
+
/*
* Local variables:
* tab-width: 4