Skip to content

Commit d2a8ec9

Browse files
committed
Test performance with RT_CONSTANT check
1 parent cfd7da7 commit d2a8ec9

10 files changed

+96
-101
lines changed

Zend/tests/bug78598.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ $my_var[0] .= "xyz";
1212
var_dump($my_var);
1313

1414
$my_var = null;
15-
$my_var[0][0] .= "xyz";
15+
$my_var[0][0][0] .= "xyz";
1616
var_dump($my_var);
1717

1818
$my_var = null;

Zend/tests/delayed_error_001.phpt

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
Delayed error 001
3+
--FILE--
4+
<?php
5+
$array[0][1] .= 'foo';
6+
$array[2][3]++;
7+
$array[3][4]--;
8+
++$array[5][6];
9+
--$array[7][8];
10+
$array[9][10] += 42;
11+
?>
12+
--EXPECTF--
13+
Warning: Undefined variable $array in %s on line %d
14+
15+
Warning: Undefined array key 0 in %s on line %d
16+
17+
Warning: Undefined array key 1 in %s on line %d
18+
19+
Warning: Undefined array key 2 in %s on line %d
20+
21+
Warning: Undefined array key 3 in %s on line %d
22+
23+
Warning: Decrement on type null has no effect, this will change in the next major version of PHP in %s on line %d
24+
25+
Warning: Undefined array key 3 in %s on line %d
26+
27+
Warning: Undefined array key 4 in %s on line %d
28+
29+
Warning: Undefined array key 5 in %s on line %d
30+
31+
Warning: Undefined array key 6 in %s on line %d
32+
33+
Warning: Decrement on type null has no effect, this will change in the next major version of PHP in %s on line %d
34+
35+
Warning: Undefined array key 7 in %s on line %d
36+
37+
Warning: Undefined array key 8 in %s on line %d
38+
39+
Warning: Undefined array key 9 in %s on line %d
40+
41+
Warning: Undefined array key 10 in %s on line %d

