From 9bd48d16d68944f3a1e9366fe8c6f3c6d985bf56 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 28 Jan 2016 17:41:04 +0100 Subject: [PATCH] flush --- m4/psi_type.m4 | 5 ++ src/context.c | 3 +- src/context_dump.c | 7 ++- src/context_validate.c | 109 +++++++++++++++++++++++++++++++---------- src/engine.c | 7 +++ src/parser.h | 89 ++++++++++++++++----------------- src/parser_proc.y | 89 ++++++++++++++++++++------------- 7 files changed, 198 insertions(+), 111 deletions(-) diff --git a/m4/psi_type.m4 b/m4/psi_type.m4 index 21484ad..050f805 100644 --- a/m4/psi_type.m4 +++ b/m4/psi_type.m4 @@ -205,25 +205,30 @@ AC_DEFUN(PSI_CHECK_STD_TYPES, [ AC_CHECK_ALIGNOF(long double) PSI_STDTYPE(char, int) + AC_CHECK_ALIGNOF(char) PSI_STDTYPE(signed char, int) PSI_STDTYPE(unsigned char, uint) PSI_STDTYPE(short, int) + AC_CHECK_ALIGNOF(short) PSI_STDTYPE(short int, int) PSI_STDTYPE(signed short, int) PSI_STDTYPE(signed short int, int) PSI_STDTYPE(unsigned short, uint) PSI_STDTYPE(unsigned short int, uint) PSI_STDTYPE(int, int) + AC_CHECK_ALIGNOF(int) PSI_STDTYPE(signed int, int) PSI_STDTYPE(signed, int) PSI_STDTYPE(unsigned int, uint) PSI_STDTYPE(unsigned, uint) PSI_STDTYPE(long, int) + AC_CHECK_ALIGNOF(long) PSI_STDTYPE(long int, int) PSI_STDTYPE(signed long int, int) PSI_STDTYPE(unsigned long, uint) PSI_STDTYPE(unsigned long int, uint) PSI_STDTYPE(long long, int) + AC_CHECK_ALIGNOF(long long) PSI_STDTYPE(signed long long, int) PSI_STDTYPE(signed long long int, int) PSI_STDTYPE(unsigned long long, uint) diff --git a/src/context.c b/src/context.c index 3fe6c3f..d1c1655 100644 --- a/src/context.c +++ b/src/context.c @@ -66,7 +66,8 @@ PSI_Context *PSI_ContextInit(PSI_Context *C, PSI_ContextOps *ops, PSI_ContextErr for (predef_type = &psi_predef_types[0]; predef_type->type_tag; ++predef_type) { decl_type *type = init_decl_type(predef_type->type_tag, predef_type->type_name); - decl_typedef *def = init_decl_typedef(predef_type->alias, type); + decl_var *var = init_decl_var(predef_type->alias, 0, 0); /* FIXME: indirection */ + decl_arg *def = init_decl_arg(type, var); T.defs = add_decl_typedef(T.defs, def); } diff --git a/src/context_dump.c b/src/context_dump.c index cb1825f..708b36f 100644 --- a/src/context_dump.c +++ b/src/context_dump.c @@ -111,18 +111,21 @@ static inline void dump_impl_set_value(int fd, set_value *set, unsigned level, i } } -static inline void dump_typedef(int fd, decl_typedef *tdef) { +static inline void dump_typedef(int fd, decl_arg *tdef) { dprintf(fd, "typedef "); + dump_decl_arg(fd, tdef); + /* dump_decl_type(fd, tdef->type); dprintf(fd, " %s%s;", tdef->type->type == PSI_T_POINTER ? "*":"", tdef->alias); + */ } static inline void dump_typedefs(int fd, decl_typedefs *defs) { size_t i; for (i = 0; i < defs->count; ++i) { - decl_typedef *tdef = defs->list[i]; + decl_arg *tdef = defs->list[i]; dump_typedef(fd, tdef); dprintf(fd, "\n"); diff --git a/src/context_validate.c b/src/context_validate.c index 6a89d6e..7c7a245 100644 --- a/src/context_validate.c +++ b/src/context_validate.c @@ -48,10 +48,10 @@ static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) { if (type->real) { return 1; } - for (i = 0; i < defs->count; ++i) { - decl_typedef *def = defs->list[i]; + if (defs) for (i = 0; i < defs->count; ++i) { + decl_arg *def = defs->list[i]; - if (def->type->type != type->type && !strcmp(def->alias, type->name)) { + if (def->type->type != type->type && !strcmp(def->var->name, type->name)) { type->real = def->type; return 1; } @@ -72,7 +72,7 @@ static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type if (type->strct) { return 1; } - for (i = 0; i < structs->count; ++i) { + if (structs) for (i = 0; i < structs->count; ++i) { if (!strcmp(structs->list[i]->name, type->name)) { type->strct = structs->list[i]; return 1; @@ -87,7 +87,7 @@ static inline int locate_decl_type_enum(decl_enums *enums, decl_type *type) { if (type->enm) { return 1; } - for (i = 0; i < enums->count; ++i) { + if (enums) for (i = 0; i < enums->count; ++i) { if (!strcmp(enums->list[i]->name, type->name)) { type->enm = enums->list[i]; return 1; @@ -103,7 +103,7 @@ static inline int validate_decl_type(PSI_Data *data, decl_type *type) { case PSI_T_INT: case PSI_T_LONG: case PSI_T_NAME: - if (!data->defs || !locate_decl_type_alias(data->defs, type)) { + if (!locate_decl_type_alias(data->defs, type)) { return 0; } if (type->real) { @@ -111,25 +111,25 @@ static inline int validate_decl_type(PSI_Data *data, decl_type *type) { } return 1; case PSI_T_STRUCT: - if (!data->structs || !locate_decl_type_struct(data->structs, type)) { + if (!locate_decl_type_struct(data->structs, type)) { return 0; } break; case PSI_T_ENUM: - if (!data->enums || !locate_decl_type_enum(data->enums, type)) { + if (!locate_decl_type_enum(data->enums, type)) { return 0; } } return 1; } -static inline int validate_decl_typedef(PSI_Data *data, decl_typedef *def) { +static inline int validate_decl_typedef(PSI_Data *data, decl_arg *def) { if (!validate_decl_type(data, def->type)) { data->error(def->token, PSI_WARNING, "Type '%s' cannot be aliased to %s'%s'", - def->type->name, def->type->type == PSI_T_STRUCT?"struct ":"",def->alias); + def->type->name, def->type->type == PSI_T_STRUCT?"struct ":"", + def->var->name); return 0; } - /* FIXME: check def->alias */ return 1; } @@ -230,7 +230,17 @@ static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) { t = real_decl_type(darg->type)->type; } - size = psi_t_size(t) * (darg->var->array_size ?: 1); + switch (t) { + case PSI_T_STRUCT: + if (!validate_decl_struct(data, real_decl_type(darg->type)->strct)) { + return 0; + } + size = real_decl_type(darg->type)->strct->size; + break; + default: + size = psi_t_size(t) * (darg->var->array_size ?: 1); + break; + } if (i) { decl_arg *last = s->args->args[i-1]; @@ -935,6 +945,7 @@ static inline int validate_impl_args(PSI_Data *data, impl *impl) { return 1; } + static inline int validate_impl(PSI_Data *data, impl *impl) { if (!validate_impl_args(data, impl)) { return 0; @@ -947,41 +958,89 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) { PSI_Data *D; void *dlopened = NULL; - size_t count = C->count++; + size_t i, count = C->count++, check_round, check_count; + decl_typedefs *check_defs = P->defs; + decl_structs *check_structs = P->structs; + decl_enums *check_enums = P->enums; C->data = realloc(C->data, C->count * sizeof(*C->data)); D = PSI_DataExchange(&C->data[count], PSI_DATA(P)); - +/* if (D->defs) { - size_t i; - for (i = 0; i < D->defs->count; ++i) { if (validate_decl_typedef(PSI_DATA(C), D->defs->list[i])) { C->defs = add_decl_typedef(C->defs, D->defs->list[i]); + } else { + check_defs = add_decl_typedef(check_defs, D->defs->list[i]); } } } if (D->structs) { - size_t i; - for (i = 0; i < D->structs->count; ++i) { if (validate_decl_struct(PSI_DATA(C), D->structs->list[i])) { C->structs = add_decl_struct(C->structs, D->structs->list[i]); + } else { + check_structs = add_decl_struct(check_structs, D->structs->list[i]); } } } if (D->enums) { - size_t i; - for (i = 0; i < D->enums->count; ++i) { if (validate_decl_enum(PSI_DATA(C), D->enums->list[i])) { C->enums = add_decl_enum(C->enums, D->enums->list[i]); + } else { + check_enums = add_decl_enum(check_enums, D->enums->list[i]); } } } - if (D->consts) { - size_t i; +*/ +#define REVALIDATE(what) do { \ + if (check_round && check_ ##what) { \ + free(check_ ##what->list); \ + free(check_ ##what); \ + } \ + check_ ##what = recheck_ ##what; \ +} while (0) +#define CHECK_TOTAL (CHECK_COUNT(defs) + CHECK_COUNT(structs) + CHECK_COUNT(enums)) +#define CHECK_COUNT(of) (check_ ##of ? check_ ##of->count : 0) + + for (check_round = 0, check_count = 0; CHECK_TOTAL && check_count != CHECK_TOTAL; ++check_round) { + decl_typedefs *recheck_defs = NULL; + decl_structs *recheck_structs = NULL; + decl_enums *recheck_enums = NULL; + + check_count = CHECK_TOTAL; + fprintf(stderr, "### Validation round %zu with %zu checks\n", check_round, check_count); + + for (i = 0; i < CHECK_COUNT(defs); ++i) { + if (validate_decl_typedef(PSI_DATA(C), check_defs->list[i])) { + C->defs = add_decl_typedef(C->defs, check_defs->list[i]); + } else { + recheck_defs = add_decl_typedef(recheck_defs, check_defs->list[i]); + } + } + for (i = 0; i < CHECK_COUNT(structs); ++i) { + if (validate_decl_struct(PSI_DATA(C), check_structs->list[i])) { + C->structs = add_decl_struct(C->structs, check_structs->list[i]); + } else { + recheck_structs = add_decl_struct(recheck_structs, check_structs->list[i]); + } + } + for (i = 0; i < CHECK_COUNT(enums); ++i) { + if (validate_decl_enum(PSI_DATA(C), check_enums->list[i])) { + C->enums = add_decl_enum(C->enums, check_enums->list[i]); + } else { + recheck_enums = add_decl_enum(recheck_enums, check_enums->list[i]); + } + } + REVALIDATE(defs); + REVALIDATE(structs); + REVALIDATE(enums); + } + + + if (D->consts) { for (i = 0; i < D->consts->count; ++i) { if (validate_constant(PSI_DATA(C), D->consts->list[i])) { C->consts = add_constant(C->consts, D->consts->list[i]); @@ -996,8 +1055,6 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) add_decl_lib(&C->psi.libs, dlopened); if (D->decls) { - size_t i; - for (i = 0; i < D->decls->count; ++i) { if (validate_decl(PSI_DATA(C), dlopened, D->decls->list[i])) { C->decls = add_decl(C->decls, D->decls->list[i]); @@ -1005,8 +1062,6 @@ int PSI_ContextValidate(PSI_Context *C, PSI_Parser *P) } } if (D->impls) { - size_t i; - for (i = 0; i < D->impls->count; ++i) { if (validate_impl(PSI_DATA(C), D->impls->list[i])) { C->impls = add_impl(C->impls, D->impls->list[i]); @@ -1023,7 +1078,7 @@ int PSI_ContextValidateData(PSI_Data *dest, PSI_Data *source) int errors = 0; if (source->defs) for (i = 0; i < source->defs->count; ++i) { - decl_typedef *def = source->defs->list[i]; + decl_arg *def = source->defs->list[i]; if (validate_decl_typedef(source, def)) { if (dest) { diff --git a/src/engine.c b/src/engine.c index c3e95c5..d14bac7 100644 --- a/src/engine.c +++ b/src/engine.c @@ -28,7 +28,11 @@ size_t psi_t_alignment(token_t t) case PSI_T_DOUBLE: return ALIGNOF_DOUBLE; case PSI_T_POINTER: + case PSI_T_FUNCTION: + case PSI_T_STRUCT: return ALIGNOF_VOID_P; + case PSI_T_ENUM: + return ALIGNOF_INT; EMPTY_SWITCH_DEFAULT_CASE(); } return 0; @@ -51,7 +55,10 @@ size_t psi_t_size(token_t t) case PSI_T_DOUBLE: return SIZEOF_DOUBLE; case PSI_T_POINTER: + case PSI_T_FUNCTION: return SIZEOF_VOID_P; + case PSI_T_ENUM: + return SIZEOF_INT; EMPTY_SWITCH_DEFAULT_CASE(); } return 0; diff --git a/src/parser.h b/src/parser.h index 41741c0..0f5671d 100644 --- a/src/parser.h +++ b/src/parser.h @@ -27,6 +27,8 @@ typedef struct PSI_Token { char buf[1]; } PSI_Token; +static inline PSI_Token *PSI_TokenCopy(PSI_Token *src); + typedef union impl_val { char cval; int8_t i8; @@ -78,60 +80,18 @@ static inline decl_type *real_decl_type(decl_type *type) { return type; } +static inline void free_decl(struct decl *decl); static inline void free_decl_type(decl_type *type) { if (type->token) { free(type->token); } + if (type->type == PSI_T_FUNCTION) { + free_decl(type->func); + } free(type->name); free(type); } -typedef struct decl_typedef { - PSI_Token *token; - char *alias; - decl_type *type; -} decl_typedef; - -static inline decl_typedef *init_decl_typedef(const char *name, decl_type *type) { - decl_typedef *t = calloc(1, sizeof(*t)); - t->alias = strdup(name); - t->type = type; - return t; -} - -static inline void free_decl_typedef(decl_typedef *t) { - if (t->token) { - free(t->token); - } - free(t->alias); - free_decl_type(t->type); - free(t); -} - -typedef struct decl_typedefs { - size_t count; - decl_typedef **list; -} decl_typedefs; - -static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_typedef *def) { - if (!defs) { - defs = calloc(1, sizeof(*defs)); - } - defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list)); - defs->list[defs->count-1] = def; - return defs; -} - -static void free_decl_typedefs(decl_typedefs *defs) { - size_t i; - - for (i = 0; i < defs->count; ++i) { - free_decl_typedef(defs->list[i]); - } - free(defs->list); - free(defs); -} - typedef struct decl_var { PSI_Token *token; char *name; @@ -148,6 +108,17 @@ static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as return v; } +static inline decl_var *copy_decl_var(decl_var *src) { + decl_var *dest = calloc(1, sizeof(*dest)); + + memcpy(dest, src, sizeof(*dest)); + dest->name = strdup(dest->name); + if (dest->token) { + dest->token = PSI_TokenCopy(dest->token); + } + return dest; +} + static inline void free_decl_var(decl_var *var) { if (var->token) { free(var->token); @@ -203,6 +174,30 @@ static inline void free_decl_arg(decl_arg *arg) { free(arg); } +typedef struct decl_typedefs { + size_t count; + decl_arg **list; +} decl_typedefs; + +static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) { + if (!defs) { + defs = calloc(1, sizeof(*defs)); + } + defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list)); + defs->list[defs->count-1] = def; + return defs; +} + +static void free_decl_typedefs(decl_typedefs *defs) { + size_t i; + + for (i = 0; i < defs->count; ++i) { + free_decl_arg(defs->list[i]); + } + free(defs->list); + free(defs); +} + typedef struct decl_vars { decl_var **vars; size_t count; @@ -641,7 +636,6 @@ static inline num_exp *init_num_exp(token_t t, void *num) { return exp; } -static inline PSI_Token *PSI_TokenCopy(PSI_Token *src); static inline num_exp *copy_num_exp(num_exp *exp) { decl_var *dvar; num_exp *num = calloc(1, sizeof(*num)); @@ -1511,6 +1505,7 @@ static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) { return T; } +char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen); static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) { php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to))); return T; diff --git a/src/parser_proc.y b/src/parser_proc.y index ac856ed..e488c0e 100644 --- a/src/parser_proc.y +++ b/src/parser_proc.y @@ -61,6 +61,9 @@ block ::= decl_typedef(def). { if (def->type->strct) { P->structs = add_decl_struct(P->structs, def->type->strct); } + if (def->type->enm) { + P->enums = add_decl_enum(P->enums, def->type->enm); + } } block ::= constant(constant). { P->consts = add_constant(P->consts, constant); @@ -90,7 +93,6 @@ enum_name(n) ::= ENUM(E) optional_name(N). { } } - %type decl_enum {decl_enum *} %destructor decl_enum {free_decl_enum($$);} decl_enum(e) ::= enum_name(N) LBRACE decl_enum_items(list) RBRACE. { @@ -176,47 +178,72 @@ constant(constant) ::= CONST const_type(type) NSNAME(T) EQUALS impl_def_val(val) free(T); } -%type decl_typedef {decl_typedef*} -%destructor decl_typedef {free_decl_typedef($$);} -decl_typedef(def) ::= TYPEDEF decl_typedef_body(def_) EOS. { +%type decl_typedef {decl_arg*} +%destructor decl_typedef { + free_decl_arg($$); + if ($$->type->strct) { + free_decl_struct($$->type->strct); + } + if ($$->type->enm) { + free_decl_enum($$->type->enm); + } + if ($$->type->func) { + free_decl($$->type->func); + } +} +decl_typedef(def) ::= TYPEDEF(T) decl_typedef_body(def_) EOS. { def = def_; + def->token = T; } -%type decl_typedef_body_ex {decl_typedef*} -%destructor decl_typedef_body_ex {free_decl_typedef($$);} -decl_typedef_body_ex(def) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) NAME(ALIAS). { - def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_STRUCT, N->text)); - def->token = ALIAS; +%type decl_typedef_body_ex {decl_arg*} +%destructor decl_typedef_body_ex { + free_decl_arg($$); + if ($$->type->strct) { + free_decl_struct($$->type->strct); + } + if ($$->type->enm) { + free_decl_enum($$->type->enm); + } + if ($$->type->func) { + free_decl($$->type->func); + } +} +decl_typedef_body_ex(def) ::= struct_name(N) struct_size(size_) decl_struct_args_block(args) decl_var(var). { + def = init_decl_arg(init_decl_type(PSI_T_STRUCT, N->text), var); def->type->token = PSI_TokenCopy(N); def->type->strct = init_decl_struct(N->text, args); def->type->strct->token = N; def->type->strct->size = size_; } decl_typedef_body_ex(def) ::= decl_enum(e) NAME(ALIAS). { - def = init_decl_typedef(ALIAS->text, init_decl_type(PSI_T_ENUM, e->name)); + def = init_decl_arg(init_decl_type(PSI_T_ENUM, e->name), init_decl_var(ALIAS->text, 0, 0)); + def->var->token = ALIAS; def->type->token = PSI_TokenCopy(e->token); - def->token = ALIAS; def->type->enm = e; } -%type decl_typedef_body {decl_typedef*} -%destructor decl_typedef_body {free_decl_typedef($$);} +%type decl_typedef_body {decl_arg*} +%destructor decl_typedef_body { + free_decl_arg($$); + if ($$->type->strct) { + free_decl_struct($$->type->strct); + } + if ($$->type->enm) { + free_decl_enum($$->type->enm); + } + if ($$->type->func) { + free_decl($$->type->func); + } +} decl_typedef_body(def) ::= decl_typedef_body_ex(def_). { def = def_; } -decl_typedef_body(def) ::= decl_type(type) NAME(ALIAS). { - def = init_decl_typedef(ALIAS->text, type); - def->token = ALIAS; -} -/* support opaque types */ -decl_typedef_body(def) ::= VOID(V) indirection(i) NAME(ALIAS). { - def = init_decl_typedef(ALIAS->text, init_decl_type(i?PSI_T_POINTER:V->type, V->text)); - def->token = ALIAS; - def->type->token = V; +decl_typedef_body(def) ::= decl_func(func_) LPAREN decl_args(args) RPAREN. { + def = init_decl_arg(init_decl_type(PSI_T_FUNCTION, func_->var->name), copy_decl_var(func_->var)); + def->type->token = PSI_TokenCopy(func_->token); + def->type->func = init_decl(init_decl_abi("default"), func_, args); } -decl_typedef_body(def) ::= decl_func(func) LPAREN decl_args(args) RPAREN. { - def = init_decl_typedef(func->var->name, init_decl_type(PSI_T_FUNCTION, func->var->name)); - def->type->token = PSI_TokenCopy(func->token); - def->type->func = init_decl(init_decl_abi("default"), func, args); - def->token = PSI_TokenCopy(func->token); +decl_typedef_body(def) ::= decl_arg(arg). { + def = arg; } %type decl {decl*} @@ -237,7 +264,6 @@ decl_func(func) ::= VOID(T) NAME(N). { init_decl_var(N->text, 0, 0) ); func->type->token = T; - //free(T); free(N); } @@ -319,12 +345,7 @@ struct_args(args) ::= struct_args(args_) struct_arg(arg). { %type struct_arg {decl_arg*} %destructor struct_arg {free_decl_arg($$);} struct_arg(arg_) ::= decl_typedef_body_ex(def) EOS. { - arg_ = init_decl_arg(def->type, init_decl_var(def->alias, 0, 0)); - arg_->var->arg = arg_; - arg_->token = PSI_TokenCopy(def->type->token); - arg_->var->token = def->token; - free(def->alias); - free(def); + arg_ = def; } struct_arg(arg) ::= decl_arg(arg_) struct_layout(layout_) EOS. { arg_->layout = layout_; -- 2.30.2