X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Flibffi.c;h=627c97f5a27e5d01384bd659930af49312c3af74;hb=6b2e6562e64a263a42910d28e23b6ca94f3ecb65;hp=514394f4047f506650473e367a724a7c729d4d8b;hpb=70f215a31fab4be1fe3e80125eb401e11eb02b9f;p=m6w6%2Fext-psi diff --git a/src/libffi.c b/src/libffi.c index 514394f..627c97f 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -78,50 +78,7 @@ static void psi_ffi_handler(ffi_cif *_sig, void *_result, void **_args, void *_d static void psi_ffi_callback(ffi_cif *_sig, void *_result, void **_args, void *_data) { - size_t i; - unsigned argc = _sig->nargs; - void **argv = _args; - let_callback *cb = _data; - decl *decl_cb = cb->decl; - impl_arg *iarg = cb->func->var->arg; - zval return_value, *zargv = calloc(argc, sizeof(*zargv)); - void *result, *to_free = NULL; - - ZEND_ASSERT(argc == cb->decl->args->count); - - /* prepare args for the userland call */ - for (i = 0; i < argc; ++i) { - cb->decl->args->args[i]->ptr = argv[i]; - } - for (i = 0; i < cb->args->count; ++i) { - psi_do_set(&zargv[i], cb->args->vals[i]); - } - zend_fcall_info_argp(&iarg->val.zend.cb->fci, cb->args->count, zargv); - - /* callback into userland */ - ZVAL_UNDEF(&return_value); - iarg->_zv = &return_value; - zend_fcall_info_call(&iarg->val.zend.cb->fci, &iarg->val.zend.cb->fcc, iarg->_zv, NULL); - - /* marshal return value of the userland call */ - switch (iarg->type->type) { - case PSI_T_BOOL: zend_parse_arg_bool(iarg->_zv, &iarg->val.zend.bval, NULL, 0); break; - case PSI_T_LONG: zend_parse_arg_long(iarg->_zv, &iarg->val.zend.lval, NULL, 0, 1); break; - case PSI_T_FLOAT: - case PSI_T_DOUBLE: zend_parse_arg_double(iarg->_zv, &iarg->val.dval, NULL, 0); break; - case PSI_T_STRING: zend_parse_arg_str(iarg->_zv, &iarg->val.zend.str, 0); break; - } - result = cb->func->handler(_result, decl_cb->func->type, iarg, &to_free); - - if (result != _result) { - *(void **)_result = result; - } - - zend_fcall_info_args_clear(&iarg->val.zend.cb->fci, 0); - for (i = 0; i < cb->args->count; ++i) { - zval_ptr_dtor(&zargv[i]); - } - free(zargv); + psi_callback(_data, _result, _sig->nargs, _args); } static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg); @@ -313,25 +270,22 @@ static inline ffi_type *psi_ffi_decl_type(decl_type *type) { decl_type *real = real_decl_type(type); switch (real->type) { - case PSI_T_FUNCTION: - return &ffi_type_pointer; - case PSI_T_STRUCT: - if (!real->strct->engine.type) { + if (!real->real.strct->engine.type) { ffi_type *strct = calloc(1, sizeof(ffi_type)); strct->type = FFI_TYPE_STRUCT; strct->size = 0; - strct->elements = psi_ffi_struct_type_elements(real->strct); + strct->elements = psi_ffi_struct_type_elements(real->real.strct); - real->strct->engine.type = strct; - real->strct->engine.dtor = psi_ffi_struct_type_dtor; + real->real.strct->engine.type = strct; + real->real.strct->engine.dtor = psi_ffi_struct_type_dtor; } - return real->strct->engine.type; + return real->real.strct->engine.type; case PSI_T_UNION: - return psi_ffi_decl_arg_type(real->unn->args->args[0]); + return psi_ffi_decl_arg_type(real->real.unn->args->args[0]); default: return psi_ffi_token_type(real->type); @@ -362,6 +316,13 @@ static inline PSI_LibffiContext *PSI_LibffiContextInit(PSI_LibffiContext *L) { return L; } +static inline void PSI_LibffiContextFree(PSI_LibffiContext **L) { + if (*L) { + free(*L); + *L = NULL; + } +} + static void psi_ffi_init(PSI_Context *C) { C->context = PSI_LibffiContextInit(NULL); @@ -400,7 +361,7 @@ static void psi_ffi_dtor(PSI_Context *C) } } } - free(C->context); + PSI_LibffiContextFree((void *) &C->context); } static zend_function_entry *psi_ffi_compile(PSI_Context *C) @@ -422,10 +383,11 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C) continue; } - call = PSI_LibffiCallAlloc(C, impl->decl); - if (FFI_OK != PSI_LibffiCallInitClosure(C, call, impl)) { - PSI_LibffiCallFree(call); - continue; + if ((call = PSI_LibffiCallAlloc(C, impl->decl))) { + if (FFI_OK != PSI_LibffiCallInitClosure(C, call, impl)) { + PSI_LibffiCallFree(call); + continue; + } } zf->fname = impl->func->name + (impl->func->name[0] == '\\'); @@ -437,16 +399,17 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C) for (c = 0; c < impl->stmts->let.count; ++c) { let_stmt *let = impl->stmts->let.list[c]; - if (let->val->kind == PSI_LET_CALLBACK) { + if (let->val && let->val->kind == PSI_LET_CALLBACK) { let_callback *cb = let->val->data.callback; - call = PSI_LibffiCallAlloc(C, cb->decl); - if (FFI_OK != PSI_LibffiCallInitCallbackClosure(C, call, cb)) { - PSI_LibffiCallFree(call); - continue; - } + if ((call = PSI_LibffiCallAlloc(C, cb->decl))) { + if (FFI_OK != PSI_LibffiCallInitCallbackClosure(C, call, cb)) { + PSI_LibffiCallFree(call); + continue; + } - cb->decl->call.sym = call->code; + cb->decl->call.sym = call->code; + } } } } @@ -454,9 +417,6 @@ static zend_function_entry *psi_ffi_compile(PSI_Context *C) for (i = 0; i < C->decls->count; ++i) { decl *decl = C->decls->list[i]; -// if (decl->impl) { -// continue; -// } if (decl->call.info) { continue; }