X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=src%2Flibffi.c;h=627c97f5a27e5d01384bd659930af49312c3af74;hb=6b2e6562e64a263a42910d28e23b6ca94f3ecb65;hp=0e948a85257739e376f10ad28e3f0bb32d48ff1c;hpb=b9193a8d80bf7ea8d768b9521bcd298a03974c9d;p=m6w6%2Fext-psi diff --git a/src/libffi.c b/src/libffi.c index 0e948a8..627c97f 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -78,44 +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; - } + psi_callback(_data, _result, _sig->nargs, _args); } static inline ffi_type *psi_ffi_decl_arg_type(decl_arg *darg); @@ -307,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); @@ -356,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); @@ -373,8 +340,28 @@ static void psi_ffi_dtor(PSI_Context *C) PSI_LibffiCallFree(decl->call.info); } } + + } + if (C->impls) { + size_t i, j; + + for (i = 0; i < C->impls->count; ++i) { + impl *impl = C->impls->list[i]; + + for (j = 0; j < impl->stmts->let.count; ++j) { + let_stmt *let = impl->stmts->let.list[j]; + + if (let->val && let->val->kind == PSI_LET_CALLBACK) { + let_callback *cb = let->val->data.callback; + + if (cb->decl && cb->decl->call.info) { + PSI_LibffiCallFree(cb->decl->call.info); + } + } + } + } } - free(C->context); + PSI_LibffiContextFree((void *) &C->context); } static zend_function_entry *psi_ffi_compile(PSI_Context *C) @@ -396,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] == '\\'); @@ -411,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; + } } } } @@ -428,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; }