Zend/tests/undef_index_to_exception.phpt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,14 @@ try {
3737
?>
3838
--EXPECT--
3939
Undefined array key 0
40-
array(0) {
40+
array(1) {
41+
[0]=>
42+
string(3) "xyz"
4143
}
4244
Undefined array key "key"
43-
array(0) {
45+
array(1) {
46+
[0]=>
47+
string(3) "xyz"
4448
}
4549
Undefined global variable $test
4650
Undefined variable $test

Zend/zend.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1736,6 +1736,8 @@ ZEND_API ZEND_COLD void zend_error_delayed(int type, const char *format, ...)
17361736
if (EG(current_execute_data)->opline != EG(delayed_error_op)) {
17371737
EG(opline_before_exception) = EG(current_execute_data)->opline;
17381738
EG(current_execute_data)->opline = EG(delayed_error_op);
1739+
/* Reset to ZEND_HANDLE_DELAYED_ERROR */
1740+
EG(delayed_error_op)[1] = EG(delayed_error_op)[2];
17391741
}
17401742
}
17411743

Zend/zend.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -343,9 +343,6 @@ extern ZEND_API zend_string *(*zend_resolve_path)(zend_string *filename);
343343
extern ZEND_API zend_result (*zend_post_startup_cb)(void);
344344
extern ZEND_API void (*zend_post_shutdown_cb)(void);
345345

346-
/* Callback for loading of not preloaded part of the script */
347-
extern ZEND_API zend_result (*zend_preload_autoload)(zend_string *filename);
348-
349346
ZEND_API ZEND_COLD void zend_error(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
350347
ZEND_API ZEND_COLD ZEND_NORETURN void zend_error_noreturn(int type, const char *format, ...) ZEND_ATTRIBUTE_FORMAT(printf, 2, 3);
351348
/* For custom format specifiers like H */

Zend/zend_compile.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -732,7 +732,7 @@ ZEND_STATIC_ASSERT(ZEND_MM_ALIGNED_SIZE(sizeof(zval)) == sizeof(zval),
732732

733733
/* run-time constant */
734734
# define RT_CONSTANT(opline, node) \
735-
((zval*)(((char*)(opline)) + (int32_t)(node).constant))
735+
((zval*)(((char*)((zend_op*)(opline) != &EG(delayed_error_op)[0] ? (zend_op*)(opline) : EG(opline_before_exception))) + (int32_t)(node).constant))
736736

737737
/* convert constant from compile-time to run-time */
738738
# define ZEND_PASS_TWO_UPDATE_CONSTANT(op_array, opline, node) do { \

Zend/zend_execute.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -436,7 +436,9 @@ static zend_always_inline zval *_get_op_data_zval_ptr_r(int op_type, znode_op no
436436
}
437437
} else {
438438
if (op_type == IS_CONST) {
439-
return RT_CONSTANT(opline + 1, node);
439+
return opline != &EG(delayed_error_op)[0]
440+
? RT_CONSTANT(opline + 1, node)
441+
: RT_CONSTANT(EG(opline_before_exception) + 1, node);
440442
} else if (op_type == IS_CV) {
441443
return _get_zval_ptr_cv_BP_VAR_R(node.var EXECUTE_DATA_CC);
442444
} else {
@@ -476,7 +478,9 @@ static zend_always_inline ZEND_ATTRIBUTE_UNUSED zval *_get_op_data_zval_ptr_dere
476478
}
477479
} else {
478480
if (op_type == IS_CONST) {
479-
return RT_CONSTANT(opline + 1, node);
481+
return opline != &EG(delayed_error_op)[0]
482+
? RT_CONSTANT(opline + 1, node)
483+
: RT_CONSTANT(EG(opline_before_exception) + 1, node);
480484
} else if (op_type == IS_CV) {
481485
return _get_zval_ptr_cv_deref_BP_VAR_R(node.var EXECUTE_DATA_CC);
482486
} else {
@@ -2500,7 +2504,6 @@ static zend_always_inline zval *zend_fetch_dimension_address_inner(HashTable *ht
25002504
retval = &EG(uninitialized_zval);
25012505
break;
25022506
case BP_VAR_RW:
2503-
// retval = zend_undefined_offset_write(ht, hval);
25042507
zend_undefined_offset_delayed(hval);
25052508
retval = zend_hash_index_add_new(ht, hval, &EG(uninitialized_zval));
25062509
break;

Zend/zend_globals.h

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,6 @@ struct _zend_executor_globals {
247247
const zend_op *opline_before_exception;
248248
zend_op exception_op[3];
249249
/* FIXME: Is this safe for VM reentry? We may have to save/restore this value. */
250-
/* Index 1-2 are always set to HANDLE_DELAYED_ERROR. When emitting a delayed error, we set
251-
* EG(current_execute_data)->opline to index 0. Index 0 is used for delaying notices of
252-
* FETCH/ASSIGN sequences. If HANDLE_DELAYED_ERROR detects that the last opcode produced an
253-
* INDIRECT value it sets EG(delayed_error_op)[0] to the next opcode. After the opcode has
254-
* executed it advances once again to the HANDLE_DELAYED_ERROR opcode which will repeat this
255-
* check. If the last opcode did not produce an INDIRECT value, it can safely emit the warning. */
256250
zend_op delayed_error_op[3];
257251

258252
struct _zend_module_entry *current_module;

Zend/zend_vm_def.h

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,9 +1163,7 @@ ZEND_VM_C_LABEL(assign_dim_op_array):
11631163
SEPARATE_ARRAY(container);
11641164
ht = Z_ARRVAL_P(container);
11651165
ZEND_VM_C_LABEL(assign_dim_op_new_array):
1166-
dim = OP2_TYPE == IS_CONST && opline == &EG(delayed_error_op)[0]
1167-
? RT_CONSTANT(EG(opline_before_exception), opline->op2)
1168-
: GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1166+
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
11691167
if (OP2_TYPE == IS_UNUSED) {
11701168
var_ptr = zend_hash_next_index_insert(ht, &EG(uninitialized_zval));
11711169
if (UNEXPECTED(!var_ptr)) {
@@ -1212,9 +1210,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12121210
if (EXPECTED(Z_TYPE_P(container) == IS_OBJECT)) {
12131211
zend_object *obj = Z_OBJ_P(container);
12141212

1215-
dim = OP2_TYPE == IS_CONST && opline == &EG(delayed_error_op)[0]
1216-
? RT_CONSTANT(EG(opline_before_exception), opline->op2)
1217-
: GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1213+
dim = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
12181214
if (OP2_TYPE == IS_CONST && Z_EXTRA_P(dim) == ZEND_EXTRA_VALUE) {
12191215
dim++;
12201216
}
@@ -1238,9 +1234,7 @@ ZEND_VM_C_LABEL(assign_dim_op_new_array):
12381234
}
12391235
ZEND_VM_C_GOTO(assign_dim_op_new_array);
12401236
} else {
1241-
dim = OP2_TYPE == IS_CONST && opline == &EG(delayed_error_op)[0]
1242-
? RT_CONSTANT(EG(opline_before_exception), opline->op2)
1243-
: GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
1237+
dim = GET_OP2_ZVAL_PTR(BP_VAR_R);
12441238
zend_binary_assign_op_dim_slow(container, dim OPLINE_CC EXECUTE_DATA_CC);
12451239
ZEND_VM_C_LABEL(assign_dim_op_ret_null):
12461240
FREE_OP_DATA();
@@ -8132,9 +8126,8 @@ ZEND_VM_HANDLER(204, ZEND_HANDLE_DELAYED_ERROR, ANY, ANY)
81328126
EG(delayed_error_op)[1] = EG(delayed_error_op)[2];
81338127
}
81348128
EG(opline_before_exception) = next_op;
8135-
EG(current_execute_data)->opline = EG(delayed_error_op);
81368129

8137-
ZEND_VM_SET_NEXT_OPCODE(EG(delayed_error_op));
8130+
ZEND_VM_SET_NEXT_OPCODE(&EG(delayed_error_op)[0]);
81388131
} else {
81398132
/* Clear EG(delayed_errors), as more errors may be delayed while we are handling these. */
81408133
HashTable ht;
@@ -8151,9 +8144,14 @@ ZEND_VM_HANDLER(204, ZEND_HANDLE_DELAYED_ERROR, ANY, ANY)
81518144
zend_hash_destroy(&ht);
81528145

81538146
if (EG(exception)) {
8147+
/* EG(opline_before_exception) is set to &EG(delayed_error_op)[0] by the throwing opline.
8148+
* Reset it to the original opline. */
8149+
EG(opline_before_exception) = prev_op;
81548150
HANDLE_EXCEPTION();
81558151
}
81568152

8153+
EG(opline_before_exception) = next_op;
8154+
81578155
ZEND_VM_SET_NEXT_OPCODE(next_op);
81588156
}
81598157

0 commit comments

Comments
 (0)