Skip to content

Commit 10249ff

Browse files
committed
improve call function
1 parent 29dd0be commit 10249ff

File tree

4 files changed

+130
-92
lines changed

4 files changed

+130
-92
lines changed

helper.c

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,3 +247,42 @@ int php_git2_make_resource(php_git2_t **out, enum php_git2_resource_type type, v
247247
return 0;
248248
}
249249

250+
251+
int php_git2_call_function_v(
252+
zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC, zval **retval_ptr_ptr, zend_uint param_count, ...)
253+
{
254+
zval **params = NULL;
255+
va_list ap;
256+
int i = 0;
257+
258+
if (param_count > 0) {
259+
params = emalloc(sizeof(zval*) * param_count);
260+
va_start(ap, param_count);
261+
for (i = 0; i < param_count; i++) {
262+
params[i] = va_arg(ap, zval**);
263+
}
264+
va_end(ap);
265+
} else {
266+
params = NULL;
267+
}
268+
269+
if (ZEND_FCI_INITIALIZED(*fci)) {
270+
fci->params = params;
271+
fci->retval_ptr_ptr = retval_ptr_ptr;
272+
fci->param_count = param_count;
273+
fci->no_separation = 1;
274+
275+
if (zend_call_function(fci, fcc TSRMLS_CC) != SUCCESS) {
276+
return 1;
277+
}
278+
zend_fcall_info_args_clear(fci, 0);
279+
}
280+
281+
if (param_count > 0) {
282+
for (i = 0; i < param_count; i++) {
283+
zval_ptr_dtor(params[i]);
284+
}
285+
efree(params);
286+
}
287+
return 0;
288+
}

helper.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,7 @@ void php_git2_strarray_to_array(git_strarray *array, zval **out TSRMLS_DC);
4444

4545
int php_git2_make_resource(php_git2_t **out, enum php_git2_resource_type type, void *resource, int should_free TSRMLS_DC);
4646

47+
int php_git2_call_function_v(
48+
zend_fcall_info *fci, zend_fcall_info_cache *fcc TSRMLS_DC, zval **retval_ptr_ptr, zend_uint param_count, ...);
49+
4750
#endif

php_git2_priv.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,16 @@ extern int git2_resource_handle;
3838
#define GIT2_RVAL_P(git2) git2->resource_id
3939
#define GIT2_SHOULD_FREE(git2) git2->should_free_v
4040

41+
#ifdef ZTS
42+
#define GIT2_TSRMLS_SET(target) void ***tsrm_ls = target;
43+
#define GIT2_TSRMLS_DECL void ***tsrm_ls;
44+
#define GIT2_TSRMLS_SET2(target, value) target->tsrm_ls = value;
45+
#else
46+
#define GIT2_TSRMLS_SET(target)
47+
#define GIT2_TSRMLS_SET2(target, value)
48+
#define GIT2_TSRMLS_DECL
49+
#endif
50+
4151
#define PHP_GIT2_MAKE_RESOURCE(val) \
4252
do {\
4353
val = (php_git2_t *)emalloc(sizeof(php_git2_t));\

tree.c

Lines changed: 78 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,64 @@
22
#include "php_git2_priv.h"
33
#include "tree.h"
44

5+
typedef struct tree_walk_cb_t {
6+
zval *payload;
7+
zend_fcall_info *fci;
8+
zend_fcall_info_cache *fcc;
9+
GIT2_TSRMLS_DECL
10+
};
11+
12+
static int tree_walk_cb(const char *root, const git_tree_entry *entry, void *payload)
13+
{
14+
php_git2_t *result;
15+
zval *param_root, *param_rsrc, *retval_ptr = NULL;
16+
struct tree_walk_cb_t *p = (struct tree_walk_cb_t*)payload;
17+
int i = 0;
18+
GIT2_TSRMLS_SET(p->tsrm_ls)
19+
20+
Z_ADDREF_P(p->payload);
21+
MAKE_STD_ZVAL(param_root);
22+
MAKE_STD_ZVAL(param_rsrc);
23+
24+
ZVAL_STRING(param_root, root, 1);
25+
php_git2_make_resource(&result, PHP_GIT2_TYPE_TREE_ENTRY, entry, 0 TSRMLS_CC);
26+
zend_list_addref(result->resource_id);
27+
ZVAL_RESOURCE(param_rsrc, result->resource_id);
28+
29+
if (php_git2_call_function_v(p->fci, p->fcc TSRMLS_CC, &retval_ptr, 3, &param_root, &param_rsrc, &p->payload)) {
30+
zval_ptr_dtor(&retval_ptr);
31+
zend_list_delete(result->resource_id);
32+
return 0;
33+
}
34+
zval_ptr_dtor(&retval_ptr);
35+
zend_list_delete(result->resource_id);
36+
37+
return 1;
38+
}
39+
40+
static int php_git2_tree_walk_cb_init(struct tree_walk_cb **out, zend_fcall_info *fci, zend_fcall_info_cache *fcc, void *payload TSRMLS_DC)
41+
{
42+
struct tree_walk_cb_t *cb;
43+
44+
cb = (struct tree_walk_cb_t*)emalloc(sizeof(struct tree_walk_cb_t));
45+
if (cb == NULL) {
46+
return 1;
47+
}
48+
49+
cb->payload = payload;
50+
cb->fci = fci;
51+
cb->fcc = fcc;
52+
GIT2_TSRMLS_SET2(cb, TSRMLS_C);
53+
54+
*out = cb;
55+
return 0;
56+
}
57+
58+
static void php_git2_tree_walk_cb_free(struct tree_walk_cb *target)
59+
{
60+
efree(target);
61+
}
62+
563
/* {{{ proto resource git_tree_entry_byindex(resource $tree, string $name)
664
*/
765
PHP_FUNCTION(git_tree_entry_byindex)
@@ -128,7 +186,6 @@ PHP_FUNCTION(git_tree_entry_id)
128186
zval *tree_entry;
129187
php_git2_t *git2;
130188
char out[GIT2_OID_HEXSIZE] = {0};
131-
132189
const git_oid *id;
133190

134191
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
@@ -138,7 +195,6 @@ PHP_FUNCTION(git_tree_entry_id)
138195

139196
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
140197
id = git_tree_entry_id(PHP_GIT2_V(git2, tree_entry));
141-
142198
git_oid_fmt(out, id);
143199
RETURN_STRING(out, 1);
144200
}
@@ -159,7 +215,6 @@ PHP_FUNCTION(git_tree_entry_type)
159215

