Skip to content

Commit 667fc96

Browse files
committed
ext/pdo: Convert def_stmt_ctor_args field from zval to Hashtable pointer
1 parent b6c1c60 commit 667fc96

File tree

2 files changed

+31
-35
lines changed

2 files changed

+31
-35
lines changed

ext/pdo/pdo_dbh.c

Lines changed: 30 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -540,15 +540,12 @@ PHP_METHOD(PDO, connect)
540540
}
541541
/* }}} */
542542

543-
static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, zval *ctor_args) /* {{{ */
543+
static zval *pdo_stmt_instantiate(pdo_dbh_t *dbh, zval *object, zend_class_entry *dbstmt_ce, const HashTable *ctor_args) /* {{{ */
544544
{
545-
if (!Z_ISUNDEF_P(ctor_args)) {
545+
if (ctor_args && dbstmt_ce->constructor == NULL) {
546546
/* This implies an error within PDO if this does not hold */
547-
ZEND_ASSERT(Z_TYPE_P(ctor_args) == IS_ARRAY);
548-
if (!dbstmt_ce->constructor) {
549-
zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
550-
return NULL;
551-
}
547+
zend_throw_error(NULL, "User-supplied statement does not accept constructor arguments");
548+
return NULL;
552549
}
553550

554551
if (UNEXPECTED(object_init_ex(object, dbstmt_ce) != SUCCESS)) {
@@ -581,10 +578,11 @@ PHP_METHOD(PDO, prepare)
581578
{
582579
pdo_stmt_t *stmt;
583580
zend_string *statement;
584-
zval *options = NULL, *value, *item, ctor_args;
581+
zval *options = NULL, *value, *item;
585582
zend_class_entry *dbstmt_ce, *pce;
586583
pdo_dbh_object_t *dbh_obj = Z_PDO_OBJECT_P(ZEND_THIS);
587584
pdo_dbh_t *dbh = dbh_obj->inner;
585+
HashTable *ctor_args = NULL;
588586

589587
ZEND_PARSE_PARAMETERS_START(1, 2)
590588
Z_PARAM_STR(statement)
@@ -631,16 +629,14 @@ PHP_METHOD(PDO, prepare)
631629
zend_zval_value_name(value));
632630
RETURN_THROWS();
633631
}
634-
ZVAL_COPY_VALUE(&ctor_args, item);
635-
} else {
636-
ZVAL_UNDEF(&ctor_args);
632+
ctor_args = Z_ARRVAL_P(item);
637633
}
638634
} else {
639635
dbstmt_ce = dbh->def_stmt_ce;
640-
ZVAL_COPY_VALUE(&ctor_args, &dbh->def_stmt_ctor_args);
636+
ctor_args = dbh->def_stmt_ctor_args;
641637
}
642638

