@@ -179,6 +179,8 @@ void zend_init_compiler_context(TSRMLS_D) /* {{{ */
179
179
CG (context ).literals_size = 0 ;
180
180
CG (context ).current_brk_cont = -1 ;
181
181
CG (context ).backpatch_count = 0 ;
182
+ CG (context ).nested_calls = 0 ;
183
+ CG (context ).used_stack = 0 ;
182
184
CG (context ).labels = NULL ;
183
185
}
184
186
/* }}} */
@@ -1950,6 +1952,9 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace
1950
1952
function_name -> u .constant .value .str .val = lcname ;
1951
1953
1952
1954
zend_stack_push (& CG (function_call_stack ), (void * ) & function , sizeof (zend_function * ));
1955
+ if (CG (context ).nested_calls + 1 > CG (active_op_array )-> nested_calls ) {
1956
+ CG (active_op_array )-> nested_calls = CG (context ).nested_calls + 1 ;
1957
+ }
1953
1958
zend_do_extended_fcall_begin (TSRMLS_C );
1954
1959
return 0 ;
1955
1960
}
@@ -1988,11 +1993,13 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
1988
1993
GET_POLYMORPHIC_CACHE_SLOT (last_op -> op2 .constant );
1989
1994
}
1990
1995
last_op -> opcode = ZEND_INIT_METHOD_CALL ;
1991
- SET_UNUSED (last_op -> result );
1996
+ last_op -> result_type = IS_UNUSED ;
1997
+ last_op -> result .num = CG (context ).nested_calls ;
1992
1998
Z_LVAL (left_bracket -> u .constant ) = ZEND_INIT_FCALL_BY_NAME ;
1993
1999
} else {
1994
2000
zend_op * opline = get_next_op (CG (active_op_array ) TSRMLS_CC );
1995
2001
opline -> opcode = ZEND_INIT_FCALL_BY_NAME ;
2002
+ opline -> result .num = CG (context ).nested_calls ;
1996
2003
SET_UNUSED (opline -> op1 );
1997
2004
if (left_bracket -> op_type == IS_CONST ) {
1998
2005
opline -> op2_type = IS_CONST ;
@@ -2004,6 +2011,9 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */
2004
2011
}
2005
2012
2006
2013
zend_stack_push (& CG (function_call_stack ), (void * ) & ptr , sizeof (zend_function * ));
2014
+ if (++ CG (context ).nested_calls > CG (active_op_array )-> nested_calls ) {
2015
+ CG (active_op_array )-> nested_calls = CG (context ).nested_calls ;
2016
+ }
2007
2017
zend_do_extended_fcall_begin (TSRMLS_C );
2008
2018
}
2009
2019
/* }}} */
@@ -2031,12 +2041,14 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML
2031
2041
/* In run-time PHP will check for function with full name and
2032
2042
internal function with short name */
2033
2043
opline -> opcode = ZEND_INIT_NS_FCALL_BY_NAME ;
2044
+ opline -> result .num = CG (context ).nested_calls ;
2034
2045
SET_UNUSED (opline -> op1 );
2035
2046
opline -> op2_type = IS_CONST ;
2036
2047
opline -> op2 .constant = zend_add_ns_func_name_literal (CG (active_op_array ), & function_name -> u .constant TSRMLS_CC );
2037
2048
GET_CACHE_SLOT (opline -> op2 .constant );
2038
2049
} else {
2039
2050
opline -> opcode = ZEND_INIT_FCALL_BY_NAME ;
2051
+ opline -> result .num = CG (context ).nested_calls ;
2040
2052
SET_UNUSED (opline -> op1 );
2041
2053
if (function_name -> op_type == IS_CONST ) {
2042
2054
opline -> op2_type = IS_CONST ;
@@ -2048,6 +2060,9 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML
2048
2060
}
2049
2061
2050
2062
zend_stack_push (& CG (function_call_stack ), (void * ) & ptr , sizeof (zend_function * ));
2063
+ if (++ CG (context ).nested_calls > CG (active_op_array )-> nested_calls ) {
2064
+ CG (active_op_array )-> nested_calls = CG (context ).nested_calls ;
2065
+ }
2051
2066
zend_do_extended_fcall_begin (TSRMLS_C );
2052
2067
}
2053
2068
/* }}} */
@@ -2395,6 +2410,7 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
2395
2410
opline -> extended_value = class_node .EA ;
2396
2411
}
2397
2412
opline -> opcode = ZEND_INIT_STATIC_METHOD_CALL ;
2413
+ opline -> result .num = CG (context ).nested_calls ;
2398
2414
if (class_node .op_type == IS_CONST ) {
2399
2415
opline -> op1_type = IS_CONST ;
2400
2416
opline -> op1 .constant =
@@ -2416,6 +2432,9 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na
2416
2432
}
2417
2433
2418
2434
zend_stack_push (& CG (function_call_stack ), (void * ) & ptr , sizeof (zend_function * ));
2435
+ if (++ CG (context ).nested_calls > CG (active_op_array )-> nested_calls ) {
2436
+ CG (active_op_array )-> nested_calls = CG (context ).nested_calls ;
2437
+ }
2419
2438
zend_do_extended_fcall_begin (TSRMLS_C );
2420
2439
return 1 ; /* Dynamic */
2421
2440
}
@@ -2436,21 +2455,29 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode
2436
2455
if (!is_method && !is_dynamic_fcall && function_name -> op_type == IS_CONST ) {
2437
2456
opline -> opcode = ZEND_DO_FCALL ;
2438
2457
SET_NODE (opline -> op1 , function_name );
2458
+ SET_UNUSED (opline -> op2 );
2459
+ opline -> op2 .num = CG (context ).nested_calls ;
2439
2460
CALCULATE_LITERAL_HASH (opline -> op1 .constant );
2440
2461
GET_CACHE_SLOT (opline -> op1 .constant );
2441
2462
} else {
2442
2463
opline -> opcode = ZEND_DO_FCALL_BY_NAME ;
2443
2464
SET_UNUSED (opline -> op1 );
2465
+ SET_UNUSED (opline -> op2 );
2466
+ opline -> op2 .num = -- CG (context ).nested_calls ;
2444
2467
}
2445
2468
}
2446
2469
2447
2470
opline -> result .var = get_temporary_variable (CG (active_op_array ));
2448
2471
opline -> result_type = IS_VAR ;
2449
- GET_NODE (result , opline -> result ) ;
2450
- SET_UNUSED (opline -> op2 );
2472
+ GET_NODE (result , opline -> result );
2451
2473
2452
2474
zend_stack_del_top (& CG (function_call_stack ));
2453
2475
opline -> extended_value = Z_LVAL (argument_list -> u .constant );
2476
+
2477
+ if (CG (context ).used_stack + 1 > CG (active_op_array )-> used_stack ) {
2478
+ CG (active_op_array )-> used_stack = CG (context ).used_stack + 1 ;
2479
+ }
2480
+ CG (context ).used_stack -= Z_LVAL (argument_list -> u .constant );
2454
2481
}
2455
2482
/* }}} */
2456
2483
@@ -2558,6 +2585,10 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{
2558
2585
SET_NODE (opline -> op1 , param );
2559
2586
opline -> op2 .opline_num = offset ;
2560
2587
SET_UNUSED (opline -> op2 );
2588
+
2589
+ if (++ CG (context ).used_stack > CG (active_op_array )-> used_stack ) {
2590
+ CG (active_op_array )-> used_stack = CG (context ).used_stack ;
2591
+ }
2561
2592
}
2562
2593
/* }}} */
2563
2594
@@ -5547,12 +5578,16 @@ void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /*
5547
5578
new_token -> u .op .opline_num = get_next_op_number (CG (active_op_array ));
5548
5579
opline = get_next_op (CG (active_op_array ) TSRMLS_CC );
5549
5580
opline -> opcode = ZEND_NEW ;
5581
+ opline -> extended_value = CG (context ).nested_calls ;
5550
5582
opline -> result_type = IS_VAR ;
5551
5583
opline -> result .var = get_temporary_variable (CG (active_op_array ));
5552
5584
SET_NODE (opline -> op1 , class_type );
5553
5585
SET_UNUSED (opline -> op2 );
5554
5586
5555
5587
zend_stack_push (& CG (function_call_stack ), (void * ) & ptr , sizeof (unsigned char * ));
5588
+ if (++ CG (context ).nested_calls > CG (active_op_array )-> nested_calls ) {
5589
+ CG (active_op_array )-> nested_calls = CG (context ).nested_calls ;
5590
+ }
5556
5591
}
5557
5592
/* }}} */
5558
5593
@@ -5765,6 +5800,13 @@ void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) /* {{{ */
5765
5800
opline -> extended_value = 1 ;
5766
5801
SET_UNUSED (opline -> op2 );
5767
5802
GET_NODE (result , opline -> result );
5803
+
5804
+ if (CG (context ).nested_calls + 1 > CG (active_op_array )-> nested_calls ) {
5805
+ CG (active_op_array )-> nested_calls = CG (context ).nested_calls + 1 ;
5806
+ }
5807
+ if (CG (context ).used_stack + 2 > CG (active_op_array )-> used_stack ) {
5808
+ CG (active_op_array )-> used_stack = CG (context ).used_stack + 2 ;
5809
+ }
5768
5810
}
5769
5811
/* }}} */
5770
5812
0 commit comments