@@ -2736,8 +2736,9 @@ ZEND_VM_HANDLER(61, ZEND_INIT_FCALL, ANY, CONST)
2736
2736
CACHE_PTR (Z_CACHE_SLOT_P (fname ), fbc );
2737
2737
}
2738
2738
2739
- EX (call ) = zend_vm_stack_push_call_frame_ex (ZEND_CALL_NESTED_FUNCTION ,
2740
- fbc , opline -> op1 .num , NULL , NULL , EX (call ) TSRMLS_CC );
2739
+ EX (call ) = zend_vm_stack_push_call_frame_ex (
2740
+ opline -> op1 .num , ZEND_CALL_NESTED_FUNCTION ,
2741
+ fbc , opline -> extended_value , NULL , NULL , EX (call ) TSRMLS_CC );
2741
2742
2742
2743
FREE_OP2 ();
2743
2744
@@ -3126,8 +3127,7 @@ ZEND_VM_HANDLER(65, ZEND_SEND_VAL, CONST|TMP, ANY)
3126
3127
3127
3128
SAVE_OPLINE ();
3128
3129
value = GET_OP1_ZVAL_PTR (BP_VAR_R );
3129
- arg = ZEND_CALL_ARG (EX (call ), opline -> op2 .num );
3130
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3130
+ arg = ZEND_CALL_VAR (EX (call ), opline -> result .var );
3131
3131
ZVAL_COPY_VALUE (arg , value );
3132
3132
if (OP1_TYPE == IS_CONST ) {
3133
3133
if (UNEXPECTED (Z_OPT_COPYABLE_P (arg ))) {
@@ -3148,8 +3148,7 @@ ZEND_VM_HANDLER(116, ZEND_SEND_VAL_EX, CONST|TMP, ANY)
3148
3148
zend_error_noreturn (E_ERROR , "Cannot pass parameter %d by reference" , opline -> op2 .num );
3149
3149
}
3150
3150
value = GET_OP1_ZVAL_PTR (BP_VAR_R );
3151
- arg = ZEND_CALL_ARG (EX (call ), opline -> op2 .num );
3152
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3151
+ arg = ZEND_CALL_VAR (EX (call ), opline -> result .var );
3153
3152
ZVAL_COPY_VALUE (arg , value );
3154
3153
if (OP1_TYPE == IS_CONST ) {
3155
3154
if (UNEXPECTED (Z_OPT_COPYABLE_P (arg ))) {
@@ -3166,8 +3165,7 @@ ZEND_VM_HANDLER(117, ZEND_SEND_VAR, VAR|CV, ANY)
3166
3165
zend_free_op free_op1 ;
3167
3166
3168
3167
varptr = GET_OP1_ZVAL_PTR (BP_VAR_R );
3169
- arg = ZEND_CALL_ARG (EX (call ), opline -> op2 .num );
3170
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3168
+ arg = ZEND_CALL_VAR (EX (call ), opline -> result .var );
3171
3169
if (Z_ISREF_P (varptr )) {
3172
3170
ZVAL_COPY (arg , Z_REFVAL_P (varptr ));
3173
3171
FREE_OP1 ();
@@ -3211,8 +3209,7 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY)
3211
3209
}
3212
3210
}
3213
3211
3214
- arg = ZEND_CALL_ARG (EX (call ), opline -> op2 .num );
3215
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3212
+ arg = ZEND_CALL_VAR (EX (call ), opline -> result .var );
3216
3213
ZVAL_COPY_VALUE (arg , varptr );
3217
3214
3218
3215
CHECK_EXCEPTION ();
@@ -3232,8 +3229,7 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY)
3232
3229
zend_error_noreturn (E_ERROR , "Only variables can be passed by reference" );
3233
3230
}
3234
3231
3235
- arg = ZEND_CALL_ARG (EX (call ), opline -> op2 .num );
3236
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3232
+ arg = ZEND_CALL_VAR (EX (call ), opline -> result .var );
3237
3233
if (OP1_TYPE == IS_VAR && UNEXPECTED (varptr == & EG (error_zval ))) {
3238
3234
ZVAL_NEW_REF (arg , & EG (uninitialized_zval ));
3239
3235
ZEND_VM_NEXT_OPCODE ();
@@ -3265,8 +3261,7 @@ ZEND_VM_HANDLER(66, ZEND_SEND_VAR_EX, VAR|CV, ANY)
3265
3261
ZEND_VM_DISPATCH_TO_HANDLER (ZEND_SEND_REF );
3266
3262
}
3267
3263
varptr = GET_OP1_ZVAL_PTR (BP_VAR_R );
3268
- arg = ZEND_CALL_ARG (EX (call ), opline -> op2 .num );
3269
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3264
+ arg = ZEND_CALL_VAR (EX (call ), opline -> result .var );
3270
3265
if (Z_ISREF_P (varptr )) {
3271
3266
ZVAL_COPY (arg , Z_REFVAL_P (varptr ));
3272
3267
FREE_OP1 ();
@@ -3477,7 +3472,6 @@ ZEND_VM_HANDLER(119, ZEND_SEND_ARRAY, ANY, ANY)
3477
3472
zval * arg , * param , tmp ;
3478
3473
3479
3474
ZEND_VM_C_LABEL (send_array ):
3480
- arg_num = 1 ;
3481
3475
ht = Z_ARRVAL_P (args );
3482
3476
zend_vm_stack_extend_call_frame (& EX (call ), 0 , zend_hash_num_elements (ht ) TSRMLS_CC );
3483
3477
@@ -3487,7 +3481,7 @@ ZEND_VM_C_LABEL(send_array):
3487
3481
3488
3482
/* check if any of arguments are going to be passed by reference */
3489
3483
for (i = 0 ; i < zend_hash_num_elements (ht ); i ++ ) {
3490
- if (ARG_SHOULD_BE_SENT_BY_REF (EX (call )-> func , arg_num + i )) {
3484
+ if (ARG_SHOULD_BE_SENT_BY_REF (EX (call )-> func , i )) {
3491
3485
separate = 1 ;
3492
3486
break ;
3493
3487
}
@@ -3498,7 +3492,8 @@ ZEND_VM_C_LABEL(send_array):
3498
3492
}
3499
3493
}
3500
3494
3501
- param = ZEND_CALL_ARG (EX (call ), arg_num );
3495
+ arg_num = 1 ;
3496
+ param = ZEND_CALL_ARG (EX (call ), 1 );
3502
3497
ZEND_HASH_FOREACH_VAL (ht , arg ) {
3503
3498
if (ARG_SHOULD_BE_SENT_BY_REF (EX (call )-> func , arg_num )) {
3504
3499
// TODO: Scalar values don't have reference counters anymore.
@@ -3577,7 +3572,7 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY)
3577
3572
zend_free_op free_op1 ;
3578
3573
3579
3574
arg = GET_OP1_ZVAL_PTR (BP_VAR_R );
3580
- param = ZEND_CALL_ARG (EX (call ), opline -> op2 . num );
3575
+ param = ZEND_CALL_VAR (EX (call ), opline -> result . var );
3581
3576
3582
3577
if (ARG_SHOULD_BE_SENT_BY_REF (EX (call )-> func , opline -> op2 .num )) {
3583
3578
// TODO: Scalar values don't have reference counters anymore.
@@ -3642,8 +3637,6 @@ ZEND_VM_HANDLER(120, ZEND_SEND_USER, VAR|CV, ANY)
3642
3637
ZVAL_COPY (param , arg );
3643
3638
}
3644
3639
3645
- ZEND_CALL_NUM_ARGS (EX (call )) = opline -> op2 .num ;
3646
-
3647
3640
FREE_OP1 ();
3648
3641
CHECK_EXCEPTION ();
3649
3642
ZEND_VM_NEXT_OPCODE ();
@@ -5670,11 +5663,86 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY)
5670
5663
}
5671
5664
}
5672
5665
5673
- if (EX (call )) {
5666
+ if (UNEXPECTED ( EX (call ) )) {
5674
5667
zend_execute_data * call = EX (call );
5668
+ zend_op * opline = EX (func )-> op_array .opcodes + op_num ;
5669
+ int level ;
5670
+ int do_exit ;
5671
+
5675
5672
do {
5676
5673
/* If the exception was thrown during a function call there might be
5677
5674
* arguments pushed to the stack that have to be dtor'ed. */
5675
+
5676
+ /* find the number of actually passed arguments */
5677
+ level = 0 ;
5678
+ do_exit = 0 ;
5679
+ do {
5680
+ switch (opline -> opcode ) {
5681
+ case ZEND_DO_FCALL :
5682
+ level ++ ;
5683
+ break ;
5684
+ case ZEND_INIT_FCALL :
5685
+ case ZEND_INIT_FCALL_BY_NAME :
5686
+ case ZEND_INIT_NS_FCALL_BY_NAME :
5687
+ case ZEND_INIT_USER_CALL :
5688
+ case ZEND_INIT_METHOD_CALL :
5689
+ case ZEND_INIT_STATIC_METHOD_CALL :
5690
+ case ZEND_NEW :
5691
+ if (level == 0 ) {
5692
+ ZEND_CALL_NUM_ARGS (call ) = 0 ;
5693
+ do_exit = 1 ;
5694
+ }
5695
+ level -- ;
5696
+ break ;
5697
+ case ZEND_SEND_VAL :
5698
+ case ZEND_SEND_VAL_EX :
5699
+ case ZEND_SEND_VAR :
5700
+ case ZEND_SEND_VAR_EX :
5701
+ case ZEND_SEND_REF :
5702
+ case ZEND_SEND_VAR_NO_REF :
5703
+ case ZEND_SEND_USER :
5704
+ if (level == 0 ) {
5705
+ ZEND_CALL_NUM_ARGS (call ) = opline -> op2 .num ;
5706
+ do_exit = 1 ;
5707
+ }
5708
+ break ;
5709
+ case ZEND_SEND_ARRAY :
5710
+ case ZEND_SEND_UNPACK :
5711
+ if (level == 0 ) {
5712
+ do_exit = 1 ;
5713
+ }
5714
+ break ;
5715
+ }
5716
+ if (!do_exit ) {
5717
+ opline -- ;
5718
+ }
5719
+ } while (!do_exit );
5720
+ if (call -> prev_execute_data ) {
5721
+ /* skip current call region */
5722
+ level = 0 ;
5723
+ do_exit = 0 ;
5724
+ do {
5725
+ switch (opline -> opcode ) {
5726
+ case ZEND_DO_FCALL :
5727
+ level ++ ;
5728
+ break ;
5729
+ case ZEND_INIT_FCALL :
5730
+ case ZEND_INIT_FCALL_BY_NAME :
5731
+ case ZEND_INIT_NS_FCALL_BY_NAME :
5732
+ case ZEND_INIT_USER_CALL :
5733
+ case ZEND_INIT_METHOD_CALL :
5734
+ case ZEND_INIT_STATIC_METHOD_CALL :
5735
+ case ZEND_NEW :
5736
+ if (level == 0 ) {
5737
+ do_exit = 1 ;
5738
+ }
5739
+ level -- ;
5740
+ break ;
5741
+ }
5742
+ opline -- ;
5743
+ } while (!do_exit );
5744
+ }
5745
+
5678
5746
zend_vm_stack_free_args (EX (call ) TSRMLS_CC );
5679
5747
5680
5748
if (Z_OBJ (call -> This )) {
0 commit comments