Skip to content

Commit 49c8d34

Browse files
committed
Address review feedback: embed zend_err_buf struct directly in EG.
- Change EG(errors) from pointer to embedded struct (arnaud-lb) - Replace flexible array member with plain pointer (arnaud-lb) - Use EG(errors).field syntax instead of EG(errors->field) (ndossche) - Remove persistent allocation, use erealloc for the inner array - Remove zend_init_errors_buf/ZEND_ERR_BUF_SIZE, zeroing suffices - Free EG(errors).errors buffer in zend_free_recorded_errors - Save/restore full EG(errors) state in error handler paths - Revert unrelated int->uint32_t change (arnaud-lb)
1 parent 155e86f commit 49c8d34

File tree

4 files changed

+46
-56
lines changed

4 files changed

+46
-56
lines changed

Zend/zend.c

Lines changed: 33 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,6 @@ static char *zend_version_info;
8080
static uint32_t zend_version_info_length;
8181
#define ZEND_CORE_VERSION_INFO "Zend Engine v" ZEND_VERSION ", Copyright (c) Zend Technologies\n"
8282
#define PRINT_ZVAL_INDENT 4
83-
#define ZEND_ERR_BUF_SIZE(capacity) \
84-
(XtOffsetOf(struct zend_err_buf, buf) + sizeof(zend_error_info *) * (capacity))
8583

8684
/* true multithread-shared globals */
8785
ZEND_API zend_class_entry *zend_standard_class_def = NULL;
@@ -645,12 +643,6 @@ static FILE *zend_fopen_wrapper(zend_string *filename, zend_string **opened_path
645643
}
646644
/* }}} */
647645

648-
static void zend_init_errors_buf(zend_executor_globals *eg)
649-
{
650-
eg->errors = pemalloc(ZEND_ERR_BUF_SIZE(2), true);
651-
eg->errors->capacity = 2;
652-
eg->errors->size = 0;
653-
}
654646

655647
#ifdef ZTS
656648
static bool short_tags_default = true;
@@ -842,7 +834,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
842834
#endif
843835
executor_globals->flags = EG_FLAGS_INITIAL;
844836
executor_globals->record_errors = false;
845-
zend_init_errors_buf(executor_globals);
837+
memset(&executor_globals->errors, 0, sizeof(executor_globals->errors));
846838
executor_globals->filename_override = NULL;
847839
executor_globals->lineno_override = -1;
848840
#ifdef ZEND_CHECK_STACK_LIMIT
@@ -877,8 +869,6 @@ static void executor_globals_dtor(zend_executor_globals *executor_globals) /* {{
877869
zend_hash_destroy(executor_globals->zend_constants);
878870
free(executor_globals->zend_constants);
879871
}
880-
881-
pefree(executor_globals->errors, true);
882872
}
883873
/* }}} */
884874

@@ -1075,7 +1065,6 @@ void zend_startup(zend_utility_functions *utility_functions) /* {{{ */
10751065
zend_init_rsrc_plist();
10761066
zend_init_exception_op();
10771067
zend_init_call_trampoline_op();
1078-
zend_init_errors_buf(&executor_globals);
10791068
#endif
10801069

10811070
zend_ini_startup();
@@ -1158,7 +1147,6 @@ zend_result zend_post_startup(void) /* {{{ */
11581147
free(EG(zend_constants));
11591148
EG(zend_constants) = NULL;
11601149

1161-
pefree(executor_globals->errors, true);
11621150
executor_globals_ctor(executor_globals);
11631151
global_persistent_list = &EG(persistent_list);
11641152
zend_copy_ini_directives();
@@ -1236,7 +1224,6 @@ void zend_shutdown(void) /* {{{ */
12361224
pefree(CG(internal_run_time_cache), 1);
12371225
CG(internal_run_time_cache) = NULL;
12381226
}
1239-
pefree(EG(errors), true);
12401227
#endif
12411228
zend_map_ptr_static_last = 0;
12421229
zend_map_ptr_static_size = 0;
@@ -1461,6 +1448,7 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14611448
bool orig_record_errors;
14621449
uint32_t orig_num_errors = 0;
14631450
uint32_t orig_cap_errors = 0;
1451+
zend_error_info **orig_errors = NULL;
14641452
zend_result res;
14651453