160216
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
161217
type = git_tree_entry_type(PHP_GIT2_V(git2, tree));
162-
163218
RETURN_LONG(type);
164219
}
165220

@@ -178,7 +233,6 @@ PHP_FUNCTION(git_tree_entry_name)
178233

179234
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
180235
name = git_tree_entry_name(PHP_GIT2_V(git2, tree_entry));
181-
182236
RETURN_STRING(name, 1);
183237
}
184238

@@ -197,7 +251,6 @@ PHP_FUNCTION(git_tree_entrycount)
197251

198252
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
199253
count = git_tree_entrycount(PHP_GIT2_V(git2, tree));
200-
201254
RETURN_LONG(count);
202255
}
203256

@@ -216,7 +269,6 @@ PHP_FUNCTION(git_tree_entry_filemode)
216269

217270
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
218271
filemode = git_tree_entry_filemode(PHP_GIT2_V(git2, tree_entry));
219-
220272
RETURN_LONG(filemode);
221273
}
222274

@@ -235,7 +287,6 @@ PHP_FUNCTION(git_tree_entry_filemode_raw)
235287

236288
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree_entry, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
237289
filemode = git_tree_entry_filemode_raw(PHP_GIT2_V(git2, tree_entry));
238-
239290
RETURN_LONG(filemode);
240291
}
241292

@@ -254,7 +305,6 @@ PHP_FUNCTION(git_tree_entry_cmp)
254305

255306
ZEND_FETCH_RESOURCE(g_e1, php_git2_t*, &e1, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
256307
ZEND_FETCH_RESOURCE(g_e2, php_git2_t*, &e2, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
257-
258308
result = git_tree_entry_cmp(PHP_GIT2_V(g_e1, tree_entry), PHP_GIT2_V(g_e2, tree_entry));
259309
RETURN_LONG(result);
260310
}
@@ -334,7 +384,6 @@ PHP_FUNCTION(git_tree_id)
334384
zval *tree;
335385
php_git2_t *git2;
336386
char out[GIT2_OID_HEXSIZE] = {0};
337-
338387
const git_oid *id;
339388

340389
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
@@ -344,7 +393,6 @@ PHP_FUNCTION(git_tree_id)
344393

345394
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
346395
id = git_tree_id(PHP_GIT2_V(git2, tree));
347-
348396
git_oid_fmt(out, id);
349397
RETURN_STRING(out, 1);
350398
}
@@ -389,88 +437,27 @@ PHP_FUNCTION(git_tree_lookup)
389437
/* }}} */
390438

391439
/* {{{ proto resource git_tree_owner(resource $tree)
392-
*/
440+
*/
393441
PHP_FUNCTION(git_tree_owner)
394442
{
395-
zval *tree;
396-
php_git2_t *git2, *result;
397-
git_repository *repository;
443+
git_repository *result = NULL;
444+
zval *tree = NULL;
445+
php_git2_t *_tree = NULL, *__result = NULL;
398446

399447
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
400448
"r", &tree) == FAILURE) {
401449
return;
402450
}
403451

