Skip to content

Commit 3ef3c3b

Browse files
committed
Convert constructor arguments in PDO Handler to HashTable*
1 parent a123ce9 commit 3ef3c3b

File tree

3 files changed

+26
-56
lines changed

3 files changed

+26
-56
lines changed

ext/pdo/pdo_dbh.c

Lines changed: 24 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -434,11 +434,9 @@ PHP_METHOD(PDO, __construct)
434434
}
435435
/* }}} */
436436

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) /* {{{ */
438438
{
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) {
442440
if (!dbstmt_ce->constructor) {
443441
zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
444442
return NULL;
@@ -455,7 +453,7 @@ static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry
455453
return object;
456454
} /* }}} */
457455

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) /* {{{ */
459457
{
460458
zval query_string;
461459
zend_string *key;
@@ -466,29 +464,7 @@ static void pdo_stmt_construct(zend_execute_data *execute_data, pdo_stmt_t *stmt
466464
zend_string_release_ex(key, 0);
467465

468466
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);
492468
}
493469
}
494470
/* }}} */
@@ -498,7 +474,8 @@ PHP_METHOD(PDO, prepare)
498474
{
499475
pdo_stmt_t *stmt;
500476
zend_string *statement;
501-
zval *options = NULL, *value, *item, ctor_args;
477+
zval *options = NULL, *value, *item;
478+
HashTable *ctor_args = NULL;
502479
zend_class_entry *dbstmt_ce, *pce;
503480
pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS);
504481
pdo_dbh_t *dbh = dbh_obj->inner;
@@ -548,16 +525,14 @@ PHP_METHOD(PDO, prepare)
548525
zend_zval_type_name(value));
549526
RETURN_THROWS();
550527
}
551-
ZVAL_COPY_VALUE(&ctor_args, item);
552-
} else {
553-
ZVAL_UNDEF(&ctor_args);
528+
ctor_args = Z_ARRVAL_P(item);
554529
}
555530
} else {
556531
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;
558533
}
559534

560-
if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, &ctor_args)) {
535+
if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args)) {
561536
RETURN_THROWS();
562537
}
563538
stmt = Z_PDO_STMT_P(return_value);
@@ -572,7 +547,7 @@ PHP_METHOD(PDO, prepare)
572547
ZVAL_UNDEF(&stmt->lazy_object_ref);
573548

574549
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);
576551
return;
577552
}
578553

@@ -833,17 +808,17 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /
833808
return false;
834809
}
835810
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;
839814
}
840815
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
841816
if (Z_TYPE_P(item) != IS_ARRAY) {
842817
zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
843818
zend_zval_type_name(value));
844819
return false;
845820
}
846-
ZVAL_COPY(&dbh->def_stmt_ctor_args, item);
821+
dbh->def_stmt_ctor_args = zend_array_dup(Z_ARRVAL_P(item));
847822
}
848823
return true;
849824
}
@@ -922,9 +897,8 @@ PHP_METHOD(PDO, getAttribute)
922897
case PDO_ATTR_STATEMENT_CLASS:
923898
array_init(return_value);
924899
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));
928902
}
929903
return;
930904
case PDO_ATTR_DEFAULT_FETCH_MODE:
@@ -1109,7 +1083,7 @@ PHP_METHOD(PDO, query)
11091083

11101084
PDO_DBH_CLEAR_ERR();
11111085

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)) {
11131087
RETURN_THROWS();
11141088
}
11151089
stmt = Z_PDO_STMT_P(return_value);
@@ -1138,7 +1112,7 @@ PHP_METHOD(PDO, query)
11381112
stmt->executed = 1;
11391113
}
11401114
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);
11421116
return;
11431117
}
11441118
}
@@ -1326,7 +1300,11 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
13261300
{
13271301
pdo_dbh_t *dbh = php_pdo_dbh_fetch_inner(object);
13281302
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+
}
13301308
if (dbh->methods && dbh->methods->get_gc) {
13311309
dbh->methods->get_gc(dbh, gc_buffer);
13321310
}
@@ -1388,9 +1366,7 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
13881366
pefree((char *)dbh->persistent_id, dbh->is_persistent);
13891367
}
13901368

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 */
13941370

13951371
for (i = 0; i < PDO_DBH_DRIVER_METHOD_KIND__MAX; i++) {
13961372
if (dbh->cls_methods[i]) {

ext/pdo/php_pdo_driver.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -487,7 +487,7 @@ struct _pdo_dbh_t {
487487

488488
zend_class_entry *def_stmt_ce;
489489

490-
zval def_stmt_ctor_args;
490+
HashTable *def_stmt_ctor_args;
491491

492492
/* when calling PDO::query(), we need to keep the error
493493
* context from the statement around until we next clear it.

run-tests.php

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -857,13 +857,7 @@ function write_information(): void
857857
$php_cgi_info = '';
858858
}
859859

860-
if ($phpdbg) {
861-
$phpdbg_info = shell_exec("$phpdbg $pass_options $info_params $no_file_cache -qrr \"$info_file\"");
862-
$php_info_sep = "\n---------------------------------------------------------------------";
863-
$phpdbg_info = "$php_info_sep\nPHP : $phpdbg $phpdbg_info$php_info_sep";
864-
} else {
865-
$phpdbg_info = '';
866-
}
860+
$phpdbg_info = '';
867861

868862
if (function_exists('opcache_invalidate')) {
869863
opcache_invalidate($info_file, true);

0 commit comments

Comments
 (0)