@@ -434,11 +434,9 @@ PHP_METHOD(PDO, __construct)
434
434
}
435
435
/* }}} */
436
436
437
- static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , zval * ctor_args ) /* {{{ */
437
+ static zval * pdo_stmt_instantiate (pdo_dbh_t * dbh , zval * object , zend_class_entry * dbstmt_ce , const HashTable * ctor_args ) /* {{{ */
438
438
{
439
- if (!Z_ISUNDEF_P (ctor_args )) {
440
- /* This implies an error within PDO if this does not hold */
441
- ZEND_ASSERT (Z_TYPE_P (ctor_args ) == IS_ARRAY );
439
+ if (ctor_args ) {
442
440
if (!dbstmt_ce -> constructor ) {
443
441
zend_throw_error (NULL , "User-supplied statement does not accept constructor arguments" );
444
442
return NULL ;
@@ -455,7 +453,7 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry
455
453
return object ;
456
454
} /* }}} */
457
455
458
- static void pdo_stmt_construct (zend_execute_data * execute_data , pdo_stmt_t * stmt , zval * object , zend_class_entry * dbstmt_ce , zval * ctor_args ) /* {{{ */
456
+ static void pdo_stmt_construct (zend_execute_data * execute_data , pdo_stmt_t * stmt , zval * object , zend_class_entry * dbstmt_ce , /* const */ HashTable * ctor_args ) /* {{{ */
459
457
{
460
458
zval query_string ;
461
459
zend_string * key ;
@@ -476,9 +474,7 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt
476
474
fci .retval = & retval ;
477
475
fci .param_count = 0 ;
478
476
fci .params = NULL ;
479
- fci .named_params = NULL ;
480
-
481
- zend_fcall_info_args (& fci , ctor_args );
477
+ fci .named_params = ctor_args ;
482
478
483
479
fcc .function_handler = dbstmt_ce -> constructor ;
484
480
fcc .called_scope = Z_OBJCE_P (object );
@@ -487,8 +483,6 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt
487
483
if (zend_call_function (& fci , & fcc ) != FAILURE ) {
488
484
zval_ptr_dtor (& retval );
489
485
}
490
-
491
- zend_fcall_info_args_clear (& fci , 1 );
492
486
}
493
487
}
494
488
/* }}} */
@@ -498,7 +492,8 @@ PHP_METHOD(PDO, prepare)
498
492
{
499
493
pdo_stmt_t * stmt ;
500
494
zend_string * statement ;
501
- zval * options = NULL , * value , * item , ctor_args ;
495
+ zval * options = NULL , * value , * item ;
496
+ HashTable * ctor_args = NULL ;
502
497
zend_class_entry * dbstmt_ce , * pce ;
503
498
pdo_dbh_object_t * dbh_obj = Z_PDO_OBJECT_P (ZEND_THIS );
504
499
pdo_dbh_t * dbh = dbh_obj -> inner ;
@@ -548,16 +543,14 @@ PHP_METHOD(PDO, prepare)
548
543
zend_zval_type_name (value ));
549
544
RETURN_THROWS ();
550
545
}
551
- ZVAL_COPY_VALUE (& ctor_args , item );
552
- } else {
553
- ZVAL_UNDEF (& ctor_args );
546
+ ctor_args = Z_ARRVAL_P (item );
554
547
}
555
548
} else {
556
549
dbstmt_ce = dbh -> def_stmt_ce ;
557
- ZVAL_COPY_VALUE ( & ctor_args , & dbh -> def_stmt_ctor_args ) ;
550
+ ctor_args = dbh -> def_stmt_ctor_args ;
558
551
}
559
552
560
- if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , & ctor_args )) {
553
+ if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , ctor_args )) {
561
554
RETURN_THROWS ();
562
555
}
563
556
stmt = Z_PDO_STMT_P (return_value );
@@ -572,7 +565,7 @@ PHP_METHOD(PDO, prepare)
572
565
ZVAL_UNDEF (& stmt -> lazy_object_ref );
573
566
574
567
if (dbh -> methods -> preparer (dbh , statement , stmt , options )) {
575
- pdo_stmt_construct (execute_data , stmt , return_value , dbstmt_ce , & ctor_args );
568
+ pdo_stmt_construct (execute_data , stmt , return_value , dbstmt_ce , ctor_args );
576
569
return ;
577
570
}
578
571
@@ -833,17 +826,17 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /
833
826
return false;
834
827
}
835
828
dbh -> def_stmt_ce = pce ;
836
- if (! Z_ISUNDEF ( dbh -> def_stmt_ctor_args ) ) {
837
- zval_ptr_dtor ( & dbh -> def_stmt_ctor_args );
838
- ZVAL_UNDEF ( & dbh -> def_stmt_ctor_args ) ;
829
+ if (dbh -> def_stmt_ctor_args ) {
830
+ zend_hash_destroy ( dbh -> def_stmt_ctor_args );
831
+ dbh -> def_stmt_ctor_args = NULL ;
839
832
}
840
833
if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 1 )) != NULL ) {
841
834
if (Z_TYPE_P (item ) != IS_ARRAY ) {
842
835
zend_type_error ("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given" ,
843
836
zend_zval_type_name (value ));
844
837
return false;
845
838
}
846
- ZVAL_COPY ( & dbh -> def_stmt_ctor_args , item );
839
+ dbh -> def_stmt_ctor_args = zend_array_dup ( Z_ARRVAL_P ( item ) );
847
840
}
848
841
return true;
849
842
}
@@ -922,9 +915,9 @@ PHP_METHOD(PDO, getAttribute)
922
915
case PDO_ATTR_STATEMENT_CLASS :
923
916
array_init (return_value );
924
917
add_next_index_str (return_value , zend_string_copy (dbh -> def_stmt_ce -> name ));
925
- if (! Z_ISUNDEF ( dbh -> def_stmt_ctor_args ) ) {
926
- Z_TRY_ADDREF (dbh -> def_stmt_ctor_args );
927
- add_next_index_zval (return_value , & dbh -> def_stmt_ctor_args );
918
+ if (dbh -> def_stmt_ctor_args ) {
919
+ // Z_TRY_ADDREF(dbh->def_stmt_ctor_args);
920
+ add_next_index_array (return_value , dbh -> def_stmt_ctor_args );
928
921
}
929
922
return ;
930
923
case PDO_ATTR_DEFAULT_FETCH_MODE :
@@ -1109,7 +1102,7 @@ PHP_METHOD(PDO, query)
1109
1102
1110
1103
PDO_DBH_CLEAR_ERR ();
1111
1104
1112
- if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args )) {
1105
+ if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args )) {
1113
1106
RETURN_THROWS ();
1114
1107
}
1115
1108
stmt = Z_PDO_STMT_P (return_value );
@@ -1138,7 +1131,7 @@ PHP_METHOD(PDO, query)
1138
1131
stmt -> executed = 1 ;
1139
1132
}
1140
1133
if (ret ) {
1141
- pdo_stmt_construct (execute_data , stmt , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args );
1134
+ pdo_stmt_construct (execute_data , stmt , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args );
1142
1135
return ;
1143
1136
}
1144
1137
}
@@ -1326,7 +1319,11 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
1326
1319
{
1327
1320
pdo_dbh_t * dbh = php_pdo_dbh_fetch_inner (object );
1328
1321
zend_get_gc_buffer * gc_buffer = zend_get_gc_buffer_create ();
1329
- zend_get_gc_buffer_add_zval (gc_buffer , & dbh -> def_stmt_ctor_args );
1322
+ if (dbh -> def_stmt_ctor_args ) {
1323
+ zval tmp = {0 };
1324
+ ZVAL_ARR (& tmp , dbh -> def_stmt_ctor_args );
1325
+ zend_get_gc_buffer_add_zval (gc_buffer , & tmp );
1326
+ }
1330
1327
if (dbh -> methods && dbh -> methods -> get_gc ) {
1331
1328
dbh -> methods -> get_gc (dbh , gc_buffer );
1332
1329
}
@@ -1388,9 +1385,7 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
1388
1385
pefree ((char * )dbh -> persistent_id , dbh -> is_persistent );
1389
1386
}
1390
1387
1391
- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
1392
- zval_ptr_dtor (& dbh -> def_stmt_ctor_args );
1393
- }
1388
+ /* Freeing of constructor arguments is handles via GC */
1394
1389
1395
1390
for (i = 0 ; i < PDO_DBH_DRIVER_METHOD_KIND__MAX ; i ++ ) {
1396
1391
if (dbh -> cls_methods [i ]) {
0 commit comments