@@ -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 ;
@@ -466,29 +464,7 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt
466
464
zend_string_release_ex (key , 0 );
467
465
468
466
if (dbstmt_ce -> constructor ) {
469
- zend_fcall_info fci ;
470
- zend_fcall_info_cache fcc ;
471
- zval retval ;
472
-
473
- fci .size = sizeof (zend_fcall_info );
474
- ZVAL_UNDEF (& fci .function_name );
475
- fci .object = Z_OBJ_P (object );
476
- fci .retval = & retval ;
477
- fci .param_count = 0 ;
478
- fci .params = NULL ;
479
- fci .named_params = NULL ;
480
-
481
- zend_fcall_info_args (& fci , ctor_args );
482
-
483
- fcc .function_handler = dbstmt_ce -> constructor ;
484
- fcc .called_scope = Z_OBJCE_P (object );
485
- fcc .object = Z_OBJ_P (object );
486
-
487
- if (zend_call_function (& fci , & fcc ) != FAILURE ) {
488
- zval_ptr_dtor (& retval );
489
- }
490
-
491
- zend_fcall_info_args_clear (& fci , 1 );
467
+ zend_call_known_function (dbstmt_ce -> constructor , Z_OBJ_P (object ), Z_OBJCE_P (object ), NULL , 0 , NULL , ctor_args );
492
468
}
493
469
}
494
470
/* }}} */
@@ -498,7 +474,8 @@ PHP_METHOD(PDO, prepare)
498
474
{
499
475
pdo_stmt_t * stmt ;
500
476
zend_string * statement ;
501
- zval * options = NULL , * value , * item , ctor_args ;
477
+ zval * options = NULL , * value , * item ;
478
+ HashTable * ctor_args = NULL ;
502
479
zend_class_entry * dbstmt_ce , * pce ;
503
480
pdo_dbh_object_t * dbh_obj = Z_PDO_OBJECT_P (ZEND_THIS );
504
481
pdo_dbh_t * dbh = dbh_obj -> inner ;
@@ -548,16 +525,14 @@ PHP_METHOD(PDO, prepare)
548
525
zend_zval_type_name (value ));
549
526
RETURN_THROWS ();
550
527
}
551
- ZVAL_COPY_VALUE (& ctor_args , item );
552
- } else {
553
- ZVAL_UNDEF (& ctor_args );
528
+ ctor_args = Z_ARRVAL_P (item );
554
529
}
555
530
} else {
556
531
dbstmt_ce = dbh -> def_stmt_ce ;
557
- ZVAL_COPY_VALUE ( & ctor_args , & dbh -> def_stmt_ctor_args ) ;
532
+ ctor_args = dbh -> def_stmt_ctor_args ;
558
533
}
559
534
560
- if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , & ctor_args )) {
535
+ if (!pdo_stmt_instantiate (dbh , return_value , dbstmt_ce , ctor_args )) {
561
536
RETURN_THROWS ();
562
537
}
563
538
stmt = Z_PDO_STMT_P (return_value );
@@ -572,7 +547,7 @@ PHP_METHOD(PDO, prepare)
572
547
ZVAL_UNDEF (& stmt -> lazy_object_ref );
573
548
574
549
if (dbh -> methods -> preparer (dbh , statement , stmt , options )) {
575
- pdo_stmt_construct (execute_data , stmt , return_value , dbstmt_ce , & ctor_args );
550
+ pdo_stmt_construct (execute_data , stmt , return_value , dbstmt_ce , ctor_args );
576
551
return ;
577
552
}
578
553
@@ -833,17 +808,17 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /
833
808
return false;
834
809
}
835
810
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 ) ;
811
+ if (dbh -> def_stmt_ctor_args ) {
812
+ zend_hash_destroy ( dbh -> def_stmt_ctor_args );
813
+ dbh -> def_stmt_ctor_args = NULL ;
839
814
}
840
815
if ((item = zend_hash_index_find (Z_ARRVAL_P (value ), 1 )) != NULL ) {
841
816
if (Z_TYPE_P (item ) != IS_ARRAY ) {
842
817
zend_type_error ("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given" ,
843
818
zend_zval_type_name (value ));
844
819
return false;
845
820
}
846
- ZVAL_COPY ( & dbh -> def_stmt_ctor_args , item );
821
+ dbh -> def_stmt_ctor_args = zend_array_dup ( Z_ARRVAL_P ( item ) );
847
822
}
848
823
return true;
849
824
}
@@ -922,9 +897,8 @@ PHP_METHOD(PDO, getAttribute)
922
897
case PDO_ATTR_STATEMENT_CLASS :
923
898
array_init (return_value );
924
899
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 );
900
+ if (dbh -> def_stmt_ctor_args ) {
901
+ add_next_index_array (return_value , zend_array_dup (dbh -> def_stmt_ctor_args ));
928
902
}
929
903
return ;
930
904
case PDO_ATTR_DEFAULT_FETCH_MODE :
@@ -1109,7 +1083,7 @@ PHP_METHOD(PDO, query)
1109
1083
1110
1084
PDO_DBH_CLEAR_ERR ();
1111
1085
1112
- if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args )) {
1086
+ if (!pdo_stmt_instantiate (dbh , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args )) {
1113
1087
RETURN_THROWS ();
1114
1088
}
1115
1089
stmt = Z_PDO_STMT_P (return_value );
@@ -1138,7 +1112,7 @@ PHP_METHOD(PDO, query)
1138
1112
stmt -> executed = 1 ;
1139
1113
}
1140
1114
if (ret ) {
1141
- pdo_stmt_construct (execute_data , stmt , return_value , dbh -> def_stmt_ce , & dbh -> def_stmt_ctor_args );
1115
+ pdo_stmt_construct (execute_data , stmt , return_value , dbh -> def_stmt_ce , dbh -> def_stmt_ctor_args );
1142
1116
return ;
1143
1117
}
1144
1118
}
@@ -1326,7 +1300,11 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
1326
1300
{
1327
1301
pdo_dbh_t * dbh = php_pdo_dbh_fetch_inner (object );
1328
1302
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 );
1303
+ if (dbh -> def_stmt_ctor_args ) {
1304
+ zval tmp = {0 };
1305
+ ZVAL_ARR (& tmp , dbh -> def_stmt_ctor_args );
1306
+ zend_get_gc_buffer_add_zval (gc_buffer , & tmp );
1307
+ }
1330
1308
if (dbh -> methods && dbh -> methods -> get_gc ) {
1331
1309
dbh -> methods -> get_gc (dbh , gc_buffer );
1332
1310
}
@@ -1388,9 +1366,7 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
1388
1366
pefree ((char * )dbh -> persistent_id , dbh -> is_persistent );
1389
1367
}
1390
1368
1391
- if (!Z_ISUNDEF (dbh -> def_stmt_ctor_args )) {
1392
- zval_ptr_dtor (& dbh -> def_stmt_ctor_args );
1393
- }
1369
+ /* Freeing of constructor arguments is handles via GC */
1394
1370
1395
1371
for (i = 0 ; i < PDO_DBH_DRIVER_METHOD_KIND__MAX ; i ++ ) {
1396
1372
if (dbh -> cls_methods [i ]) {
0 commit comments