404-
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
405-
406-
PHP_GIT2_MAKE_RESOURCE(result);
407-
repository = git_tree_owner(PHP_GIT2_V(git2, tree));
408-
409-
PHP_GIT2_V(result, repository) = repository;
410-
result->type = PHP_GIT2_TYPE_REPOSITORY;
411-
result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle);
412-
result->should_free_v = 0;
413-
414-
ZVAL_RESOURCE(return_value, result->resource_id);
452+
ZEND_FETCH_RESOURCE(_tree, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
453+
result = git_tree_owner(PHP_GIT2_V(_tree, tree));
454+
if (php_git2_make_resource(&__result, PHP_GIT2_TYPE_TREE, result, 0 TSRMLS_CC)) {
455+
RETURN_FALSE;
456+
}
457+
ZVAL_RESOURCE(return_value, GIT2_RVAL_P(__result));
415458
}
416459
/* }}} */
417460

418-
typedef struct tree_walk_cb_t {
419-
zval *payload;
420-
zend_fcall_info *fci;
421-
zend_fcall_info_cache *fcc;
422-
#ifdef ZTS
423-
void ***tsrmls;
424-
#endif
425-
};
426-
427-
static int tree_walk_cb(const char *root, const git_tree_entry *entry, void *payload)
428-
{
429-
php_git2_t *result;
430-
zval **params[3], *param_root, *param_rsrc, *retval_ptr = NULL;
431-
struct tree_walk_cb_t *p = (struct tree_walk_cb_t*)payload;
432-
#ifdef ZTS
433-
void ***tsrm_ls = p->tsrmls;
434-
#endif
435-
436-
MAKE_STD_ZVAL(param_root);
437-
ZVAL_STRING(param_root, root, 1);
438-
MAKE_STD_ZVAL(param_rsrc);
439-
//MAKE_STD_ZVAL(retval_ptr);
440-
441-
PHP_GIT2_MAKE_RESOURCE_NOCHECK(result);
442-
443-
PHP_GIT2_V(result, tree_entry) = entry;
444-
result->type = PHP_GIT2_TYPE_TREE_ENTRY;
445-
result->resource_id = PHP_GIT2_LIST_INSERT(result, git2_resource_handle);
446-
result->should_free_v = 0;
447-
448-
ZVAL_RESOURCE(param_rsrc, result->resource_id);
449-
450-
params[0] = &param_root;
451-
params[1] = &param_rsrc;
452-
params[2] = &p->payload;
453-
454-
if (ZEND_FCI_INITIALIZED(*p->fci)) {
455-
p->fci->params = params;
456-
p->fci->retval_ptr_ptr = &retval_ptr;
457-
p->fci->param_count = 3;
458-
p->fci->no_separation = 1;
459-
460-
if (zend_call_function(p->fci, p->fcc TSRMLS_CC) != SUCCESS) {
461-
}
462-
463-
zend_fcall_info_args_clear(p->fci, 0);
464-
}
465-
466-
zval_ptr_dtor(&param_root);
467-
zval_ptr_dtor(&param_rsrc);
468-
zval_ptr_dtor(&retval_ptr);
469-
470-
zend_list_delete(result->resource_id);
471-
472-
return 1;
473-
}
474461

475462
/* {{{ proto void git_tree_walk(resource $tree, long $mode, Callable $callback, mixed &$payload)
476463
*/
@@ -480,25 +467,24 @@ PHP_FUNCTION(git_tree_walk)
480467
php_git2_t *git2, *result;
481468
zend_fcall_info fci = empty_fcall_info;
482469
zend_fcall_info_cache fcc = empty_fcall_info_cache;
483-
long mode;
470+
long mode = GIT_TREEWALK_PRE;
484471
struct tree_walk_cb_t *cb;
472+
int error = 0;
485473

486474
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
487475
"rlf|z", &tree, &mode, &fci, &fcc, &payload) == FAILURE) {
488476
return;
489477
}
490478

491-
cb = (struct tree_walk_cb_t*)emalloc(sizeof(struct tree_walk_cb_t));
492-
cb->payload = payload;
493-
#ifdef ZTS
494-
cb->tsrmls = TSRMLS_C;
495-
#endif
496-
cb->fci = &fci;
497-
cb->fcc = &fcc;
498-
499479
ZEND_FETCH_RESOURCE(git2, php_git2_t*, &tree, -1, PHP_GIT2_RESOURCE_NAME, git2_resource_handle);
500-
git_tree_walk(PHP_GIT2_V(git2, tree), mode, tree_walk_cb, cb);
480+
if (php_git2_tree_walk_cb_init(&cb, &fci, &fcc, payload TSRMLS_CC)) {
481+
RETURN_FALSE;
482+
}
483+
error = git_tree_walk(PHP_GIT2_V(git2, tree), mode, tree_walk_cb, cb);
484+
php_git2_tree_walk_cb_free(cb);
485+
if (php_git2_check_error(error, "git_tree_walk" TSRMLS_CC)) {
486+
RETURN_FALSE
487+
}
501488

502-
efree(cb);
503489
}
504490
/* }}} */

0 commit comments

Comments
 (0)