@@ -1218,14 +1218,19 @@ binary_assign_op_addr: {
1218
1218
AI_USE_PTR (Ts [opline -> result .u .var ].var );
1219
1219
break ;
1220
1220
case ZEND_ASSIGN : {
1221
- zval * value = get_zval_ptr (& opline -> op2 , Ts , & EG (free_op2 ), BP_VAR_R );
1221
+ zval * value ;
1222
+ SUSPEND_GARBAGE ();
1223
+ value = get_zval_ptr (& opline -> op2 , Ts , & EG (free_op2 ), BP_VAR_R );
1224
+ RESUME_GARBAGE ();
1222
1225
1223
1226
zend_assign_to_variable (& opline -> result , & opline -> op1 , & opline -> op2 , value , (EG (free_op2 )?IS_TMP_VAR :opline -> op2 .op_type ), Ts ELS_CC );
1224
1227
/* zend_assign_to_variable() always takes care of op2, never free it! */
1225
1228
}
1226
1229
break ;
1227
1230
case ZEND_ASSIGN_REF :
1231
+ SUSPEND_GARBAGE ();
1228
1232
zend_assign_to_variable_reference (& opline -> result , get_zval_ptr_ptr (& opline -> op1 , Ts , BP_VAR_W ), get_zval_ptr_ptr (& opline -> op2 , Ts , BP_VAR_W ), Ts ELS_CC );
1233
+ RESUME_GARBAGE ();
1229
1234
break ;
1230
1235
case ZEND_JMP :
1231
1236
#if DEBUG_ZEND >=2
@@ -1467,13 +1472,18 @@ binary_assign_op_addr: {
1467
1472
}
1468
1473
do_fcall_common :
1469
1474
{
1470
- zval * original_return_value ;
1475
+ zval * * original_return_value ;
1471
1476
int return_value_not_used = (opline -> result .u .EA .type & EXT_TYPE_UNUSED );
1472
1477
1473
1478
zend_ptr_stack_push (& EG (argument_stack ), (void * ) opline -> extended_value );
1474
- var_uninit (& Ts [opline -> result .u .var ].tmp_var );
1479
+ Ts [opline -> result .u .var ].var .ptr = (zval * )emalloc (sizeof (zval ));
1480
+ Ts [opline -> result .u .var ].var .ptr_ptr = & Ts [opline -> result .u .var ].var .ptr ;
1481
+ var_uninit (Ts [opline -> result .u .var ].var .ptr );
1482
+ Ts [opline -> result .u .var ].var .ptr -> is_ref = 0 ;
1483
+ Ts [opline -> result .u .var ].var .ptr -> refcount = 1 ;
1484
+
1475
1485
if (function_state .function -> type == ZEND_INTERNAL_FUNCTION ) {
1476
- ((zend_internal_function * ) function_state .function )-> handler (opline -> extended_value , & Ts [opline -> result .u .var ].tmp_var , & EG (regular_list ), & EG (persistent_list ), object .ptr , !return_value_not_used );
1486
+ ((zend_internal_function * ) function_state .function )-> handler (opline -> extended_value , Ts [opline -> result .u .var ].var . ptr , & EG (regular_list ), & EG (persistent_list ), object .ptr , !return_value_not_used );
1477
1487
if (object .ptr ) {
1478
1488
object .ptr -> refcount -- ;
1479
1489
}
@@ -1502,13 +1512,13 @@ binary_assign_op_addr: {
1502
1512
* this_ptr = object .ptr ;
1503
1513
object .ptr = NULL ;
1504
1514
}
1505
- original_return_value = EG (return_value );
1506
- EG (return_value ) = & Ts [opline -> result .u .var ].tmp_var ;
1515
+ original_return_value = EG (return_value_ptr_ptr );
1516
+ EG (return_value_ptr_ptr ) = Ts [opline -> result .u .var ].var . ptr_ptr ;
1507
1517
EG (active_op_array ) = (zend_op_array * ) function_state .function ;
1508
1518
zend_execute (EG (active_op_array ) ELS_CC );
1509
1519
EG (opline_ptr ) = & opline ;
1510
1520
EG (active_op_array ) = op_array ;
1511
- EG (return_value )= original_return_value ;
1521
+ EG (return_value_ptr_ptr )= original_return_value ;
1512
1522
if (EG (symtable_cache_ptr )>=EG (symtable_cache_limit )) {
1513
1523
zend_hash_destroy (function_state .function_symbol_table );
1514
1524
efree (function_state .function_symbol_table );
@@ -1518,11 +1528,11 @@ binary_assign_op_addr: {
1518
1528
}
1519
1529
EG (active_symbol_table ) = calling_symbol_table ;
1520
1530
} else { /* ZEND_OVERLOADED_FUNCTION */
1521
- call_overloaded_function (opline -> extended_value , & Ts [opline -> result .u .var ].tmp_var , & EG (regular_list ), & EG (persistent_list ) ELS_CC );
1531
+ call_overloaded_function (opline -> extended_value , Ts [opline -> result .u .var ].var . ptr , & EG (regular_list ), & EG (persistent_list ) ELS_CC );
1522
1532
efree (fbc );
1523
1533
}
1524
1534
if (return_value_not_used ) {
1525
- zendi_zval_dtor ( Ts [opline -> result .u .var ].tmp_var );
1535
+ zval_ptr_dtor ( & Ts [opline -> result .u .var ].var . ptr );
1526
1536
}
1527
1537
object .ptr = zend_ptr_stack_pop (& EG (arg_types_stack ));
1528
1538
if (opline -> opcode == ZEND_DO_FCALL_BY_NAME ) {
@@ -1536,9 +1546,15 @@ binary_assign_op_addr: {
1536
1546
case ZEND_RETURN : {
1537
1547
zval * retval = get_zval_ptr (& opline -> op1 , Ts , & EG (free_op1 ), BP_VAR_R );
1538
1548
1539
- * EG (return_value ) = * retval ;
1540
- if (!EG (free_op1 )) {
1541
- zendi_zval_copy_ctor (* EG (return_value ));
1549
+ if (!EG (free_op1 )) { /* Not a temp var */
1550
+ efree (* EG (return_value_ptr_ptr ));
1551
+ /* Still need to check for reference */
1552
+ * EG (return_value_ptr_ptr ) = retval ;
1553
+ retval -> refcount ++ ;
1554
+ } else {
1555
+ * * EG (return_value_ptr_ptr ) = * retval ;
1556
+ (* EG (return_value_ptr_ptr ))-> refcount = 1 ;
1557
+ (* EG (return_value_ptr_ptr ))-> is_ref = 0 ;
1542
1558
}
1543
1559
#if SUPPORT_INTERACTIVE
1544
1560
op_array -> last_executed_op_number = opline - op_array -> opcodes ;
@@ -1566,7 +1582,10 @@ binary_assign_op_addr: {
1566
1582
goto send_by_ref ;
1567
1583
}
1568
1584
{
1569
- zval * varptr = get_zval_ptr (& opline -> op1 , Ts , & EG (free_op1 ), BP_VAR_R );
1585
+ zval * varptr ;
1586
+ SUSPEND_GARBAGE ();
1587
+ varptr = get_zval_ptr (& opline -> op1 , Ts , & EG (free_op1 ), BP_VAR_R );
1588
+ RESUME_GARBAGE ();
1570
1589
1571
1590
if (varptr == & EG (uninitialized_zval )) {
1572
1591
varptr = (zval * ) emalloc (sizeof (zval ));
@@ -1589,8 +1608,13 @@ binary_assign_op_addr: {
1589
1608
break ;
1590
1609
send_by_ref :
1591
1610
case ZEND_SEND_REF : {
1592
- zval * * varptr_ptr = get_zval_ptr_ptr (& opline -> op1 , Ts , BP_VAR_W );
1593
- zval * varptr = * varptr_ptr ;
1611
+ zval * * varptr_ptr ;
1612
+ zval * varptr ;
1613
+ SUSPEND_GARBAGE ();
1614
+ varptr_ptr = get_zval_ptr_ptr (& opline -> op1 , Ts , BP_VAR_W );
1615
+ RESUME_GARBAGE ();
1616
+
1617
+ varptr = * varptr_ptr ;
1594
1618
1595
1619
if (!PZVAL_IS_REF (varptr )) {
1596
1620
/* code to break away this variable */
0 commit comments