summaryrefslogtreecommitdiff
path: root/Zend/zend.c
diff options
context:
space:
mode:
Diffstat (limited to 'Zend/zend.c')
-rw-r--r--Zend/zend.c128
1 files changed, 82 insertions, 46 deletions
diff --git a/Zend/zend.c b/Zend/zend.c
index 72a7b4d588..aae1d13b11 100644
--- a/Zend/zend.c
+++ b/Zend/zend.c
@@ -33,6 +33,7 @@
#include "zend_virtual_cwd.h"
#include "zend_smart_str.h"
#include "zend_smart_string.h"
+#include "zend_cpuinfo.h"
#ifdef ZTS
ZEND_API int compiler_globals_id;
@@ -75,13 +76,18 @@ ZEND_API void (*zend_error_cb)(int type, const char *error_filename, const uint3
void (*zend_printf_to_smart_string)(smart_string *buf, const char *format, va_list ap);
void (*zend_printf_to_smart_str)(smart_str *buf, const char *format, va_list ap);
ZEND_API char *(*zend_getenv)(char *name, size_t name_len);
-ZEND_API zend_string *(*zend_resolve_path)(const char *filename, int filename_len);
+ZEND_API zend_string *(*zend_resolve_path)(const char *filename, size_t filename_len);
+ZEND_API int (*zend_post_startup_cb)(void) = NULL;
void (*zend_on_timeout)(int seconds);
static void (*zend_message_dispatcher_p)(zend_long message, const void *data);
static zval *(*zend_get_configuration_directive_p)(zend_string *name);
+#if ZEND_RC_DEBUG
+ZEND_API zend_bool zend_rc_debug = 0;
+#endif
+
static ZEND_INI_MH(OnUpdateErrorReporting) /* {{{ */
{
if (!new_value) {
@@ -130,7 +136,7 @@ static ZEND_INI_MH(OnUpdateAssertions) /* {{{ */
p = (zend_long *) (base+(size_t) mh_arg1);
- val = zend_atol(ZSTR_VAL(new_value), (int)ZSTR_LEN(new_value));
+ val = zend_atol(ZSTR_VAL(new_value), ZSTR_LEN(new_value));
if (stage != ZEND_INI_STAGE_STARTUP &&
stage != ZEND_INI_STAGE_SHUTDOWN &&
@@ -197,6 +203,18 @@ ZEND_API size_t zend_spprintf(char **message, size_t max_len, const char *format
}
/* }}} */
+ZEND_API size_t zend_spprintf_unchecked(char **message, size_t max_len, const char *format, ...) /* {{{ */
+{
+ va_list arg;
+ size_t len;
+
+ va_start(arg, format);
+ len = zend_vspprintf(message, max_len, format, arg);
+ va_end(arg);
+ return len;
+}
+/* }}} */
+
ZEND_API zend_string *zend_vstrpprintf(size_t max_len, const char *format, va_list ap) /* {{{ */
{
smart_str buf = {0};
@@ -228,6 +246,18 @@ ZEND_API zend_string *zend_strpprintf(size_t max_len, const char *format, ...) /
}
/* }}} */
+ZEND_API zend_string *zend_strpprintf_unchecked(size_t max_len, const char *format, ...) /* {{{ */
+{
+ va_list arg;
+ zend_string *str;
+
+ va_start(arg, format);
+ str = zend_vstrpprintf(max_len, format, arg);
+ va_end(arg);
+ return str;
+}
+/* }}} */
+
static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent);
static void print_hash(smart_str *buf, HashTable *ht, int indent, zend_bool is_object) /* {{{ */
@@ -309,7 +339,7 @@ ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
if (Z_TYPE_P(expr) == IS_STRING) {
return 0;
} else {
- ZVAL_STR(expr_copy, _zval_get_string_func(expr));
+ ZVAL_STR(expr_copy, zval_get_string_func(expr));
return 1;
}
}
@@ -317,14 +347,15 @@ ZEND_API int zend_make_printable_zval(zval *expr, zval *expr_copy) /* {{{ */
ZEND_API size_t zend_print_zval(zval *expr, int indent) /* {{{ */
{
- zend_string *str = zval_get_string(expr);
+ zend_string *tmp_str;
+ zend_string *str = zval_get_tmp_string(expr, &tmp_str);
size_t len = ZSTR_LEN(str);
if (len != 0) {
zend_write(ZSTR_VAL(str), len);
}
- zend_string_release(str);
+ zend_tmp_string_release(tmp_str);
return len;
}
/* }}} */
@@ -334,16 +365,17 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
switch (Z_TYPE_P(expr)) {
case IS_ARRAY:
ZEND_PUTS("Array (");
- if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
- ++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
- ZEND_PUTS(" *RECURSION*");
- Z_ARRVAL_P(expr)->u.v.nApplyCount--;
- return;
+ if (Z_REFCOUNTED_P(expr)) {
+ if (Z_IS_RECURSIVE_P(expr)) {
+ ZEND_PUTS(" *RECURSION*");
+ return;
+ }
+ Z_PROTECT_RECURSION_P(expr);
}
print_flat_hash(Z_ARRVAL_P(expr));
ZEND_PUTS(")");
- if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
- Z_ARRVAL_P(expr)->u.v.nApplyCount--;
+ if (Z_REFCOUNTED_P(expr)) {
+ Z_UNPROTECT_RECURSION_P(expr);
}
break;
case IS_OBJECT:
@@ -353,7 +385,7 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
zend_printf("%s Object (", ZSTR_VAL(class_name));
zend_string_release(class_name);
- if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
+ if (Z_IS_RECURSIVE_P(expr)) {
ZEND_PUTS(" *RECURSION*");
return;
}
@@ -362,9 +394,9 @@ ZEND_API void zend_print_flat_zval_r(zval *expr) /* {{{ */
properties = Z_OBJPROP_P(expr);
}
if (properties) {
- Z_OBJ_INC_APPLY_COUNT_P(expr);
+ Z_PROTECT_RECURSION_P(expr);
print_flat_hash(properties);
- Z_OBJ_DEC_APPLY_COUNT_P(expr);
+ Z_UNPROTECT_RECURSION_P(expr);
}
ZEND_PUTS(")");
break;
@@ -384,15 +416,16 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
switch (Z_TYPE_P(expr)) {
case IS_ARRAY:
smart_str_appends(buf, "Array\n");
- if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr)) &&
- ++Z_ARRVAL_P(expr)->u.v.nApplyCount>1) {
- smart_str_appends(buf, " *RECURSION*");
- Z_ARRVAL_P(expr)->u.v.nApplyCount--;
- return;
+ if (Z_REFCOUNTED_P(expr)) {
+ if (Z_IS_RECURSIVE_P(expr)) {
+ smart_str_appends(buf, " *RECURSION*");
+ return;
+ }
+ Z_PROTECT_RECURSION_P(expr);
}
print_hash(buf, Z_ARRVAL_P(expr), indent, 0);
- if (ZEND_HASH_APPLY_PROTECTION(Z_ARRVAL_P(expr))) {
- Z_ARRVAL_P(expr)->u.v.nApplyCount--;
+ if (Z_REFCOUNTED_P(expr)) {
+ Z_UNPROTECT_RECURSION_P(expr);
}
break;
case IS_OBJECT:
@@ -405,7 +438,7 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
zend_string_release(class_name);
smart_str_appends(buf, " Object\n");
- if (Z_OBJ_APPLY_COUNT_P(expr) > 0) {
+ if (Z_IS_RECURSIVE_P(expr)) {
smart_str_appends(buf, " *RECURSION*");
return;
}
@@ -413,9 +446,9 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
break;
}
- Z_OBJ_INC_APPLY_COUNT_P(expr);
+ Z_PROTECT_RECURSION_P(expr);
print_hash(buf, properties, indent, 1);
- Z_OBJ_DEC_APPLY_COUNT_P(expr);
+ Z_UNPROTECT_RECURSION_P(expr);
if (is_temp) {
zend_hash_destroy(properties);
@@ -429,9 +462,12 @@ static void zend_print_zval_r_to_buf(smart_str *buf, zval *expr, int indent) /*
case IS_REFERENCE:
zend_print_zval_r_to_buf(buf, Z_REFVAL_P(expr), indent);
break;
+ case IS_STRING:
+ smart_str_append(buf, Z_STR_P(expr));
+ break;
default:
{
- zend_string *str = zval_get_string(expr);
+ zend_string *str = zval_get_string_func(expr);
smart_str_append(buf, str);
zend_string_release(str);
}
@@ -498,19 +534,10 @@ static void zend_init_exception_op(void) /* {{{ */
{
memset(EG(exception_op), 0, sizeof(EG(exception_op)));
EG(exception_op)[0].opcode = ZEND_HANDLE_EXCEPTION;
- EG(exception_op)[0].op1_type = IS_UNUSED;
- EG(exception_op)[0].op2_type = IS_UNUSED;
- EG(exception_op)[0].result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op));
EG(exception_op)[1].opcode = ZEND_HANDLE_EXCEPTION;
- EG(exception_op)[1].op1_type = IS_UNUSED;
- EG(exception_op)[1].op2_type = IS_UNUSED;
- EG(exception_op)[1].result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+1);
EG(exception_op)[2].opcode = ZEND_HANDLE_EXCEPTION;
- EG(exception_op)[2].op1_type = IS_UNUSED;
- EG(exception_op)[2].op2_type = IS_UNUSED;
- EG(exception_op)[2].result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(EG(exception_op)+2);
}
/* }}} */
@@ -519,9 +546,6 @@ static void zend_init_call_trampoline_op(void) /* {{{ */
{
memset(&EG(call_trampoline_op), 0, sizeof(EG(call_trampoline_op)));
EG(call_trampoline_op).opcode = ZEND_CALL_TRAMPOLINE;
- EG(call_trampoline_op).op1_type = IS_UNUSED;
- EG(call_trampoline_op).op2_type = IS_UNUSED;
- EG(call_trampoline_op).result_type = IS_UNUSED;
ZEND_VM_SET_OPCODE_HANDLER(&EG(call_trampoline_op));
}
/* }}} */
@@ -696,8 +720,9 @@ static zend_bool php_auto_globals_create_globals(zend_string *name) /* {{{ */
{
zval globals;
+ /* IS_ARRAY, but with ref-counter 1 and not IS_TYPE_REFCOUNTED */
ZVAL_ARR(&globals, &EG(symbol_table));
- Z_TYPE_INFO_P(&globals) = IS_ARRAY;
+ Z_TYPE_FLAGS_P(&globals) = 0;
ZVAL_NEW_REF(&globals, &globals);
zend_hash_update(&EG(symbol_table), name, &globals);
return 0;
@@ -717,6 +742,10 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
extern zend_php_scanner_globals language_scanner_globals;
#endif
+#ifndef HAVE_FUNC_ATTRIBUTE_IFUNC
+ zend_cpu_startup();
+#endif
+
#ifdef ZEND_WIN32
php_win32_cp_set_by_id(65001);
#endif
@@ -831,7 +860,7 @@ int zend_startup(zend_utility_functions *utility_functions, char **extensions) /
zend_interned_strings_init();
zend_startup_builtin_functions();
zend_register_standard_constants();
- zend_register_auto_global(zend_string_init("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
+ zend_register_auto_global(zend_string_init_interned("GLOBALS", sizeof("GLOBALS") - 1, 1), 1, php_auto_globals_create_globals);
#ifndef ZTS
zend_init_rsrc_plist();
@@ -866,7 +895,7 @@ void zend_register_standard_ini_entries(void) /* {{{ */
/* Unlink the global (r/o) copies of the class, function and constant tables,
* and use a fresh r/w copy for the startup thread
*/
-void zend_post_startup(void) /* {{{ */
+int zend_post_startup(void) /* {{{ */
{
#ifdef ZTS
zend_encoding **script_encoding_list;
@@ -896,6 +925,17 @@ void zend_post_startup(void) /* {{{ */
global_persistent_list = &EG(persistent_list);
zend_copy_ini_directives();
#endif
+
+ if (zend_post_startup_cb) {
+ int (*cb)(void) = zend_post_startup_cb;
+
+ zend_post_startup_cb = NULL;
+ if (cb() != SUCCESS) {
+ return FAILURE;
+ }
+ }
+
+ return SUCCESS;
}
/* }}} */
@@ -930,10 +970,6 @@ void zend_shutdown(void) /* {{{ */
GLOBAL_CONSTANTS_TABLE = NULL;
#endif
zend_destroy_rsrc_list_dtors();
-
-#ifndef ZTS
- zend_interned_strings_dtor();
-#endif
}
/* }}} */
@@ -1350,7 +1386,7 @@ ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const c
{
va_list va;
char *message = NULL;
-
+
if (exception_ce) {
if (!instanceof_function(exception_ce, zend_ce_error)) {
zend_error(E_NOTICE, "Error exceptions must be derived from Error");