14661454
/* If we're executing a function during SCCP, count any warnings that may be emitted,
@@ -1472,11 +1460,11 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14721460
}
14731461

14741462
/* Emit any delayed error before handling fatal error */
1475-
if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(errors->size)) {
1476-
uint32_t num_errors = EG(errors->size);
1477-
uint32_t cap_errors = EG(errors->capacity);
1478-
zend_error_info **errors = EG(errors->buf);
1479-
EG(errors->size) = 0;
1463+
if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(errors).size) {
1464+
uint32_t num_errors = EG(errors).size;
1465+
uint32_t cap_errors = EG(errors).capacity;
1466+
zend_error_info **errors = EG(errors).errors;
1467+
EG(errors).size = 0;
14801468

14811469
bool orig_record_errors = EG(record_errors);
14821470
EG(record_errors) = false;
@@ -1490,8 +1478,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14901478

14911479
EG(user_error_handler_error_reporting) = orig_user_error_handler_error_reporting;
14921480
EG(record_errors) = orig_record_errors;
1493-
EG(errors->size) = num_errors;
1494-
EG(errors->capacity) = cap_errors;
1481+
EG(errors).size = num_errors;
1482+
EG(errors).capacity = cap_errors;
1483+
EG(errors).errors = errors;
14951484
}
14961485

