X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-psi;a=blobdiff_plain;f=src%2Fdata.c;h=3fa456b99c4f31905a6885e75eb4db72b91a4b95;hp=9c2cefbea63cc8da9319a9362a2d971ca6b0aecf;hb=b029005e56a8913fbb3d17ab497b4a37a00a211c;hpb=9bcb1df0786a8193d65949c857baaba2f4296e84 diff --git a/src/data.c b/src/data.c index 9c2cefb..3fa456b 100644 --- a/src/data.c +++ b/src/data.c @@ -29,6 +29,7 @@ #include "php_globals.h" #include +#include struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data, psi_error_cb error, unsigned flags) @@ -58,6 +59,9 @@ struct psi_data *psi_data_ctor_with_dtors(struct psi_data *data, if (!data->decls) { data->decls = psi_plist_init((psi_plist_dtor) psi_decl_free); } + if (!data->vars) { + data->vars = psi_plist_init((psi_plist_dtor) psi_decl_extvar_free); + } if (!data->impls) { data->impls = psi_plist_init((psi_plist_dtor) psi_impl_free); } @@ -95,6 +99,9 @@ struct psi_data *psi_data_ctor(struct psi_data *data, psi_error_cb error, if (!data->decls) { data->decls = psi_plist_init(NULL); } + if (!data->vars) { + data->vars = psi_plist_init(NULL); + } if (!data->impls) { data->impls = psi_plist_init(NULL); } @@ -134,6 +141,9 @@ void psi_data_dtor(struct psi_data *data) if (data->decls) { psi_plist_free(data->decls); } + if (data->vars) { + psi_plist_free(data->vars); + } if (data->impls) { psi_plist_free(data->impls); } @@ -221,6 +231,15 @@ void psi_data_dump(int fd, struct psi_data *D) } dprintf(fd, "\n"); } + if (psi_plist_count(D->vars)) { + size_t i = 0; + struct psi_decl_extvar *evar; + + while (psi_plist_get(D->vars, i++, &evar)) { + psi_decl_extvar_dump(fd, evar); + } + dprintf(fd, "\n"); + } if (psi_plist_count(D->impls)) { size_t i = 0; struct psi_impl *impl; @@ -241,14 +260,23 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) struct psi_plist *check_structs = src->structs; struct psi_plist *check_unions = src->unions; struct psi_plist *check_enums = src->enums; + struct psi_plist *check_vars = src->vars; + struct psi_plist *check_decls = src->decls; unsigned flags = dst->flags; unsigned errors = src->errors; + struct psi_validate_stack type_stack; /* fail early if library is not found */ if (!psi_decl_file_validate(dst, src, &dlopened)) { return false; } + psi_validate_stack_ctor(&type_stack); + + if (dst->vars) { + + } + dst->flags |= PSI_SILENT; while (check_count) { @@ -256,12 +284,16 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) struct psi_plist *recheck_structs; struct psi_plist *recheck_unions; struct psi_plist *recheck_enums; + struct psi_plist *recheck_vars; + struct psi_plist *recheck_decls; size_t count_types = psi_plist_count(check_types); size_t count_structs = psi_plist_count(check_structs); size_t count_unions = psi_plist_count(check_unions); size_t count_enums = psi_plist_count(check_enums); + size_t count_vars = psi_plist_count(check_vars); + size_t count_decls = psi_plist_count(check_decls); size_t count_all = count_types + count_structs + count_unions - + count_enums; + + count_enums + count_vars + count_decls; if (check_count == count_all) { /* nothing changed; bail out */ @@ -280,6 +312,8 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) recheck_structs = count_structs ? psi_plist_init(NULL) : NULL; recheck_unions = count_unions ? psi_plist_init(NULL) : NULL; recheck_enums = count_enums ? psi_plist_init(NULL) : NULL; + recheck_vars = count_vars ? psi_plist_init(NULL) : NULL; + recheck_decls = count_decls ? psi_plist_init(NULL) : NULL; check_count = count_all; src->errors = errors + check_count; @@ -293,13 +327,14 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) while (psi_plist_get(check_types, i++, &def)) { *dst->last_error = 0; + dst->types = psi_plist_add(dst->types, &def); PSI_DEBUG_PRINT(dst, "PSI: validate typedef %s ", def->var->name); - if (psi_decl_arg_validate_typedef(PSI_DATA(dst), def)) { + if (psi_decl_arg_validate_typedef(PSI_DATA(dst), def, &type_stack)) { PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - dst->types = psi_plist_add(dst->types, &def); } else { PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); recheck_types = psi_plist_add(recheck_types, &def); + psi_plist_pop(dst->types, NULL); } } } @@ -311,7 +346,7 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) *dst->last_error = 0; dst->structs = psi_plist_add(dst->structs, &str); PSI_DEBUG_PRINT(dst, "PSI: validate struct %s ", str->name); - if (psi_decl_struct_validate(PSI_DATA(dst), str)) { + if (psi_decl_struct_validate(PSI_DATA(dst), str, &type_stack)) { PSI_DEBUG_PRINT(dst, "%s ::(%zu, %zu)\n", "✔", str->align, str->size); } else { PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); @@ -328,9 +363,8 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) *dst->last_error = 0; dst->unions = psi_plist_add(dst->unions, &unn); PSI_DEBUG_PRINT(dst, "PSI: validate union %s ", unn->name); - if (psi_decl_union_validate(PSI_DATA(dst), unn)) { + if (psi_decl_union_validate(PSI_DATA(dst), unn, &type_stack)) { PSI_DEBUG_PRINT(dst, "%s ::(%zu, %zu)\n", "✔", unn->align, unn->size); - } else { PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); recheck_unions = psi_plist_add(recheck_unions, &unn); @@ -354,6 +388,40 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) } } } + if (count_vars) { + size_t i = 0; + struct psi_decl_extvar *evar; + + while (psi_plist_get(check_vars, i++, &evar)) { + *dst->last_error = 0; + PSI_DEBUG_PRINT(dst, "PSI: validate extvar %s ", evar->arg->var->name); + if (psi_decl_extvar_validate(PSI_DATA(dst), evar, dlopened, &type_stack)) { + PSI_DEBUG_PRINT(dst, "%s\n", "✔"); + dst->vars = psi_plist_add(dst->vars, &evar); + dst->decls = psi_plist_add(dst->decls, &evar->getter); + dst->decls = psi_plist_add(dst->decls, &evar->setter); + } else { + PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); + recheck_vars = psi_plist_add(recheck_vars, &evar); + } + } + } + if (count_decls) { + size_t i = 0; + struct psi_decl *decl; + + while (psi_plist_get(check_decls, i++, &decl)) { + *dst->last_error = 0; + PSI_DEBUG_PRINT(dst, "PSI: validate decl %s ", decl->func->var->name); + if (psi_decl_validate(PSI_DATA(dst), decl, dlopened, &type_stack)) { + PSI_DEBUG_PRINT(dst, "%s\n", "✔"); + dst->decls = psi_plist_add(dst->decls, &decl); + } else { + PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); + recheck_decls = psi_plist_add(recheck_decls, &decl); + } + } + } } if (check_types && check_types != src->types) { @@ -372,11 +440,60 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) psi_plist_free(check_enums); } check_enums = recheck_enums; + if (check_vars && check_vars != src->vars) { + psi_plist_free(check_vars); + } + check_vars = recheck_vars; + if (check_decls && check_decls != src->decls) { + psi_plist_free(check_decls); + } + check_decls = recheck_decls; } /* reset original flags */ dst->flags = flags; + if (dst->structs) { + size_t i = 0; + struct psi_decl_struct *str; + + while (psi_plist_get(dst->structs, i++, &str)) { + size_t nlen = strlen(str->name); + size_t slen = sizeof("psi\\SIZEOF_STRUCT_"); + size_t alen = sizeof("psi\\ALIGNOF_STRUCT_"); + char *nptr = str->name, *sname, *aname; + struct psi_const *cnst; + struct psi_const_type *ctyp; + struct psi_impl_def_val *cval; + + sname = malloc(slen + nlen + 1); + strcpy(sname, "psi\\SIZEOF_STRUCT_"); + aname = malloc(alen + nlen + 1); + strcpy(aname, "psi\\ALIGNOF_STRUCT_"); + + nptr = str->name; + while (*nptr) { + size_t off = nptr - str->name; + sname[slen - 1 + off] = aname[alen - 1 + off] = toupper(*nptr++); + } + sname[slen - 1 + nlen] = aname[alen - 1 + nlen] = 0; + + ctyp = psi_const_type_init(PSI_T_INT, "int"); + cval = psi_impl_def_val_init(PSI_T_INT, NULL); + cval->ival.zend.lval = str->size; + cnst = psi_const_init(ctyp, sname, cval); + src->consts = psi_plist_add(src->consts, &cnst); + free(sname); + + ctyp = psi_const_type_init(PSI_T_INT, "int"); + cval = psi_impl_def_val_init(PSI_T_INT, NULL); + cval->ival.zend.lval = str->align; + cnst = psi_const_init(ctyp, aname, cval); + src->consts = psi_plist_add(src->consts, &cnst); + free(aname); + } + } + if (src->consts) { size_t i = 0; struct psi_const *cnst; @@ -394,23 +511,6 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) } } - if (src->decls) { - size_t i = 0; - struct psi_decl *decl; - - while (psi_plist_get(src->decls, i++, &decl)) { - *dst->last_error = 0; - PSI_DEBUG_PRINT(dst, "PSI: validate decl %s ", decl->func->var->name); - if (psi_decl_validate(PSI_DATA(dst), decl, dlopened)) { - PSI_DEBUG_PRINT(dst, "%s\n", "✔"); - dst->decls = psi_plist_add(dst->decls, &decl); - } else { - PSI_DEBUG_PRINT(dst, "%s (%s)\n", "✘", dst->last_error); - ++src->errors; - } - } - } - if (src->impls) { size_t i = 0; struct psi_impl *impl; @@ -428,6 +528,8 @@ bool psi_data_validate(struct psi_data *dst, struct psi_data *src) } } + psi_validate_stack_dtor(&type_stack); + return true; }