X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Flibffi.c;h=30210cf5b329762d6c44e7c8121291159d60ed1c;hp=99f5c5fe2adfa129d6e82ee5936c5fbbcd6b3634;hb=216e7ac3b97aed5a5d65c511dc061c78be90e79d;hpb=f8b910b8bc0326683697c639288900b6a095368b diff --git a/src/libffi.c b/src/libffi.c index 99f5c5f..30210cf 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -137,8 +137,7 @@ static ffi_type *ffi_type_sint128; static ffi_type *ffi_type_uint128; #endif -static inline ffi_type *psi_ffi_decl_arg_type(struct psi_decl_arg *darg, - struct psi_decl *fn); +static inline ffi_type *psi_ffi_decl_arg_type(struct psi_decl_arg *darg); static inline ffi_type *psi_ffi_token_type(token_t t) { switch (t) { @@ -219,7 +218,7 @@ static size_t psi_ffi_struct_type_pad(ffi_type **els, size_t padding) { size_t i; for (i = 0; i < padding; ++i) { - ffi_type *pad = malloc(sizeof(*pad)); + ffi_type *pad = pemalloc(sizeof(*pad), 1); memcpy(pad, &ffi_type_schar, sizeof(*pad)); *els++ = pad; @@ -238,9 +237,10 @@ struct psi_ffi_struct_element_storage { }; static inline void psi_ffi_struct_type_element( - struct psi_ffi_struct_element_storage *s, struct psi_decl_arg *darg) { + struct psi_ffi_struct_element_storage *s, struct psi_decl_arg *darg, + ffi_type *darg_type) { - ffi_type *type, **tmp; + ffi_type *type; size_t padding; if (darg->layout->pos == s->last_arg_pos) { @@ -249,8 +249,8 @@ static inline void psi_ffi_struct_type_element( } s->last_arg_pos = darg->layout->pos; - type = malloc(sizeof(*type)); - *type = *psi_ffi_decl_arg_type(darg, NULL); + type = pemalloc(sizeof(*type), 1); + *type = *darg_type; if (type->alignment > s->max_align) { s->max_align = type->alignment; @@ -260,13 +260,7 @@ static inline void psi_ffi_struct_type_element( if ((padding = psi_offset_padding(darg->layout->pos - s->offset, type->alignment))) { if (s->nels + padding + 1 > s->argc) { s->argc += padding; - tmp = realloc(s->els, (s->argc + 1) * sizeof(*s->els)); - if (tmp) { - s->els = tmp; - } else { - free(s->els); - abort(); - } + s->els = safe_perealloc(s->els, (s->argc + 1), sizeof(*s->els), 0, 1); s->els[s->argc] = NULL; } psi_ffi_struct_type_pad(&s->els[s->nels], padding); @@ -281,16 +275,15 @@ static inline void psi_ffi_struct_type_element( static ffi_type **psi_ffi_struct_type_elements(struct psi_decl_struct *strct) { size_t i = 0; - ffi_type **tmp; struct psi_decl_arg *darg; struct psi_ffi_struct_element_storage s = {0}; s.last_arg_pos = -1; s.argc = psi_plist_count(strct->args); - s.els = calloc(s.argc + 1, sizeof(*s.els)); + s.els = pecalloc(s.argc + 1, sizeof(*s.els), 1); while (psi_plist_get(strct->args, i++, &darg)) { - psi_ffi_struct_type_element(&s, darg); + psi_ffi_struct_type_element(&s, darg, psi_ffi_decl_arg_type(darg)); } /* apply struct alignment padding */ @@ -300,13 +293,7 @@ static ffi_type **psi_ffi_struct_type_elements(struct psi_decl_struct *strct) { if (s.offset < strct->size) { /* WTF? */ size_t padding = strct->size - s.offset; - tmp = realloc(s.els, (padding + s.argc + 1) * sizeof(*s.els)); - if (tmp) { - s.els = tmp; - } else { - free(s.els); - return NULL; - } + s.els = safe_perealloc(s.els, (padding + s.argc + 1), sizeof(*s.els), 0, 1); psi_ffi_struct_type_pad(&s.els[s.nels], padding); s.els[s.argc + padding] = NULL; } @@ -324,7 +311,7 @@ static inline ffi_type *psi_ffi_decl_type(struct psi_decl_type *type) { switch (real->type) { case PSI_T_STRUCT: if (!real->real.strct->engine.type) { - ffi_type *strct = calloc(1, sizeof(ffi_type)); + ffi_type *strct = pecalloc(1, sizeof(ffi_type), 1); strct->type = FFI_TYPE_STRUCT; strct->size = 0; @@ -340,7 +327,7 @@ static inline ffi_type *psi_ffi_decl_type(struct psi_decl_type *type) { { struct psi_decl_arg *arg; psi_plist_get(real->real.unn->args, 0, &arg); - return psi_ffi_decl_arg_type(arg, NULL); + return psi_ffi_decl_arg_type(arg); } default: @@ -354,32 +341,56 @@ static inline ffi_type *psi_ffi_decl_func_array_type(struct psi_decl *fn) { struct psi_ffi_decl_info *info = fn->info; struct psi_ffi_struct_element_storage s = {0}; struct psi_layout l; + ffi_type *type; size_t i; + if (info->rv_array) { + return info->rv_array; + } + s.last_arg_pos = -1; s.argc = fn->func->var->array_size; - s.els = calloc(s.argc + 1, sizeof(*s.els)); + s.els = pecalloc(s.argc + 1, sizeof(*s.els), 1); + + info->rv_array = pecalloc(1, sizeof(ffi_type), 1); + info->rv_array->type = FFI_TYPE_STRUCT; + info->rv_array->size = 0; + info->rv_array->elements = s.els; - assert(!fn->func->layout); l.pos = 0; - l.len = psi_decl_arg_get_size(fn->func); + if (fn->func->var->pointer_level > 1) { + l.len = SIZEOF_VOID_P; + type = &ffi_type_pointer; + } else { + l.len = psi_decl_type_get_size(fn->func->type, NULL); + type = psi_ffi_decl_type(fn->func->type); + } + assert(!fn->func->layout); fn->func->layout = &l; - psi_ffi_struct_type_element(&s, fn->func); + for (i = 0; i < fn->func->var->array_size; ++i) { + psi_ffi_struct_type_element(&s, fn->func, type); + info->rv_array->elements = s.els; + l.pos += l.len; + } fn->func->layout = NULL; - info->rv_array = calloc(1, sizeof(ffi_type)); - info->rv_array->type = FFI_TYPE_STRUCT; - info->rv_array->size = 0; - info->rv_array->elements = s.els; - return info->rv_array; } -static inline ffi_type *psi_ffi_decl_arg_type(struct psi_decl_arg *darg, - struct psi_decl *fn) { +static inline ffi_type *psi_ffi_decl_arg_type(struct psi_decl_arg *darg) { if (darg->var->pointer_level) { - if (darg->var->array_size && fn) { + return &ffi_type_pointer; + } else { + return psi_ffi_decl_type(darg->type); + } +} + +static inline ffi_type *psi_ffi_decl_func_type(struct psi_decl *fn) { + struct psi_decl_arg *darg = fn->func; + + if (darg->var->pointer_level) { + if (darg->var->array_size) { /* mimic a struct resembling the array return type of fn */ return psi_ffi_decl_func_array_type(fn); } @@ -389,15 +400,15 @@ static inline ffi_type *psi_ffi_decl_arg_type(struct psi_decl_arg *darg, } } -static inline ffi_abi psi_ffi_abi(const char *convention) { +static inline ffi_abi psi_ffi_abi(zend_string *convention) { if (FFI_LAST_ABI - 2 != FFI_FIRST_ABI) { #ifdef HAVE_FFI_STDCALL - if (!strcasecmp(convention, "stdcall")) { + if (zend_string_equals_literal(convention, "stdcall")) { return FFI_STDCALL; } #endif #ifdef HAVE_FFI_FASTCALL - if (!strcasecmp(convention, "fastcall")) { + if (zend_string_equals_literal(convention, "fastcall")) { return FFI_FASTCALL; } #endif @@ -410,17 +421,17 @@ static inline struct psi_ffi_decl_info *psi_ffi_decl_init(struct psi_decl *decl) int rc; size_t i, c = psi_plist_count(decl->args); struct psi_decl_arg *arg; - struct psi_ffi_decl_info *info = calloc(1, sizeof(*info) + 2 * c * sizeof(void *)); + struct psi_ffi_decl_info *info = pecalloc(1, sizeof(*info) + 2 * c * sizeof(void *), 1); decl->info = info; for (i = 0; psi_plist_get(decl->args, i, &arg); ++i) { - info->params[i] = psi_ffi_decl_arg_type(arg, NULL); + info->params[i] = psi_ffi_decl_arg_type(arg); } info->params[c] = NULL; rc = ffi_prep_cif(&info->signature, psi_ffi_abi(decl->abi->convention), - c, psi_ffi_decl_arg_type(decl->func, decl), info->params); + c, psi_ffi_decl_func_type(decl), info->params); if (FFI_OK != rc) { free(info); @@ -483,7 +494,7 @@ static inline void psi_ffi_callback_init(struct psi_ffi_impl_info *impl_info, decl_info = psi_ffi_decl_init(cb->decl); } - cb_info = calloc(1, sizeof(*cb_info)); + cb_info = pecalloc(1, sizeof(*cb_info), 1); cb_info->impl_info = impl_info; cb_info->let_exp = let_exp; rc = psi_ffi_prep_closure(&cb_info->closure, &cb_info->code, @@ -561,7 +572,7 @@ static inline void psi_ffi_callback_dtor(struct psi_let_exp *let_exp) { static inline struct psi_ffi_impl_info *psi_ffi_impl_init(struct psi_impl *impl, struct psi_context *C) { struct psi_ffi_context *context = C->context; - struct psi_ffi_impl_info *info = calloc(1, sizeof(*info)); + struct psi_ffi_impl_info *info = pecalloc(1, sizeof(*info), 1); struct psi_let_stmt *let; ffi_status rc; size_t l = 0; @@ -628,8 +639,7 @@ struct psi_ffi_extvar_info { }; static inline ffi_status psi_ffi_extvar_init(struct psi_decl_extvar *evar) { - struct psi_ffi_extvar_info *info = calloc(1, sizeof(*info)); - ffi_type *type; + struct psi_ffi_extvar_info *info = pecalloc(1, sizeof(*info), 1); ffi_status rc; evar->info = info; @@ -637,10 +647,8 @@ static inline ffi_status psi_ffi_extvar_init(struct psi_decl_extvar *evar) { psi_ffi_decl_init(evar->getter); psi_ffi_decl_init(evar->setter); - type = psi_ffi_decl_arg_type(evar->arg, evar->getter); - rc = ffi_prep_cif(&info->get.signature, FFI_DEFAULT_ABI, 0, - type, NULL); + psi_ffi_decl_func_type(evar->getter), NULL); if (FFI_OK != rc) { return rc; } @@ -650,7 +658,7 @@ static inline ffi_status psi_ffi_extvar_init(struct psi_decl_extvar *evar) { return rc; } - info->set.params[0] = type; + info->set.params[0] = psi_ffi_decl_arg_type(evar->arg); rc = ffi_prep_cif(&info->set.signature, FFI_DEFAULT_ABI, 1, &ffi_type_void, info->set.params); if (FFI_OK != rc) { @@ -679,7 +687,7 @@ static inline struct psi_ffi_context *psi_ffi_context_init(struct psi_ffi_contex ffi_status rc; if (!L) { - L = malloc(sizeof(*L)); + L = pemalloc(sizeof(*L), 1); } memset(L, 0, sizeof(*L)); @@ -749,7 +757,7 @@ static zend_function_entry *psi_ffi_compile(struct psi_context *C) } if (C->impls) { - zfe = calloc(psi_plist_count(C->impls) + 1, sizeof(*zfe)); + zfe = pecalloc(psi_plist_count(C->impls) + 1, sizeof(*zfe), 1); while (psi_plist_get(C->impls, i++, &impl)) { zend_function_entry *zf = &zfe[nf]; @@ -764,7 +772,7 @@ static zend_function_entry *psi_ffi_compile(struct psi_context *C) continue; } - zf->fname = impl->func->name + (impl->func->name[0] == '\\'); + zf->fname = impl->func->name->val + (impl->func->name->val[0] == '\\'); zf->handler = ((struct psi_ffi_impl_info *) impl->info)->code; zf->num_args = psi_plist_count(impl->func->args); zf->arg_info = psi_internal_arginfo(impl); @@ -864,7 +872,7 @@ static ZEND_RESULT_CODE psi_ffi_load() #if HAVE_INT128 ffi_type *i128, *u128; - i128 = calloc(1, 3*sizeof(ffi_type)); + i128 = pecalloc(1, 3*sizeof(ffi_type), 1); i128->type = FFI_TYPE_STRUCT; i128->size = 0; i128->elements = (ffi_type **) (i128 + 1); @@ -873,7 +881,7 @@ static ZEND_RESULT_CODE psi_ffi_load() ffi_type_sint128 = i128; - u128 = calloc(1, 3*sizeof(ffi_type)); + u128 = pecalloc(1, 3*sizeof(ffi_type), 1); u128->type = FFI_TYPE_STRUCT; u128->size = 0; u128->elements = (ffi_type **) (u128 + 1);