14971486
if (EG(record_errors)) {
@@ -1500,13 +1489,13 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
15001489
info->lineno = error_lineno;
15011490
info->filename = zend_string_copy(error_filename);
15021491
info->message = zend_string_copy(message);
1503-
EG(errors->size)++;
1504-
if (EG(errors->size) >= EG(errors->capacity)) {
1505-
uint32_t capacity = EG(errors->capacity) + (EG(errors->capacity) >> 1);
1506-
EG(errors) = safe_perealloc(EG(errors), sizeof(zend_error_info *), capacity, XtOffsetOf(struct zend_err_buf, buf), true);
1507-
EG(errors->capacity) = capacity;
1492+
EG(errors).size++;
1493+
if (EG(errors).size > EG(errors).capacity) {
1494+
uint32_t capacity = EG(errors).capacity ? EG(errors).capacity + (EG(errors).capacity >> 1) : 2;
1495+
EG(errors).errors = erealloc(EG(errors).errors, sizeof(zend_error_info *) * capacity);
1496+
EG(errors).capacity = capacity;
15081497
}
1509-
EG(errors->buf)[EG(errors->size)-1] = info;
1498+
EG(errors).errors[EG(errors).size - 1] = info;
15101499

15111500
/* Do not process non-fatal recorded error */
15121501
if (!(type & E_FATAL_ERRORS) || (type & E_DONT_BAIL)) {
@@ -1591,16 +1580,18 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
15911580
orig_record_errors = EG(record_errors);
15921581
EG(record_errors) = false;
15931582

1594-
orig_num_errors = EG(errors->size);
1595-
orig_cap_errors = EG(errors->capacity);
1596-
EG(errors->size) = 0;
1583+
orig_num_errors = EG(errors).size;
1584+
orig_cap_errors = EG(errors).capacity;
1585+
orig_errors = EG(errors).errors;
1586+
memset(&EG(errors), 0, sizeof(EG(errors)));
15971587

15981588
res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params);
15991589

16001590
EG(record_errors) = orig_record_errors;
16011591

1602-
EG(errors->capacity) = orig_cap_errors;
1603-
EG(errors->size) = orig_num_errors;
1592+
EG(errors).capacity = orig_cap_errors;
1593+
EG(errors).size = orig_num_errors;
1594+
EG(errors).errors = orig_errors;
16041595

16051596
if (res == SUCCESS) {
16061597
if (Z_TYPE(retval) != IS_UNDEF) {
@@ -1795,7 +1786,7 @@ ZEND_API void zend_begin_record_errors(void)
17951786
{
17961787
ZEND_ASSERT(!EG(record_errors) && "Error recording already enabled");
17971788
EG(record_errors) = true;
1798-
EG(errors->size) = 0;
1789+
EG(errors).size = 0;
17991790
}
18001791

18011792
ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors)
@@ -1809,22 +1800,21 @@ ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info
18091800
ZEND_API void zend_emit_recorded_errors(void)
18101801
{
18111802
EG(record_errors) = false;
1812-
zend_emit_recorded_errors_ex(EG(errors->size), EG(errors->buf));
1803+
zend_emit_recorded_errors_ex(EG(errors).size, EG(errors).errors);
18131804
}
18141805

18151806
ZEND_API void zend_free_recorded_errors(void)
18161807
{
1817-
if (!EG(errors->size)) {
1818-
return;
1819-
}
1820-
1821-
for (uint32_t i = 0; i < EG(errors->size); i++) {
1822-
zend_error_info *info = EG(errors->buf)[i];
1808+
for (uint32_t i = 0; i < EG(errors).size; i++) {
1809+
zend_error_info *info = EG(errors).errors[i];
18231810
zend_string_release(info->filename);
18241811
zend_string_release(info->message);
18251812
efree_size(info, sizeof(zend_error_info));
18261813
}
1827-
EG(errors->size) = 0;
1814+
if (EG(errors).errors) {
1815+
efree(EG(errors).errors);
1816+
}
1817+
memset(&EG(errors), 0, sizeof(EG(errors)));
18281818
}
18291819

18301820
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */
@@ -2032,12 +2022,12 @@ ZEND_API zend_result zend_execute_scripts(int type, zval *retval, int file_count
20322022
}
20332023
/* }}} */
20342024

2035-
#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%u) : %s"
2025+
#define COMPILED_STRING_DESCRIPTION_FORMAT "%s(%d) : %s"
20362026

20372027
ZEND_API char *zend_make_compiled_string_description(const char *name) /* {{{ */
20382028
{
20392029
const char *cur_filename;
2040-
uint32_t cur_lineno;
2030+
int cur_lineno;
20412031
char *compiled_string_description;
20422032

20432033
if (zend_is_compiling()) {

Zend/zend_execute_API.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ void init_executor(void) /* {{{ */
192192
EG(get_gc_buffer).start = EG(get_gc_buffer).end = EG(get_gc_buffer).cur = NULL;
193193

194194
EG(record_errors) = false;
195-
EG(errors->size) = 0;
195+
memset(&EG(errors), 0, sizeof(EG(errors)));
196196

197197
EG(filename_override) = NULL;
198198
EG(lineno_override) = -1;

Zend/zend_globals.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ typedef enum {
8585
struct zend_err_buf {
8686
uint32_t size;
8787
uint32_t capacity;
88-
zend_error_info *buf[1];
88+
zend_error_info **errors;
8989
};
9090

9191
struct _zend_compiler_globals {
@@ -305,7 +305,7 @@ struct _zend_executor_globals {
305305
* and their processing is delayed until zend_emit_recorded_errors()
306306
* is called or a fatal diagnostic is emitted. */
307307
bool record_errors;
308-
struct zend_err_buf *errors;
308+
struct zend_err_buf errors;
309309

310310
/* Override filename or line number of thrown errors and exceptions */
311311
zend_string *filename_override;

ext/opcache/ZendAccelerator.c

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1968,8 +1968,8 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int
19681968

19691969
if (persistent_script) {
19701970
if (ZCG(accel_directives).record_warnings) {
1971-
persistent_script->num_warnings = EG(errors->size);
1972-
persistent_script->warnings = EG(errors->buf);
1971+
persistent_script->num_warnings = EG(errors).size;
1972+
persistent_script->warnings = EG(errors).errors;
19731973
}
19741974

19751975
from_memory = false;
@@ -2193,8 +2193,8 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
21932193
from_shared_memory = false;
21942194
if (persistent_script) {
21952195
if (ZCG(accel_directives).record_warnings) {
2196-
persistent_script->num_warnings = EG(errors->size);
2197-
persistent_script->warnings = EG(errors->buf);
2196+
persistent_script->num_warnings = EG(errors).size;
2197+
persistent_script->warnings = EG(errors).errors;
21982198
}
21992199

22002200
/* See GH-17246: we disable GC so that user code cannot be executed during the optimizer run. */
@@ -2421,7 +2421,7 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24212421
}
24222422
ZCG(current_persistent_script) = &dummy;
24232423
zend_persist_class_entry_calc(ce);
2424-
zend_persist_warnings_calc(EG(errors->size), EG(errors->buf));
2424+
zend_persist_warnings_calc(EG(errors).size, EG(errors).errors);
24252425
size = dummy.size;
24262426

24272427
zend_shared_alloc_clear_xlat_table();
@@ -2491,8 +2491,8 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24912491
JIT_G(on) = jit_on_old;
24922492
#endif
24932493

2494-
entry->num_warnings = EG(errors->size);
2495-
entry->warnings = zend_persist_warnings(EG(errors->size), EG(errors->buf));
2494+
entry->num_warnings = EG(errors).size;
2495+
entry->warnings = zend_persist_warnings(EG(errors).size, EG(errors).errors);
24962496
entry->next = proto->inheritance_cache;
24972497
proto->inheritance_cache = entry;
24982498

@@ -4123,9 +4123,9 @@ static void preload_link(void)
41234123
/* Remember the last error. */
41244124
zend_error_cb = orig_error_cb;
41254125
EG(record_errors) = false;
4126-
ZEND_ASSERT(EG(errors->size) > 0);
4127-
zend_hash_update_ptr(&errors, key, EG(errors->buf)[EG(errors->size)-1]);
4128-
EG(errors->size)--;
4126+
ZEND_ASSERT(EG(errors).size > 0);
4127+
zend_hash_update_ptr(&errors, key, EG(errors).errors[EG(errors).size-1]);
4128+
EG(errors).size--;
41294129
} zend_end_try();
41304130
CG(in_compilation) = false;
41314131
CG(compiled_filename) = NULL;

0 commit comments

Comments
 (0)