Skip to content

Commit 019cdd0

Browse files
committed
Changes for hooks
1 parent 88e2844 commit 019cdd0

File tree

1 file changed

+50
-45
lines changed

1 file changed

+50
-45
lines changed

Zend/zend_exceptions.c

Lines changed: 50 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -254,44 +254,59 @@ ZEND_API void zend_clear_exception(void) /* {{{ */
254254
}
255255
/* }}} */
256256

257-
/* Same as OBJ_PROP_NUM(), but checks the offset is correct when Zend is built in debug mode. */
258-
static zend_always_inline zval *zend_obj_prop_num_checked(zend_object *object, uint32_t prop_num, zend_string *str)
257+
/* Same as writing to OBJ_PROP_NUM() when there are no hooks,
258+
* but checks the offset is correct when Zend is built in debug mode.
259+
* This is faster than going through the regular property write routine when the offset is known at compile time. */
260+
static void zend_update_property_num_checked(zend_object *object, uint32_t prop_num, zend_string *member, zval *value)
259261
{
262+
if (UNEXPECTED(object->ce->num_hooked_props > 0)) {
263+
/* Property may have been overridden with a hook. */
264+
zend_update_property_ex(object->ce, object, member, value);
265+
zval_ptr_dtor(value);
266+
return;
267+
}
260268
#if ZEND_DEBUG
261269
zend_class_entry *old_scope = EG(fake_scope);
262270
EG(fake_scope) = i_get_exception_base(object);
263-
const zend_property_info *prop_info = zend_get_property_info(object->ce, str, true);
271+
const zend_property_info *prop_info = zend_get_property_info(object->ce, member, true);
264272
ZEND_ASSERT(OBJ_PROP_TO_NUM(prop_info->offset) == prop_num);
265273
EG(fake_scope) = old_scope;
266-
#else
267-
ZEND_IGNORE_VALUE(str);
268274
#endif
269-
return OBJ_PROP_NUM(object, prop_num);
275+
zval *zv = OBJ_PROP_NUM(object, prop_num);
276+
zval_ptr_safe_dtor(zv);
277+
ZVAL_COPY_VALUE(zv, value);
270278
}
271279

272280
static zend_object *zend_default_exception_new(zend_class_entry *class_type) /* {{{ */
273281
{
282+
zval tmp;
283+
zval trace;
274284
zend_string *filename;
275285

276286
zend_object *object = zend_objects_new(class_type);
277287
object_properties_init(object, class_type);
278-
zval *trace = zend_obj_prop_num_checked(object, 5, ZSTR_KNOWN(ZEND_STR_TRACE));
279288

280289
if (EG(current_execute_data)) {
281-
zend_fetch_debug_backtrace(trace,
290+
zend_fetch_debug_backtrace(&trace,
282291
0,
283292
EG(exception_ignore_args) ? DEBUG_BACKTRACE_IGNORE_ARGS : 0, 0);
284293
} else {
285-
ZVAL_EMPTY_ARRAY(trace);
294+
ZVAL_EMPTY_ARRAY(&trace);
286295
}
287296

297+
zend_update_property_num_checked(object, 5, ZSTR_KNOWN(ZEND_STR_TRACE), &trace);
298+
288299
if (EXPECTED((class_type != zend_ce_parse_error && class_type != zend_ce_compile_error)
289300
|| !(filename = zend_get_compiled_filename()))) {
290-
ZVAL_STRING(zend_obj_prop_num_checked(object, 3, ZSTR_KNOWN(ZEND_STR_FILE)), zend_get_executed_filename());
291-
ZVAL_LONG(zend_obj_prop_num_checked(object, 4, ZSTR_KNOWN(ZEND_STR_LINE)), zend_get_executed_lineno());
301+
ZVAL_STRING(&tmp, zend_get_executed_filename());
302+
zend_update_property_num_checked(object, 3, ZSTR_KNOWN(ZEND_STR_FILE), &tmp);
303+
ZVAL_LONG(&tmp, zend_get_executed_lineno());
304+
zend_update_property_num_checked(object, 4, ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
292305
} else {
293-
ZVAL_STR_COPY(zend_obj_prop_num_checked(object, 3, ZSTR_KNOWN(ZEND_STR_FILE)), filename);
294-
ZVAL_LONG(zend_obj_prop_num_checked(object, 4, ZSTR_KNOWN(ZEND_STR_LINE)), zend_get_compiled_lineno());
306+
ZVAL_STR_COPY(&tmp, filename);
307+
zend_update_property_num_checked(object, 3, ZSTR_KNOWN(ZEND_STR_FILE), &tmp);
308+
ZVAL_LONG(&tmp, zend_get_compiled_lineno());
309+
zend_update_property_num_checked(object, 4, ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
295310
}
296311

297312
return object;
@@ -311,7 +326,7 @@ ZEND_METHOD(Exception, __construct)
311326
{
312327
zend_string *message = NULL;
313328
zend_long code = 0;
314-
zval *object, *previous = NULL;
329+
zval tmp, *object, *previous = NULL;
315330

316331
object = ZEND_THIS;
317332

@@ -320,21 +335,18 @@ ZEND_METHOD(Exception, __construct)
320335
}
321336

322337
if (message) {
323-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 0, ZSTR_KNOWN(ZEND_STR_MESSAGE));
324-
zval_ptr_safe_dtor(tmp);
325-
ZVAL_STR_COPY(tmp, message);
338+
ZVAL_STR_COPY(&tmp, message);
339+
zend_update_property_num_checked(Z_OBJ_P(object), 0, ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp);
326340
}
327341

328342
if (code) {
329-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 2, ZSTR_KNOWN(ZEND_STR_CODE));
330-
zval_ptr_dtor(tmp);
331-
ZVAL_LONG(tmp, code);
343+
ZVAL_LONG(&tmp, code);
344+
zend_update_property_num_checked(Z_OBJ_P(object), 2, ZSTR_KNOWN(ZEND_STR_CODE), &tmp);
332345
}
333346

334347
if (previous) {
335-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 6, ZSTR_KNOWN(ZEND_STR_PREVIOUS));
336-
zval_ptr_safe_dtor(tmp);
337-
ZVAL_COPY(tmp, previous);
348+
Z_ADDREF_P(previous);
349+
zend_update_property_num_checked(Z_OBJ_P(object), 6, ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous);
338350
}
339351
}
340352
/* }}} */
@@ -364,7 +376,7 @@ ZEND_METHOD(ErrorException, __construct)
364376
zend_string *message = NULL, *filename = NULL;
365377
zend_long code = 0, severity = E_ERROR, lineno;
366378
bool lineno_is_null = 1;
367-
zval *object, *previous = NULL;
379+
zval tmp, *object, *previous = NULL;
368380

