@@ -64,7 +64,7 @@ typedef struct _zend_loop_var {
64
64
65
65
typedef struct _zend_short_circuiting_scope {
66
66
zend_stack jump_opnums ;
67
- zend_bool skip ;
67
+ zend_bool flags ;
68
68
} zend_short_circuiting_scope ;
69
69
70
70
static inline uint32_t zend_alloc_cache_slots (unsigned count ) {
@@ -2177,6 +2177,7 @@ static inline void zend_update_jump_target(uint32_t opnum_jump, uint32_t opnum_t
2177
2177
case ZEND_JMPNZ_EX :
2178
2178
case ZEND_JMP_SET :
2179
2179
case ZEND_COALESCE :
2180
+ case ZEND_JMP_NULL :
2180
2181
opline -> op2 .opline_num = opnum_target ;
2181
2182
break ;
2182
2183
EMPTY_SWITCH_DEFAULT_CASE ()
@@ -2249,7 +2250,7 @@ static void zend_begin_short_circuiting_scope()
2249
2250
2250
2251
zend_short_circuiting_scope scope ;
2251
2252
zend_stack_init (& scope .jump_opnums , sizeof (uint32_t ));
2252
- scope .skip = 0 ;
2253
+ scope .flags = 0 ;
2253
2254
zend_stack_push (& CG (short_circuiting_scopes ), & scope );
2254
2255
}
2255
2256
@@ -2269,11 +2270,18 @@ static void zend_end_short_circuiting_scope(znode *result)
2269
2270
zend_stack_del_top (labels );
2270
2271
}
2271
2272
2272
- znode null_node ;
2273
- null_node .op_type = IS_CONST ;
2274
- ZVAL_NULL (& null_node .u .constant );
2273
+ znode result_node ;
2274
+ result_node .op_type = IS_CONST ;
2275
2275
2276
- zend_op * opline_call = zend_emit_op_tmp (NULL , ZEND_QM_ASSIGN , & null_node , NULL );
2276
+ if (scope -> flags & ZEND_SHORT_CIRCUITING_SCOPE_ISSET ) {
2277
+ ZVAL_BOOL (& result_node .u .constant , 0 );
2278
+ } else if (scope -> flags & ZEND_SHORT_CIRCUITING_SCOPE_EMPTY ) {
2279
+ ZVAL_BOOL (& result_node .u .constant , 1 );
2280
+ } else {
2281
+ ZVAL_NULL (& result_node .u .constant );
2282
+ }
2283
+
2284
+ zend_op * opline_call = zend_emit_op_tmp (NULL , ZEND_QM_ASSIGN , & result_node , NULL );
2277
2285
SET_NODE (opline_call -> result , result );
2278
2286
2279
2287
zend_update_jump_target_to_next (end_label );
@@ -2767,17 +2775,11 @@ static zend_op *zend_delayed_compile_prop(znode *result, zend_ast *ast, uint32_t
2767
2775
}
2768
2776
2769
2777
if (nullsafe ) {
2770
- znode typecheck_node ;
2771
- zend_op * typecheck_opline = zend_emit_op_tmp (& typecheck_node , ZEND_TYPE_CHECK , & obj_node , NULL );
2772
- typecheck_opline -> extended_value = 1 << IS_NULL ;
2773
-
2774
- uint32_t jmp_call = zend_emit_cond_jump (ZEND_JMPZ , & typecheck_node , 0 );
2778
+ uint32_t jmp_null = zend_emit_cond_jump (ZEND_JMP_NULL , & obj_node , 0 );
2775
2779
2776
2780
zend_short_circuiting_scope * short_circuiting_scope = zend_current_short_circuiting_scope ();
2777
2781
zend_stack * short_circuiting_scopes = & short_circuiting_scope -> jump_opnums ;
2778
- uint32_t jmp_end = zend_emit_jump (0 );
2779
- zend_stack_push (short_circuiting_scopes , & jmp_end );
2780
- zend_update_jump_target_to_next (jmp_call );
2782
+ zend_stack_push (short_circuiting_scopes , & jmp_null );
2781
2783
}
2782
2784
2783
2785
zend_compile_expr (& prop_node , prop_ast );
@@ -4249,17 +4251,11 @@ void zend_compile_method_call(znode *result, zend_ast *ast, uint32_t type) /* {{
4249
4251
}
4250
4252
4251
4253
if (nullsafe ) {
4252
- znode typecheck_node ;
4253
- zend_op * typecheck_opline = zend_emit_op_tmp (& typecheck_node , ZEND_TYPE_CHECK , & obj_node , NULL );
4254
- typecheck_opline -> extended_value = 1 << IS_NULL ;
4255
-
4256
- uint32_t jmp_call = zend_emit_cond_jump (ZEND_JMPZ , & typecheck_node , 0 );
4254
+ uint32_t jmp_null = zend_emit_cond_jump (ZEND_JMP_NULL , & obj_node , 0 );
4257
4255
4258
4256
zend_short_circuiting_scope * short_circuiting_scope = zend_current_short_circuiting_scope ();
4259
4257
zend_stack * short_circuiting_scopes = & short_circuiting_scope -> jump_opnums ;
4260
- uint32_t jmp_end = zend_emit_jump (0 );
4261
- zend_stack_push (short_circuiting_scopes , & jmp_end );
4262
- zend_update_jump_target_to_next (jmp_call );
4258
+ zend_stack_push (short_circuiting_scopes , & jmp_null );
4263
4259
}
4264
4260
4265
4261
zend_compile_expr (& method_node , method_ast );
@@ -8260,7 +8256,9 @@ void zend_compile_isset_or_empty(znode *result, zend_ast *ast) /* {{{ */
8260
8256
ZEND_ASSERT (ast -> kind == ZEND_AST_ISSET || ast -> kind == ZEND_AST_EMPTY );
8261
8257
8262
8258
zend_begin_short_circuiting_scope ();
8263
- zend_current_short_circuiting_scope ()-> skip = 1 ;
8259
+ zend_current_short_circuiting_scope ()-> flags = ast -> kind == ZEND_AST_ISSET
8260
+ ? ZEND_SHORT_CIRCUITING_SCOPE_ISSET
8261
+ : ZEND_SHORT_CIRCUITING_SCOPE_EMPTY ;
8264
8262
8265
8263
if (!zend_is_variable (var_ast )) {
8266
8264
if (ast -> kind == ZEND_AST_EMPTY ) {
0 commit comments