Skip to content

Commit f38b0e3

Browse files
committed
review
1 parent 821a02e commit f38b0e3

File tree

4 files changed

+69
-55
lines changed

4 files changed

+69
-55
lines changed

Zend/zend.c

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -833,8 +833,7 @@ static void executor_globals_ctor(zend_executor_globals *executor_globals) /* {{
833833
#endif
834834
executor_globals->flags = EG_FLAGS_INITIAL;
835835
executor_globals->record_errors = false;
836-
executor_globals->num_errors = 0;
837-
executor_globals->errors = NULL;
836+
executor_globals->errors = 0;
838837
executor_globals->filename_override = NULL;
839838
executor_globals->lineno_override = -1;
840839
#ifdef ZEND_CHECK_STACK_LIMIT
@@ -1447,8 +1446,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14471446
zend_stack delayed_oplines_stack;
14481447
int type = orig_type & E_ALL;
14491448
bool orig_record_errors;
1450-
uint32_t orig_num_errors;
1451-
zend_error_info **orig_errors;
1449+
uint32_t orig_num_errors = 0;
1450+
uint32_t orig_cap_errors = 0;
1451+
zend_error_info **orig_errors = NULL;
14521452
zend_result res;
14531453

14541454
/* If we're executing a function during SCCP, count any warnings that may be emitted,
@@ -1460,11 +1460,12 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14601460
}
14611461

14621462
/* Emit any delayed error before handling fatal error */
1463-
if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(num_errors)) {
1464-
uint32_t num_errors = EG(num_errors);
1465-
zend_error_info **errors = EG(errors);
1466-
EG(num_errors) = 0;
1467-
EG(errors) = NULL;
1463+
if ((type & E_FATAL_ERRORS) && !(type & E_DONT_BAIL) && EG(errors)) {
1464+
uint32_t num_errors = EG(errors->size);
1465+
uint32_t cap_errors = EG(errors->capacity);
1466+
zend_error_info **errors = EG(errors->buf);
1467+
EG(errors->size) = 0;
1468+
EG(errors->capacity) = 0;
14681469

14691470
bool orig_record_errors = EG(record_errors);
14701471
EG(record_errors) = false;
@@ -1478,8 +1479,9 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14781479

14791480
EG(user_error_handler_error_reporting) = orig_user_error_handler_error_reporting;
14801481
EG(record_errors) = orig_record_errors;
1481-
EG(num_errors) = num_errors;
1482-
EG(errors) = errors;
1482+
EG(errors->size) = num_errors;
1483+
EG(errors->capacity) = cap_errors;
1484+
memcpy(EG(errors->buf), errors, EG(errors->capacity) * sizeof(zend_error_info *));
14831485
}
14841486

14851487
if (EG(record_errors)) {
@@ -1489,25 +1491,20 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
14891491
info->filename = zend_string_copy(error_filename);
14901492
info->message = zend_string_copy(message);
14911493

1492-
EG(num_errors)++;
1493-
// pondering if uint32_t is more appropriate but would need to align the allocation size then
1494-
size_t *errors_size;
1495-
1496-
if (EG(num_errors) == 1) {
1497-
errors_size = emalloc(sizeof(size_t) + (2 * sizeof(zend_error_info *)));
1498-
// can be seen as "waste" but to have a round even number from start
1499-
*errors_size = 2;
1494+
if (!EG(errors) ) {
1495+
EG(errors) = emalloc(sizeof(*EG(errors)) + 2 * sizeof(zend_error_info *));
1496+
EG(errors->capacity) = 2;
1497+
EG(errors->size) = 1;
15001498
} else {
1501-
errors_size = (size_t *)(EG(errors) - 1);
1502-
if (EG(num_errors) == *errors_size) {
1503-
size_t tmp = *errors_size + (*errors_size >> 1);
1499+
EG(errors->size)++;
1500+
if (EG(errors->size) == EG(errors->capacity)) {
15041501
// not sure we can get high number of errors so safe `might be` over cautious here
1505-
errors_size = safe_erealloc(errors_size, sizeof(size_t) + (tmp * sizeof(zend_error_info *)), 1, 0);
1506-
*errors_size = tmp;
1502+
uint32_t capacity = EG(errors->capacity) + (EG(errors->capacity) >> 1);
1503+
EG(errors) = safe_erealloc(EG(errors), sizeof(*EG(errors)) + capacity * sizeof(zend_error_info *), 1, 0);
1504+
EG(errors->capacity) = capacity;
15071505
}
15081506
}
1509-
EG(errors) = (zend_error_info **)(errors_size + 1);
1510-
EG(errors)[EG(num_errors)-1] = info;
1507+
EG(errors->buf)[EG(errors->size)-1] = info;
15111508

15121509
/* Do not process non-fatal recorded error */
15131510
if (!(type & E_FATAL_ERRORS) || (type & E_DONT_BAIL)) {
@@ -1590,17 +1587,23 @@ ZEND_API ZEND_COLD void zend_error_zstr_at(
15901587
}
15911588

15921589
orig_record_errors = EG(record_errors);
1593-
orig_num_errors = EG(num_errors);
1594-
orig_errors = EG(errors);
15951590
EG(record_errors) = false;
1596-
EG(num_errors) = 0;
1597-
EG(errors) = NULL;
1591+
1592+
if (EG(errors)) {
1593+
orig_num_errors = EG(errors->size);
1594+
orig_cap_errors = EG(errors->capacity);
1595+
orig_errors = EG(errors->buf);
1596+
}
15981597

15991598
res = call_user_function(CG(function_table), NULL, &orig_user_error_handler, &retval, 4, params);
16001599

16011600
EG(record_errors) = orig_record_errors;
1602-
EG(num_errors) = orig_num_errors;
1603-
EG(errors) = orig_errors;
1601+
1602+
if (EG(errors)) {
1603+
EG(errors->capacity) = orig_cap_errors;
1604+
EG(errors->size) = orig_num_errors;
1605+
memcpy(EG(errors->buf), orig_errors, EG(errors->capacity) * sizeof(zend_error_info *));
1606+
}
16041607

16051608
if (res == SUCCESS) {
16061609
if (Z_TYPE(retval) != IS_UNDEF) {
@@ -1795,8 +1798,7 @@ ZEND_API void zend_begin_record_errors(void)
17951798
{
17961799
ZEND_ASSERT(!EG(record_errors) && "Error recording already enabled");
17971800
EG(record_errors) = true;
1798-
EG(num_errors) = 0;
1799-
EG(errors) = NULL;
1801+
zend_free_recorded_errors();
18001802
}
18011803

18021804
ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info **errors)
@@ -1810,24 +1812,25 @@ ZEND_API void zend_emit_recorded_errors_ex(uint32_t num_errors, zend_error_info
18101812
ZEND_API void zend_emit_recorded_errors(void)
18111813
{
18121814
EG(record_errors) = false;
1813-
zend_emit_recorded_errors_ex(EG(num_errors), EG(errors));
1815+
if (EG(errors)) {
1816+
zend_emit_recorded_errors_ex(EG(errors->size), EG(errors->buf));
1817+
}
18141818
}
18151819

18161820
ZEND_API void zend_free_recorded_errors(void)
18171821
{
1818-
if (!EG(num_errors)) {
1822+
if (!EG(errors)) {
18191823
return;
18201824
}
18211825

1822-
for (uint32_t i = 0; i < EG(num_errors); i++) {
1823-
zend_error_info *info = EG(errors)[i];
1826+
for (uint32_t i = 0; i < EG(errors->size); i++) {
1827+
zend_error_info *info = EG(errors->buf)[i];
18241828
zend_string_release(info->filename);
18251829
zend_string_release(info->message);
18261830
efree_size(info, sizeof(zend_error_info));
18271831
}
1828-
efree(((size_t *)EG(errors)) - 1);
1832+
efree(EG(errors));
18291833
EG(errors) = NULL;
1830-
EG(num_errors) = 0;
18311834
}
18321835

18331836
ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */

Zend/zend_execute_API.c

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

195195
EG(record_errors) = false;
196-
EG(num_errors) = 0;
197196
EG(errors) = NULL;
198197

199198
EG(filename_override) = NULL;

Zend/zend_globals.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -298,8 +298,6 @@ struct _zend_executor_globals {
298298
* and their processing is delayed until zend_emit_recorded_errors()
299299
* is called or a fatal diagnostic is emitted. */
300300
bool record_errors;
301-
uint32_t num_errors;
302-
zend_error_info **errors;
303301

304302
/* Override filename or line number of thrown errors and exceptions */
305303
zend_string *filename_override;
@@ -322,6 +320,11 @@ struct _zend_executor_globals {
322320
HashTable callable_convert_cache;
323321

324322
void *reserved[ZEND_MAX_RESERVED_RESOURCES];
323+
struct {
324+
uint32_t size;
325+
uint32_t capacity;
326+
zend_error_info *buf[];
327+
} *errors;
325328
};
326329

327330
#define EG_FLAGS_INITIAL (0)

ext/opcache/ZendAccelerator.c

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1973,9 +1973,9 @@ static zend_op_array *file_cache_compile_file(zend_file_handle *file_handle, int
19731973
persistent_script = opcache_compile_file(file_handle, type, &op_array);
19741974

19751975
if (persistent_script) {
1976-
if (ZCG(accel_directives).record_warnings) {
1977-
persistent_script->num_warnings = EG(num_errors);
1978-
persistent_script->warnings = EG(errors);
1976+
if (ZCG(accel_directives).record_warnings && EG(errors)) {
1977+
persistent_script->num_warnings = EG(errors->size);
1978+
persistent_script->warnings = EG(errors->buf);
19791979
}
19801980

19811981
from_memory = false;
@@ -2198,9 +2198,9 @@ zend_op_array *persistent_compile_file(zend_file_handle *file_handle, int type)
21982198
*/
21992199
from_shared_memory = false;
22002200
if (persistent_script) {
2201-
if (ZCG(accel_directives).record_warnings) {
2202-
persistent_script->num_warnings = EG(num_errors);
2203-
persistent_script->warnings = EG(errors);
2201+
if (ZCG(accel_directives).record_warnings && EG(errors)) {
2202+
persistent_script->num_warnings = EG(errors->size);
2203+
persistent_script->warnings = EG(errors->buf);
22042204
}
22052205

22062206
/* See GH-17246: we disable GC so that user code cannot be executed during the optimizer run. */
@@ -2428,7 +2428,9 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24282428
}
24292429
ZCG(current_persistent_script) = &dummy;
24302430
zend_persist_class_entry_calc(ce);
2431-
zend_persist_warnings_calc(EG(num_errors), EG(errors));
2431+
if (EG(errors)) {
2432+
zend_persist_warnings_calc(EG(errors->size), EG(errors->buf));
2433+
}
24322434
size = dummy.size;
24332435

24342436
zend_shared_alloc_clear_xlat_table();
@@ -2498,8 +2500,13 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24982500
JIT_G(on) = jit_on_old;
24992501
#endif
25002502

2501-
entry->num_warnings = EG(num_errors);
2502-
entry->warnings = zend_persist_warnings(EG(num_errors), EG(errors));
2503+
if (EG(errors)) {
2504+
entry->num_warnings = EG(errors->size);
2505+
entry->warnings = zend_persist_warnings(EG(errors->size), EG(errors->buf));
2506+
} else {
2507+
entry->num_warnings = 0;
2508+
entry->warnings = NULL;
2509+
}
25032510
entry->next = proto->inheritance_cache;
25042511
proto->inheritance_cache = entry;
25052512

@@ -4133,9 +4140,11 @@ static void preload_link(void)
41334140
/* Remember the last error. */
41344141
zend_error_cb = orig_error_cb;
41354142
EG(record_errors) = false;
4136-
ZEND_ASSERT(EG(num_errors) > 0);
4137-
zend_hash_update_ptr(&errors, key, EG(errors)[EG(num_errors)-1]);
4138-
EG(num_errors)--;
4143+
if (EG(errors)) {
4144+
ZEND_ASSERT(EG(errors->size) > 0);
4145+
zend_hash_update_ptr(&errors, key, EG(errors->buf)[EG(errors->size)-1]);
4146+
EG(errors->size)--;
4147+
}
41394148
} zend_end_try();
41404149
CG(in_compilation) = false;
41414150
CG(compiled_filename) = NULL;

0 commit comments

Comments
 (0)