Skip to content

Commit f6e74e7

Browse files
committed
Remove zend_fcall_info_args_ex() HashTable emulation
1 parent d4ae5f3 commit f6e74e7

File tree

3 files changed

+17
-51
lines changed

3 files changed

+17
-51
lines changed

ext/pdo/pdo_stmt.c

Lines changed: 6 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -634,49 +634,6 @@ static bool pdo_do_key_pair_fetch(pdo_stmt_t *stmt, enum pdo_fetch_orientation o
634634
return true;
635635
}
636636

637-
/* Previous the legacy zend_fcall_info_args_ex() function was used to set the
638-
* constructor arguments. The particularity of this function is to it "wraps" arguments
639-
* that need to be passed by-ref in a reference.
640-
* As this API only supported positional args, we don't bother doing this for named arguments. */
641-
static HashTable* pdo_class_fetch_prepare_constructor_arguments(const zend_function *constructor, HashTable *ctor_args)
642-
{
643-
zend_ulong index;
644-
zend_string *arg_name = NULL;
645-
zval *arg_value = NULL;
646-
bool needs_duplication = false;
647-
ZEND_HASH_FOREACH_KEY_VAL(ctor_args, index, arg_name, arg_value) {
648-
/* Named param, means we can assume no positional arguments exist after */
649-
if (arg_name) {
650-
break;
651-
}
652-
if (!Z_ISREF_P(arg_value) && ARG_SHOULD_BE_SENT_BY_REF(constructor, index+1)) {
653-
needs_duplication = true;
654-
break;
655-
}
656-
} ZEND_HASH_FOREACH_END();
657-
if (needs_duplication) {
658-
HashTable *duplicated = zend_new_array(zend_hash_num_elements(ctor_args));
659-
ZEND_HASH_FOREACH_KEY_VAL(ctor_args, index, arg_name, arg_value) {
660-
if (arg_name) {
661-
zend_hash_add(duplicated, arg_name, arg_value);
662-
} else {
663-
zval val;
664-
if (!Z_ISREF_P(arg_value) && ARG_SHOULD_BE_SENT_BY_REF(constructor, index+1)) {
665-
Z_TRY_ADDREF_P(arg_value);
666-
ZVAL_NEW_REF(&val, arg_value);
667-
} else {
668-
ZVAL_COPY_VALUE(&val, arg_value);
669-
}
670-
zend_hash_index_add(duplicated, index, &val);
671-
}
672-
} ZEND_HASH_FOREACH_END();
673-
return duplicated;
674-
} else {
675-
GC_TRY_ADDREF(ctor_args);
676-
return ctor_args;
677-
}
678-
}
679-
680637
/* Return value MUST be an initialized object */
681638
static bool pdo_call_fetch_object_constructor(zend_function *constructor, HashTable *ctor_args, zval *return_value)
682639
{
@@ -1118,7 +1075,8 @@ PHP_METHOD(PDOStatement, fetchObject)
11181075
zend_argument_value_error(2, "must be empty when class provided in argument #1 ($class) does not have a constructor");
11191076
goto reset_old_ctor_args;
11201077
}
1121-
stmt->fetch.cls.ctor_args = pdo_class_fetch_prepare_constructor_arguments(ce->constructor, ctor_args);
1078+
GC_TRY_ADDREF(ctor_args);
1079+
stmt->fetch.cls.ctor_args = ctor_args;
11221080
}
11231081
} else {
11241082
stmt->fetch.cls.ce = zend_standard_class_def;
@@ -1230,7 +1188,8 @@ PHP_METHOD(PDOStatement, fetchAll)
12301188
zend_argument_value_error(3, "must be empty when class provided in argument #2 ($class) does not have a constructor");
12311189
goto reset_old_ctor_args;
12321190
}
1233-
stmt->fetch.cls.ctor_args = pdo_class_fetch_prepare_constructor_arguments(stmt->fetch.cls.ce->constructor, ctor_args);
1191+
GC_TRY_ADDREF(ctor_args);
1192+
stmt->fetch.cls.ctor_args = ctor_args;
12341193
}
12351194
break;
12361195

@@ -1753,7 +1712,8 @@ bool pdo_stmt_setup_fetch_mode(pdo_stmt_t *stmt, zend_long mode, uint32_t mode_a
17531712
zend_argument_value_error(3, "must be empty when class provided in argument #2 ($class) does not have a constructor");
17541713
return false;
17551714
}
1756-
stmt->fetch.cls.ctor_args = pdo_class_fetch_prepare_constructor_arguments(cep->constructor, Z_ARRVAL(args[1]));
1715+
GC_TRY_ADDREF(Z_ARRVAL(args[1]));
1716+
stmt->fetch.cls.ctor_args = Z_ARRVAL(args[1]);
17571717
}
17581718
}
17591719
stmt->fetch.cls.ce = cep;

ext/pdo/tests/pdo_fetch_class_basic.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ $stmt->execute();
4848
var_dump($stmt->fetchAll(PDO::FETCH_CLASS, 'TestBase'));
4949

5050
$stmt->execute();
51-
var_dump($stmt->fetchAll(PDO::FETCH_CLASS, 'TestDerived', array(0)));
51+
$rowCounter = 0;
52+
var_dump($stmt->fetchAll(PDO::FETCH_CLASS, 'TestDerived', [&$rowCounter]));
5253

5354
?>
5455
--CLEAN--

ext/pdo/tests/pdo_fetch_class_by_ref_constructor.phpt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,14 @@ $db = PDOTest::factory();
4747
PDOTest::dropTableIfExists($db, "pdo_fetch_class_by_ref_ctor");
4848
?>
4949
--EXPECTF--
50+
Warning: TestByRefCtor::__construct(): Argument #1 ($str) must be passed by reference, value given in %s on line %d
5051
TestByRefCtor::__construct(aaaaaaaaaa, 1)
51-
TestByRefCtor::__construct(aaaaaaaaaaA, 2)
52-
TestByRefCtor::__construct(aaaaaaaaaaAB, 3)
52+
53+
Warning: TestByRefCtor::__construct(): Argument #1 ($str) must be passed by reference, value given in %s on line %d
54+
TestByRefCtor::__construct(aaaaaaaaaa, 2)
55+
56+
Warning: TestByRefCtor::__construct(): Argument #1 ($str) must be passed by reference, value given in %s on line %d
57+
TestByRefCtor::__construct(aaaaaaaaaa, 3)
5358
array(3) {
5459
[0]=>
5560
object(TestByRefCtor)#%d (3) {
@@ -67,7 +72,7 @@ array(3) {
6772
["val"]=>
6873
string(1) "B"
6974
["str":"TestByRefCtor":private]=>
70-
string(12) "aaaaaaaaaaAB"
75+
string(11) "aaaaaaaaaaB"
7176
}
7277
[2]=>
7378
object(TestByRefCtor)#%d (3) {
@@ -76,6 +81,6 @@ array(3) {
7681
["val"]=>
7782
string(1) "C"
7883
["str":"TestByRefCtor":private]=>
79-
string(13) "aaaaaaaaaaABC"
84+
string(11) "aaaaaaaaaaC"
8085
}
8186
}

0 commit comments

Comments
 (0)