Skip to content

Commit f9b0c64

Browse files
committed
Use the new FCC API
1 parent 8e4363d commit f9b0c64

File tree

3 files changed

+62
-71
lines changed

3 files changed

+62
-71
lines changed

ext/pdo_sqlite/pdo_sqlite.c

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -335,33 +335,25 @@ PHP_METHOD(PdoSqlite, openBlob)
335335
static int php_sqlite_collation_callback(void *context, int string1_len, const void *string1,
336336
int string2_len, const void *string2)
337337
{
338-
int ret;
338+
int ret = 0;
339339
zval zargs[2];
340340
zval retval;
341341
struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
342342

343-
collation->fc.fci.size = sizeof(collation->fc.fci);
344-
ZVAL_COPY_VALUE(&collation->fc.fci.function_name, &collation->callback);
345-
collation->fc.fci.object = NULL;
346-
collation->fc.fci.retval = &retval;
347-
348343
// Prepare the arguments.
349344
ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
350345
ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
351-
collation->fc.fci.param_count = 2;
352-
collation->fc.fci.params = zargs;
353346

354-
if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc)) == FAILURE) {
355-
php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
356-
} else if (!Z_ISUNDEF(retval)) {
347+
zend_call_known_fcc(&collation->callback, &retval, /* argc */ 2, zargs, /* named_params */ NULL);
348+
349+
if (!Z_ISUNDEF(retval)) {
357350
if (Z_TYPE(retval) != IS_LONG) {
358351
zend_string *func_name = get_active_function_or_method_name();
359352
zend_type_error("%s(): Return value of the callback must be of type int, %s returned",
360353
ZSTR_VAL(func_name), zend_zval_value_name(&retval));
361354
zend_string_release(func_name);
362355
return FAILURE;
363356
}
364-
ret = 0;
365357
if (Z_LVAL(retval) > 0) {
366358
ret = 1;
367359
} else if (Z_LVAL(retval) < 0) {

ext/pdo_sqlite/php_pdo_sqlite_int.h

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,23 @@ typedef struct {
2626
char *errmsg;
2727
} pdo_sqlite_error_info;
2828

29-
struct pdo_sqlite_fci {
30-
zend_fcall_info fci;
31-
zend_fcall_info_cache fcc;
32-
};
33-
3429
struct pdo_sqlite_func {
3530
struct pdo_sqlite_func *next;
3631

37-
zval func, step, fini;
3832
int argc;
3933
const char *funcname;
4034

4135
/* accelerated callback references */
42-
struct pdo_sqlite_fci afunc, astep, afini;
36+
zend_fcall_info_cache func;
37+
zend_fcall_info_cache step;
38+
zend_fcall_info_cache fini;
4339
};
4440

4541
struct pdo_sqlite_collation {
4642
struct pdo_sqlite_collation *next;
4743

4844
const char *name;
49-
zval callback;
50-
struct pdo_sqlite_fci fc;
45+
zend_fcall_info_cache callback;
5146
};
5247

5348
typedef struct {

ext/pdo_sqlite/sqlite_driver.c

Lines changed: 54 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -112,14 +112,14 @@ static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
112112
}
113113

114114
efree((char*)func->funcname);
115-
if (!Z_ISUNDEF(func->func)) {
116-
zval_ptr_dtor(&func->func);
115+
if (ZEND_FCC_INITIALIZED(func->func)) {
116+
zend_fcc_dtor(&func->func);
117117
}
118-
if (!Z_ISUNDEF(func->step)) {
119-
zval_ptr_dtor(&func->step);
118+
if (ZEND_FCC_INITIALIZED(func->step)) {
119+
zend_fcc_dtor(&func->step);
120120
}
121-
if (!Z_ISUNDEF(func->fini)) {
122-
zval_ptr_dtor(&func->fini);
121+
if (ZEND_FCC_INITIALIZED(func->fini)) {
122+
zend_fcc_dtor(&func->fini);
123123
}
124124
efree(func);
125125
}
@@ -139,8 +139,8 @@ static void pdo_sqlite_cleanup_callbacks(pdo_sqlite_db_handle *H)
139139
}
140140

141141
efree((char*)collation->name);
142-
if (!Z_ISUNDEF(collation->callback)) {
143-
zval_ptr_dtor(&collation->callback);
142+
if (ZEND_FCC_INITIALIZED(collation->callback)) {
143+
zend_fcc_dtor(&collation->callback);
144144
}
145145
efree(collation);
146146
}
@@ -309,12 +309,12 @@ typedef struct {
309309
zend_long row;
310310
} aggregate_context;
311311

312-
static int do_callback(struct pdo_sqlite_fci *fc, zval *cb, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg)
312+
static int do_callback(zend_fcall_info_cache *fcc, int argc, sqlite3_value **argv, sqlite3_context *context, int is_agg)
313313
{
314314
zval *zargs = NULL;
315315
zval retval;
316316
int i;
317-
int ret;
317+
int ret = SUCCESS;
318318
int fake_argc;
319319
aggregate_context *agg_context = NULL;
320320

@@ -324,14 +324,7 @@ static int do_callback(struct pdo_sqlite_fci *fc, zval *cb, int argc, sqlite3_va
324324

325325
fake_argc = argc + is_agg;
326326

327-
fc->fci.size = sizeof(fc->fci);
328-
ZVAL_COPY_VALUE(&fc->fci.function_name, cb);
329-
fc->fci.object = NULL;
330-
fc->fci.retval = &retval;
331-
fc->fci.param_count = fake_argc;
332-
333327
/* build up the params */
334-
335328
if (fake_argc) {
336329
zargs = safe_emalloc(fake_argc, sizeof(zval), 0);
337330
}
@@ -372,11 +365,7 @@ static int do_callback(struct pdo_sqlite_fci *fc, zval *cb, int argc, sqlite3_va
372365
}
373366
}
374367

375-
fc->fci.params = zargs;
376-
377-
if ((ret = zend_call_function(&fc->fci, &fc->fcc)) == FAILURE) {
378-
php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
379-
}
368+
zend_call_known_fcc(fcc, &retval, fake_argc, zargs, /* named_params */ NULL);
380369

381370
/* clean up the params */
382371
if (zargs) {
@@ -445,41 +434,33 @@ static void php_sqlite3_func_step_callback(sqlite3_context *context, int argc, s
445434
{
446435
struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
447436

448-
do_callback(&func->astep, &func->step, argc, argv, context, 1);
437+
do_callback(&func->step, argc, argv, context, 1);
449438
}
450439

451440
static void php_sqlite3_func_final_callback(sqlite3_context *context)
452441
{
453442
struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
454443

455-
do_callback(&func->afini, &func->fini, 0, NULL, context, 1);
444+
do_callback(&func->fini, 0, NULL, context, 1);
456445
}
457446

458447
static int php_sqlite3_collation_callback(void *context, int string1_len, const void *string1, int string2_len, const void *string2)
459448
{
460-
int ret;
449+
int ret = 0;
461450
zval zargs[2];
462451
zval retval;
463452
struct pdo_sqlite_collation *collation = (struct pdo_sqlite_collation*) context;
464453

465-
collation->fc.fci.size = sizeof(collation->fc.fci);
466-
ZVAL_COPY_VALUE(&collation->fc.fci.function_name, &collation->callback);
467-
collation->fc.fci.object = NULL;
468-
collation->fc.fci.retval = &retval;
469-
470454
/* Prepare the arguments. */
471455
ZVAL_STRINGL(&zargs[0], (char *) string1, string1_len);
472456
ZVAL_STRINGL(&zargs[1], (char *) string2, string2_len);
473-
collation->fc.fci.param_count = 2;
474-
collation->fc.fci.params = zargs;
475457

476-
if ((ret = zend_call_function(&collation->fc.fci, &collation->fc.fcc)) == FAILURE) {
477-
php_error_docref(NULL, E_WARNING, "An error occurred while invoking the callback");
478-
} else if (!Z_ISUNDEF(retval)) {
458+
zend_call_known_fcc(&collation->callback, &retval, /* argc */ 2, zargs, /* named_params */ NULL);
459+
460+
if (!Z_ISUNDEF(retval)) {
479461
if (Z_TYPE(retval) != IS_LONG) {
480462
convert_to_long(&retval);
481463
}
482-
ret = 0;
483464
if (Z_LVAL(retval) > 0) {
484465
ret = 1;
485466
} else if (Z_LVAL(retval) < 0) {
@@ -498,7 +479,7 @@ static void php_sqlite3_func_callback(sqlite3_context *context, int argc, sqlite
498479
{
499480
struct pdo_sqlite_func *func = (struct pdo_sqlite_func*)sqlite3_user_data(context);
500481

501-
do_callback(&func->afunc, &func->func, argc, argv, context, 0);
482+
do_callback(&func->func, argc, argv, context, 0);
502483
}
503484

504485
void pdo_sqlite_create_function_internal(INTERNAL_FUNCTION_PARAMETERS)
@@ -516,7 +497,7 @@ void pdo_sqlite_create_function_internal(INTERNAL_FUNCTION_PARAMETERS)
516497

517498
ZEND_PARSE_PARAMETERS_START(2, 4)
518499
Z_PARAM_STRING(func_name, func_name_len)
519-
Z_PARAM_FUNC(fci, fcc)
500+
Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(fci, fcc)
520501
Z_PARAM_OPTIONAL
521502
Z_PARAM_LONG(argc)
522503
Z_PARAM_LONG(flags)
@@ -533,7 +514,7 @@ void pdo_sqlite_create_function_internal(INTERNAL_FUNCTION_PARAMETERS)
533514
if (ret == SQLITE_OK) {
534515
func->funcname = estrdup(func_name);
535516

536-
ZVAL_COPY(&func->func, &fci.function_name);
517+
zend_fcc_dup(&func->func, &fcc);
537518

538519
func->argc = argc;
539520

@@ -544,6 +525,7 @@ void pdo_sqlite_create_function_internal(INTERNAL_FUNCTION_PARAMETERS)
544525
}
545526

546527
efree(func);
528+
zend_release_fcall_info_cache(&fcc);
547529
RETURN_FALSE;
548530
}
549531

@@ -566,14 +548,18 @@ void pdo_sqlite_create_aggregate_internal(INTERNAL_FUNCTION_PARAMETERS)
566548
pdo_dbh_t *dbh;
567549
pdo_sqlite_db_handle *H;
568550
int ret;
551+
bool is_throw = false;
552+
553+
step_fcc.function_handler = NULL;
554+
fini_fcc.function_handler = NULL;
569555

570556
ZEND_PARSE_PARAMETERS_START(3, 4)
571557
Z_PARAM_STRING(func_name, func_name_len)
572-
Z_PARAM_FUNC(step_fci, step_fcc)
573-
Z_PARAM_FUNC(fini_fci, fini_fcc)
558+
Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(step_fci, step_fcc)
559+
Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(fini_fci, fini_fcc)
574560
Z_PARAM_OPTIONAL
575561
Z_PARAM_LONG(argc)
576-
ZEND_PARSE_PARAMETERS_END();
562+
ZEND_PARSE_PARAMETERS_END_EX(is_throw = true; goto error;);
577563

578564
dbh = Z_PDO_DBH_P(ZEND_THIS);
579565
PDO_CONSTRUCT_CHECK;
@@ -587,9 +573,9 @@ void pdo_sqlite_create_aggregate_internal(INTERNAL_FUNCTION_PARAMETERS)
587573
if (ret == SQLITE_OK) {
588574
func->funcname = estrdup(func_name);
589575

590-
ZVAL_COPY(&func->step, &step_fci.function_name);
576+
zend_fcc_dup(&func->step, &step_fcc);
591577

592-
ZVAL_COPY(&func->fini, &fini_fci.function_name);
578+
zend_fcc_dup(&func->fini, &fini_fcc);
593579

594580
func->argc = argc;
595581

@@ -600,6 +586,14 @@ void pdo_sqlite_create_aggregate_internal(INTERNAL_FUNCTION_PARAMETERS)
600586
}
601587

602588
efree(func);
589+
590+
error:
591+
zend_release_fcall_info_cache(&step_fcc);
592+
zend_release_fcall_info_cache(&fini_fcc);
593+
594+
if (is_throw) {
595+
RETURN_THROWS();
596+
}
603597
RETURN_FALSE;
604598
}
605599

@@ -641,7 +635,7 @@ void pdo_sqlite_create_collation_internal(INTERNAL_FUNCTION_PARAMETERS, pdo_sqli
641635

642636
ZEND_PARSE_PARAMETERS_START(2, 2)
643637
Z_PARAM_STRING(collation_name, collation_name_len)
644-
Z_PARAM_FUNC(fci, fcc)
638+
Z_PARAM_FUNC_NO_TRAMPOLINE_FREE(fci, fcc)
645639
ZEND_PARSE_PARAMETERS_END();
646640

647641
dbh = Z_PDO_DBH_P(ZEND_THIS);
@@ -655,14 +649,16 @@ void pdo_sqlite_create_collation_internal(INTERNAL_FUNCTION_PARAMETERS, pdo_sqli
655649
if (ret == SQLITE_OK) {
656650
collation->name = estrdup(collation_name);
657651

658-
ZVAL_COPY(&collation->callback, &fci.function_name);
652+
zend_fcc_dup(&collation->callback, &fcc);
659653

660654
collation->next = H->collations;
661655
H->collations = collation;
662656

663657
RETURN_TRUE;
664658
}
665659

660+
zend_release_fcall_info_cache(&fcc);
661+
666662
if (UNEXPECTED(EG(exception))) {
667663
RETURN_THROWS();
668664
}
@@ -706,15 +702,23 @@ static void pdo_sqlite_get_gc(pdo_dbh_t *dbh, zend_get_gc_buffer *gc_buffer)
706702

707703
struct pdo_sqlite_func *func = H->funcs;
708704
while (func) {
709-
zend_get_gc_buffer_add_zval(gc_buffer, &func->func);
710-
zend_get_gc_buffer_add_zval(gc_buffer, &func->step);
711-
zend_get_gc_buffer_add_zval(gc_buffer, &func->fini);
705+
if (ZEND_FCC_INITIALIZED(func->func)) {
706+
zend_get_gc_buffer_add_fcc(gc_buffer, &func->func);
707+
}
708+
if (ZEND_FCC_INITIALIZED(func->step)) {
709+
zend_get_gc_buffer_add_fcc(gc_buffer, &func->step);
710+
}
711+
if (ZEND_FCC_INITIALIZED(func->fini)) {
712+
zend_get_gc_buffer_add_fcc(gc_buffer, &func->fini);
713+
}
712714
func = func->next;
713715
}
714716

715717
struct pdo_sqlite_collation *collation = H->collations;
716718
while (collation) {
717-
zend_get_gc_buffer_add_zval(gc_buffer, &collation->callback);
719+
if (ZEND_FCC_INITIALIZED(collation->callback)) {
720+
zend_get_gc_buffer_add_fcc(gc_buffer, &collation->callback);
721+
}
718722
collation = collation->next;
719723
}
720724
}

0 commit comments

Comments
 (0)