643-
if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, &ctor_args)) {
639+
if (!pdo_stmt_instantiate(dbh, return_value, dbstmt_ce, ctor_args)) {
644640
RETURN_THROWS();
645641
}
646642
stmt = Z_PDO_STMT_P(return_value);
@@ -655,11 +651,7 @@ PHP_METHOD(PDO, prepare)
655651
ZVAL_UNDEF(&stmt->lazy_object_ref);
656652

657653
if (dbh->methods->preparer(dbh, statement, stmt, options)) {
658-
if (Z_TYPE(ctor_args) == IS_ARRAY) {
659-
pdo_stmt_construct(stmt, return_value, dbstmt_ce, Z_ARRVAL(ctor_args));
660-
} else {
661-
pdo_stmt_construct(stmt, return_value, dbstmt_ce, /* ctor_args */ NULL);
662-
}
654+
pdo_stmt_construct(stmt, return_value, dbstmt_ce, ctor_args);
663655
return;
664656
}
665657

@@ -923,17 +915,19 @@ static bool pdo_dbh_attribute_set(pdo_dbh_t *dbh, zend_long attr, zval *value) /
923915
return false;
924916
}
925917
dbh->def_stmt_ce = pce;
926-
if (!Z_ISUNDEF(dbh->def_stmt_ctor_args)) {
927-
zval_ptr_dtor(&dbh->def_stmt_ctor_args);
928-
ZVAL_UNDEF(&dbh->def_stmt_ctor_args);
918+
if (dbh->def_stmt_ctor_args != NULL) {
919+
zend_array_release(dbh->def_stmt_ctor_args);
920+
dbh->def_stmt_ctor_args = NULL;
929921
}
930922
if ((item = zend_hash_index_find(Z_ARRVAL_P(value), 1)) != NULL) {
931923
if (Z_TYPE_P(item) != IS_ARRAY) {
932924
zend_type_error("PDO::ATTR_STATEMENT_CLASS constructor_args must be of type ?array, %s given",
933925
zend_zval_value_name(value));
934926
return false;
935927
}
936-
ZVAL_COPY(&dbh->def_stmt_ctor_args, item);
928+
dbh->def_stmt_ctor_args = Z_ARRVAL_P(item);
929+
/* Increase refcount */
930+
GC_TRY_ADDREF(dbh->def_stmt_ctor_args);
937931
}
938932
return true;
939933
}
@@ -1012,9 +1006,10 @@ PHP_METHOD(PDO, getAttribute)
10121006
case PDO_ATTR_STATEMENT_CLASS:
10131007
array_init(return_value);
10141008
add_next_index_str(return_value, zend_string_copy(dbh->def_stmt_ce->name));
1015-
if (!Z_ISUNDEF(dbh->def_stmt_ctor_args)) {
1016-
Z_TRY_ADDREF(dbh->def_stmt_ctor_args);
1017-
add_next_index_zval(return_value, &dbh->def_stmt_ctor_args);
1009+
if (dbh->def_stmt_ctor_args != NULL) {
1010+
/* Increase refcount */
1011+
GC_TRY_ADDREF(dbh->def_stmt_ctor_args);
1012+
add_next_index_array(return_value, dbh->def_stmt_ctor_args);
10181013
}
10191014
return;
10201015

@@ -1204,7 +1199,7 @@ PHP_METHOD(PDO, query)
12041199

12051200
PDO_DBH_CLEAR_ERR();
12061201

1207-
if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, &dbh->def_stmt_ctor_args)) {
1202+
if (!pdo_stmt_instantiate(dbh, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args)) {
12081203
RETURN_THROWS();
12091204
}
12101205
stmt = Z_PDO_STMT_P(return_value);
@@ -1233,11 +1228,7 @@ PHP_METHOD(PDO, query)
12331228
stmt->executed = 1;
12341229
}
12351230
if (ret) {
1236-
if (Z_TYPE(dbh->def_stmt_ctor_args) == IS_ARRAY) {
1237-
pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, Z_ARRVAL(dbh->def_stmt_ctor_args));
1238-
} else {
1239-
pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, /* ctor_args */ NULL);
1240-
}
1231+
pdo_stmt_construct(stmt, return_value, dbh->def_stmt_ce, dbh->def_stmt_ctor_args);
12411232
return;
12421233
}
12431234
}
@@ -1432,7 +1423,10 @@ static HashTable *dbh_get_gc(zend_object *object, zval **gc_data, int *gc_count)
14321423
{
14331424
pdo_dbh_t *dbh = php_pdo_dbh_fetch_inner(object);
14341425
zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
1435-
zend_get_gc_buffer_add_zval(gc_buffer, &dbh->def_stmt_ctor_args);
1426+
if (dbh->def_stmt_ctor_args != NULL) {
1427+
zend_get_gc_buffer_add_ht(gc_buffer, dbh->def_stmt_ctor_args);
1428+
dbh->def_stmt_ctor_args = NULL;
1429+
}
14361430
if (dbh->methods && dbh->methods->get_gc) {
14371431
dbh->methods->get_gc(dbh, gc_buffer);
14381432
}
@@ -1495,8 +1489,9 @@ static void dbh_free(pdo_dbh_t *dbh, bool free_persistent)
14951489
pefree((char *)dbh->persistent_id, dbh->is_persistent);
14961490
}
14971491

1498-
if (!Z_ISUNDEF(dbh->def_stmt_ctor_args)) {
1499-
zval_ptr_dtor(&dbh->def_stmt_ctor_args);
1492+
if (dbh->def_stmt_ctor_args != NULL) {
1493+
zend_array_release(dbh->def_stmt_ctor_args);
1494+
dbh->def_stmt_ctor_args = NULL;
15001495
}
15011496

15021497
for (i = 0; i < PDO_DBH_DRIVER_METHOD_KIND__MAX; i++) {
@@ -1541,6 +1536,7 @@ zend_object *pdo_dbh_new(zend_class_entry *ce)
15411536
zend_std_get_properties_ex(&dbh->std);
15421537
dbh->inner = ecalloc(1, sizeof(pdo_dbh_t));
15431538
dbh->inner->def_stmt_ce = pdo_dbstmt_ce;
1539+
dbh->inner->def_stmt_ctor_args = NULL;
15441540

15451541
return &dbh->std;
15461542
}

ext/pdo/php_pdo_driver.h

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

493493
zend_class_entry *def_stmt_ce;
494494

495-
zval def_stmt_ctor_args;
495+
HashTable *def_stmt_ctor_args;
496496

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

0 commit comments

Comments
 (0)