369381
if (zend_parse_parameters(ZEND_NUM_ARGS(), "|SllS!l!O!", &message, &code, &severity, &filename, &lineno, &lineno_is_null, &previous, zend_ce_throwable) == FAILURE) {
370382
RETURN_THROWS();
@@ -373,41 +385,34 @@ ZEND_METHOD(ErrorException, __construct)
373385
object = ZEND_THIS;
374386

375387
if (message) {
376-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 0, ZSTR_KNOWN(ZEND_STR_MESSAGE));
377-
zval_ptr_safe_dtor(tmp);
378-
ZVAL_STR_COPY(tmp, message);
388+
ZVAL_STR_COPY(&tmp, message);
389+
zend_update_property_num_checked(Z_OBJ_P(object), 0, ZSTR_KNOWN(ZEND_STR_MESSAGE), &tmp);
379390
}
380391

381392
if (code) {
382-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 2, ZSTR_KNOWN(ZEND_STR_CODE));
383-
zval_ptr_dtor(tmp);
384-
ZVAL_LONG(tmp, code);
393+
ZVAL_LONG(&tmp, code);
394+
zend_update_property_num_checked(Z_OBJ_P(object), 2, ZSTR_KNOWN(ZEND_STR_CODE), &tmp);
385395
}
386396

387397
if (previous) {
388-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 6, ZSTR_KNOWN(ZEND_STR_PREVIOUS));
389-
zval_ptr_safe_dtor(tmp);
390-
ZVAL_COPY(tmp, previous);
398+
Z_ADDREF_P(previous);
399+
zend_update_property_num_checked(Z_OBJ_P(object), 6, ZSTR_KNOWN(ZEND_STR_PREVIOUS), previous);
391400
}
392401

393-
{
394-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 7, ZSTR_KNOWN(ZEND_STR_SEVERITY));
395-
zval_ptr_dtor(tmp);
396-
ZVAL_LONG(tmp, severity);
397-
}
402+
ZVAL_LONG(&tmp, severity);
403+
zend_update_property_num_checked(Z_OBJ_P(object), 7, ZSTR_KNOWN(ZEND_STR_SEVERITY), &tmp);
398404

399405
if (filename) {
400-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 3, ZSTR_KNOWN(ZEND_STR_FILE));
401-
zval_ptr_dtor(tmp);
402-
ZVAL_STR_COPY(tmp, filename);
406+
ZVAL_STR_COPY(&tmp, filename);
407+
zend_update_property_num_checked(Z_OBJ_P(object), 3, ZSTR_KNOWN(ZEND_STR_FILE), &tmp);
403408
}
404409

405-
zval *tmp = zend_obj_prop_num_checked(Z_OBJ_P(object), 4, ZSTR_KNOWN(ZEND_STR_LINE));
406-
zval_ptr_dtor(tmp);
407410
if (!lineno_is_null) {
408-
ZVAL_LONG(tmp, lineno);
411+
ZVAL_LONG(&tmp, lineno);
412+
zend_update_property_num_checked(Z_OBJ_P(object), 4, ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
409413
} else if (filename) {
410-
ZVAL_LONG(tmp, 0);
414+
ZVAL_LONG(&tmp, 0);
415+
zend_update_property_num_checked(Z_OBJ_P(object), 4, ZSTR_KNOWN(ZEND_STR_LINE), &tmp);
411416
}
412417
}
413418
/* }}} */

0 commit comments

Comments
 (0)