@@ -59,6 +59,14 @@ typedef struct _zend_loop_var {
59
59
uint32_t try_catch_offset ;
60
60
} zend_loop_var ;
61
61
62
+ #define ZEND_SHORT_CIRCUITING_SCOPE_ISSET (1 << 0)
63
+ #define ZEND_SHORT_CIRCUITING_SCOPE_EMPTY (1 << 1)
64
+
65
+ typedef struct _zend_short_circuiting_scope {
66
+ zend_stack jump_opnums ;
67
+ zend_bool skip ;
68
+ } zend_short_circuiting_scope ;
69
+
62
70
static inline uint32_t zend_alloc_cache_slots (unsigned count ) {
63
71
if (count == 0 ) {
64
72
return (uint32_t ) -1 ;
@@ -368,7 +376,7 @@ void zend_init_compiler_data_structures(void) /* {{{ */
368
376
{
369
377
zend_stack_init (& CG (loop_var_stack ), sizeof (zend_loop_var ));
370
378
zend_stack_init (& CG (delayed_oplines_stack ), sizeof (zend_op ));
371
- zend_stack_init (& CG (short_circuiting_labels ), sizeof (zend_stack * ));
379
+ zend_stack_init (& CG (short_circuiting_scopes ), sizeof (zend_short_circuiting_scope ));
372
380
CG (active_class_entry ) = NULL ;
373
381
CG (in_compilation ) = 0 ;
374
382
CG (skip_shebang ) = 0 ;
@@ -422,7 +430,7 @@ void shutdown_compiler(void) /* {{{ */
422
430
{
423
431
zend_stack_destroy (& CG (loop_var_stack ));
424
432
zend_stack_destroy (& CG (delayed_oplines_stack ));
425
- zend_stack_destroy (& CG (short_circuiting_labels ));
433
+ zend_stack_destroy (& CG (short_circuiting_scopes ));
426
434
zend_hash_destroy (& CG (filenames_table ));
427
435
zend_arena_destroy (CG (arena ));
428
436
@@ -2225,23 +2233,30 @@ static zend_op *zend_delayed_compile_end(uint32_t offset) /* {{{ */
2225
2233
}
2226
2234
/* }}} */
2227
2235
2228
- zend_bool zend_should_start_short_circuiting ()
2236
+ static zend_bool zend_should_begin_short_circuiting_scope ()
2229
2237
{
2230
2238
return !CG (short_circuiting );
2231
2239
}
2232
2240
2233
- void zend_start_short_circuiting ()
2241
+ static zend_short_circuiting_scope * zend_current_short_circuiting_scope ()
2242
+ {
2243
+ return zend_stack_top (& CG (short_circuiting_scopes ));
2244
+ }
2245
+
2246
+ static void zend_begin_short_circuiting_scope ()
2234
2247
{
2235
2248
CG (short_circuiting ) = 1 ;
2236
2249
2237
- zend_stack * labels = emalloc (sizeof (zend_stack ));
2238
- zend_stack_init (labels , sizeof (uint32_t ));
2239
- zend_stack_push (& CG (short_circuiting_labels ), & labels );
2250
+ zend_short_circuiting_scope scope ;
2251
+ zend_stack_init (& scope .jump_opnums , sizeof (uint32_t ));
2252
+ scope .skip = 0 ;
2253
+ zend_stack_push (& CG (short_circuiting_scopes ), & scope );
2240
2254
}
2241
2255
2242
- void zend_end_short_circuiting (znode * result )
2256
+ static void zend_end_short_circuiting_scope (znode * result )
2243
2257
{
2244
- zend_stack * labels = * (zend_stack * * )zend_stack_top (& CG (short_circuiting_labels ));
2258
+ zend_short_circuiting_scope * scope = zend_current_short_circuiting_scope ();
2259
+ zend_stack * labels = & scope -> jump_opnums ;
2245
2260
zend_bool contains_short_circuiting_operators = !zend_stack_is_empty (labels );
2246
2261
2247
2262
uint32_t end_label = 0 ;
@@ -2266,9 +2281,8 @@ void zend_end_short_circuiting(znode *result)
2266
2281
2267
2282
CG (short_circuiting ) = 0 ;
2268
2283
2269
- zend_stack_del_top (& CG (short_circuiting_labels ));
2284
+ zend_stack_del_top (& CG (short_circuiting_scopes ));
2270
2285
zend_stack_destroy (labels );
2271
- efree (labels );
2272
2286
}
2273
2287
2274
2288
#define ZEND_MEMOIZE_NONE 0
@@ -2759,9 +2773,10 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t
2759
2773
2760
2774
uint32_t jmp_call = zend_emit_cond_jump (ZEND_JMPZ , & typecheck_node , 0 );
2761
2775
2762
- zend_stack * short_circuiting_labels = * (zend_stack * * )zend_stack_top (& CG (short_circuiting_labels ));
2776
+ zend_short_circuiting_scope * short_circuiting_scope = zend_current_short_circuiting_scope ();
2777
+ zend_stack * short_circuiting_scopes = & short_circuiting_scope -> jump_opnums ;
2763
2778
uint32_t jmp_end = zend_emit_jump (0 );
2764
- zend_stack_push (short_circuiting_labels , & jmp_end );
2779
+ zend_stack_push (short_circuiting_scopes , & jmp_end );
2765
2780
zend_update_jump_target_to_next (jmp_call );
2766
2781
}
2767
2782
@@ -3010,9 +3025,9 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
3010
3025
zend_op * opline ;
3011
3026
uint32_t offset ;
3012
3027
3013
- zend_bool start_short_circuiting = zend_should_start_short_circuiting ();
3028
+ zend_bool start_short_circuiting = zend_should_begin_short_circuiting_scope ();
3014
3029
if (start_short_circuiting ) {
3015
- zend_start_short_circuiting ();
3030
+ zend_begin_short_circuiting_scope ();
3016
3031
}
3017
3032
3018
3033
if (is_this_fetch (var_ast )) {
@@ -3123,7 +3138,7 @@ void zend_compile_assign(znode *result, zend_ast *ast) /* {{{ */
3123
3138
}
3124
3139
3125
3140
if (start_short_circuiting ) {
3126
- zend_end_short_circuiting (result );
3141
+ zend_end_short_circuiting_scope (result );
3127
3142
}
3128
3143
}
3129
3144
/* }}} */
@@ -3202,7 +3217,7 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
3202
3217
zend_ast * var_ast = ast -> child [0 ];
3203
3218
zend_ast * expr_ast = ast -> child [1 ];
3204
3219
uint32_t opcode = ast -> attr ;
3205
- zend_bool start_short_circuiting = zend_should_start_short_circuiting ();
3220
+ zend_bool start_short_circuiting = zend_should_begin_short_circuiting_scope ();
3206
3221
3207
3222
znode var_node , expr_node ;
3208
3223
zend_op * opline ;
@@ -3211,7 +3226,7 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
3211
3226
zend_ensure_writable_variable (var_ast );
3212
3227
3213
3228
if (start_short_circuiting ) {
3214
- zend_start_short_circuiting ();
3229
+ zend_begin_short_circuiting_scope ();
3215
3230
}
3216
3231
3217
3232
switch (var_ast -> kind ) {
@@ -3271,7 +3286,7 @@ void zend_compile_compound_assign(znode *result, zend_ast *ast) /* {{{ */
3271
3286
}
3272
3287
3273
3288
if (start_short_circuiting ) {
3274
- zend_end_short_circuiting (result );
3289
+ zend_end_short_circuiting_scope (result );
3275
3290
}
3276
3291
}
3277
3292
/* }}} */
@@ -4240,9 +4255,10 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
4240
4255
4241
4256
uint32_t jmp_call = zend_emit_cond_jump (ZEND_JMPZ , & typecheck_node , 0 );
4242
4257
4243
- zend_stack * short_circuiting_labels = * (zend_stack * * )zend_stack_top (& CG (short_circuiting_labels ));
4258
+ zend_short_circuiting_scope * short_circuiting_scope = zend_current_short_circuiting_scope ();
4259
+ zend_stack * short_circuiting_scopes = & short_circuiting_scope -> jump_opnums ;
4244
4260
uint32_t jmp_end = zend_emit_jump (0 );
4245
- zend_stack_push (short_circuiting_labels , & jmp_end );
4261
+ zend_stack_push (short_circuiting_scopes , & jmp_end );
4246
4262
zend_update_jump_target_to_next (jmp_call );
4247
4263
}
4248
4264
@@ -7797,9 +7813,9 @@ void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */
7797
7813
7798
7814
zend_ensure_writable_variable (var_ast );
7799
7815
7800
- zend_bool start_short_circuiting = zend_should_start_short_circuiting ();
7816
+ zend_bool start_short_circuiting = zend_should_begin_short_circuiting_scope ();
7801
7817
if (start_short_circuiting ) {
7802
- zend_start_short_circuiting ();
7818
+ zend_begin_short_circuiting_scope ();
7803
7819
}
7804
7820
7805
7821
if (var_ast -> kind == ZEND_AST_PROP || var_ast -> kind == ZEND_AST_NULLSAFE_PROP ) {
@@ -7818,7 +7834,7 @@ void zend_compile_post_incdec(znode *result, zend_ast *ast) /* {{{ */
7818
7834
}
7819
7835
7820
7836
if (start_short_circuiting ) {
7821
- zend_end_short_circuiting (result );
7837
+ zend_end_short_circuiting_scope (result );
7822
7838
}
7823
7839
}
7824
7840
/* }}} */
@@ -7830,9 +7846,9 @@ void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */
7830
7846
7831
7847
zend_ensure_writable_variable (var_ast );
7832
7848
7833
- zend_bool start_short_circuiting = zend_should_start_short_circuiting ();
7849
+ zend_bool start_short_circuiting = zend_should_begin_short_circuiting_scope ();
7834
7850
if (start_short_circuiting ) {
7835
- zend_start_short_circuiting ();
7851
+ zend_begin_short_circuiting_scope ();
7836
7852
}
7837
7853
7838
7854
if (var_ast -> kind == ZEND_AST_PROP || var_ast -> kind == ZEND_AST_NULLSAFE_PROP ) {
@@ -7853,7 +7869,7 @@ void zend_compile_pre_incdec(znode *result, zend_ast *ast) /* {{{ */
7853
7869
}
7854
7870
7855
7871
if (start_short_circuiting ) {
7856
- zend_end_short_circuiting (result );
7872
+ zend_end_short_circuiting_scope (result );
7857
7873
}
7858
7874
}
7859
7875
/* }}} */
@@ -8003,10 +8019,10 @@ void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */
8003
8019
zend_op * opline ;
8004
8020
uint32_t coalesce_opnum ;
8005
8021
zend_bool need_frees = 0 ;
8006
- zend_bool start_short_circuiting = zend_should_start_short_circuiting ();
8022
+ zend_bool start_short_circuiting = zend_should_begin_short_circuiting_scope ();
8007
8023
8008
8024
if (start_short_circuiting ) {
8009
- zend_start_short_circuiting ();
8025
+ zend_begin_short_circuiting_scope ();
8010
8026
}
8011
8027
8012
8028
/* Remember expressions compiled during the initial BP_VAR_IS lookup,
@@ -8097,7 +8113,7 @@ void zend_compile_assign_coalesce(znode *result, zend_ast *ast) /* {{{ */
8097
8113
CG (memoize_mode ) = orig_memoize_mode ;
8098
8114
8099
8115
if (start_short_circuiting ) {
8100
- zend_end_short_circuiting (result );
8116
+ zend_end_short_circuiting_scope (result );
8101
8117
}
8102
8118
}
8103
8119
/* }}} */
@@ -8243,6 +8259,9 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
8243
8259
8244
8260
ZEND_ASSERT (ast -> kind == ZEND_AST_ISSET || ast -> kind == ZEND_AST_EMPTY );
8245
8261
8262
+ zend_begin_short_circuiting_scope ();
8263
+ zend_current_short_circuiting_scope ()-> skip = 1 ;
8264
+
8246
8265
if (!zend_is_variable (var_ast )) {
8247
8266
if (ast -> kind == ZEND_AST_EMPTY ) {
8248
8267
/* empty(expr) can be transformed to !expr */
@@ -8288,6 +8307,8 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
8288
8307
if (!(ast -> kind == ZEND_AST_ISSET )) {
8289
8308
opline -> extended_value |= ZEND_ISEMPTY ;
8290
8309
}
8310
+
8311
+ zend_end_short_circuiting_scope (result );
8291
8312
}
8292
8313
/* }}} */
8293
8314
@@ -9187,16 +9208,16 @@ zend_op *zend_compile_var_inner(znode *result, zend_ast *ast, uint32_t type, int
9187
9208
9188
9209
zend_op * zend_compile_var (znode * result , zend_ast * ast , uint32_t type , int by_ref , zend_bool allow_starting_short_circuiting ) /* {{{ */
9189
9210
{
9190
- zend_bool start_short_circuiting = allow_starting_short_circuiting && zend_should_start_short_circuiting ();
9211
+ zend_bool start_short_circuiting = allow_starting_short_circuiting && zend_should_begin_short_circuiting_scope ();
9191
9212
9192
9213
if (start_short_circuiting ) {
9193
- zend_start_short_circuiting ();
9214
+ zend_begin_short_circuiting_scope ();
9194
9215
}
9195
9216
9196
9217
zend_op * opcode = zend_compile_var_inner (result , ast , type , by_ref );
9197
9218
9198
9219
if (start_short_circuiting ) {
9199
- zend_end_short_circuiting (result );
9220
+ zend_end_short_circuiting_scope (result );
9200
9221
}
9201
9222
9202
9223
return opcode ;
0 commit comments