From: Michael Wallner Date: Thu, 19 Nov 2015 07:23:56 +0000 (+0100) Subject: cleanup X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=7a717dad32d06fe5273ad3a9ce755908723f6685;p=m6w6%2Fext-psi cleanup --- diff --git a/config.m4 b/config.m4 index 71ac862..77373a8 100644 --- a/config.m4 +++ b/config.m4 @@ -31,6 +31,7 @@ if test "$PHP_PSI" != "no"; then AC_MSG_RESULT($PSI_cv_LIBFFI_DIR) PHP_EVAL_INCLINE(`$PKG_CONFIG --cflags libffi`) PHP_EVAL_LIBLINE(`$PKG_CONFIG --libs libffi`, PSI_SHARED_LIBADD) + AC_DEFINE(HAVE_LIBFFI, 1, Have libffi) else AC_CACHE_CHECK(for libffi, PSI_cv_LIBFFI_DIR, [ for PSI_cv_LIBFFI_DIR in $PHP_PSI_LIBFFI {/usr{,/local},/opt}{,/libffi} @@ -45,6 +46,7 @@ if test "$PHP_PSI" != "no"; then then PHP_ADD_INCLUDE($PSI_cv_LIBFFI_DIR/include/ffi) PHP_ADD_LIBRARY_WITH_PATH(ffi, $PSI_cv_LIBFFI_DIR/$PHP_LIBDIR, PSI_SHARED_LIBADD) + AC_DEFINE(HAVE_LIBFFI, 1, Have libffi) else AC_MSG_WARN([Could not find libffi, please provide the base install path]) fi @@ -76,6 +78,7 @@ if test "$PHP_PSI" != "no"; then then PHP_ADD_INCLUDE($PSI_cv_LIBJIT_DIR/include) PHP_ADD_LIBRARY_WITH_PATH(jit, $PSI_cv_LIBJIT_DIR/$PHP_LIBDIR, PSI_SHARED_LIBADD) + AC_DEFINE(HAVE_LIBJIT, 1, Have libjit) else AC_MSG_WARN([Could not find libjit, please provide the base install path]) fi diff --git a/src/compiler.c b/src/compiler.c deleted file mode 100644 index 3181aea..0000000 --- a/src/compiler.c +++ /dev/null @@ -1,41 +0,0 @@ -#include - -#include - -#include -#include - -#include "compiler.h" - -PSI_Compiler *PSI_CompilerInit(PSI_Compiler *C, PSI_Validator *V, void *context) -{ - if (!C) { - C = malloc(sizeof(*C)); - } - memset(C, 0, sizeof(*C)); - - PSI_DataExchange((PSI_Data *) C, (PSI_Data *) V); - - C->context = context; - - return C; -} - -void PSI_CompilerDtor(PSI_Compiler *C) -{ - PSI_DataDtor((PSI_Data *) C); -} - -void PSI_Compiler_Free(PSI_Compiler **C) -{ - if (*C) { - PSI_CompilerDtor(*C); - free(*C); - *C = NULL; - } -} - - -zend_function_entry *PSI_CompilerCompile(PSI_Compiler *C) -{ -} diff --git a/src/compiler.h b/src/compiler.h deleted file mode 100644 index fcf2cf6..0000000 --- a/src/compiler.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _PSI_COMPILER_H -#define _PSI_COMPILER_H - -#include "validator.h" - -typedef struct PSI_Compiler { - PSI_DATA_MEMBERS; - void *context; -} PSI_Compiler; - -PSI_Compiler *PSI_CompilerInit(PSI_Compiler *C, PSI_Validator *V, void *context); -void PSI_CompilerDtor(PSI_Compiler *C); -void PSI_CompilerFree(PSI_Compiler **C); -zend_function_entry *PSI_CompilerCompile(PSI_Compiler *C); - -#endif diff --git a/src/libffi.c b/src/libffi.c index d802bd1..bb1f34f 100644 --- a/src/libffi.c +++ b/src/libffi.c @@ -1,4 +1,11 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "php.h" + +#ifdef HAVE_LIBFFI + #include "php_psi.h" #include "libffi.h" @@ -257,3 +264,5 @@ PSI_ContextOps *PSI_Libffi(void) { return &ops; } + +#endif /* HAVE_LIBFFI */ diff --git a/src/libffi.h b/src/libffi.h index e8b0553..4b36b30 100644 --- a/src/libffi.h +++ b/src/libffi.h @@ -3,6 +3,8 @@ #include "context.h" +#ifdef HAVE_LIBFFI PSI_ContextOps *PSI_Libffi(void); +#endif #endif diff --git a/src/libjit.c b/src/libjit.c index 736b54d..6e2760d 100644 --- a/src/libjit.c +++ b/src/libjit.c @@ -1,4 +1,11 @@ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include "php.h" + +#ifdef HAVE_LIBJIT + #include "php_psi.h" #include "libjit.h" @@ -217,3 +224,5 @@ PSI_ContextOps *PSI_Libjit(void) { return &ops; } + +#endif /* HAVE_LIBJIT */ diff --git a/src/libjit.h b/src/libjit.h index e5464a6..3cd4b28 100644 --- a/src/libjit.h +++ b/src/libjit.h @@ -3,6 +3,8 @@ #include "context.h" +#ifdef HAVE_LIBJIT PSI_ContextOps *PSI_Libjit(void); +#endif #endif diff --git a/src/module.c b/src/module.c index a02784c..20b25ea 100644 --- a/src/module.c +++ b/src/module.c @@ -10,13 +10,21 @@ #include "php_psi.h" #include "parser.h" -#include "libjit.h" -#include "libffi.h" +#if HAVE_LIBJIT +# include "libjit.h" +# ifndef HAVE_LIBFFI +# define PSI_ENGINE "jit" +# endif +#endif +#if HAVE_LIBFFI +# include "libffi.h" +# define PSI_ENGINE "ffi" +#endif ZEND_DECLARE_MODULE_GLOBALS(psi); PHP_INI_BEGIN() - STD_PHP_INI_ENTRY("psi.engine", "ffi", PHP_INI_SYSTEM, OnUpdateString, engine, zend_psi_globals, psi_globals) + STD_PHP_INI_ENTRY("psi.engine", PSI_ENGINE, PHP_INI_SYSTEM, OnUpdateString, engine, zend_psi_globals, psi_globals) STD_PHP_INI_ENTRY("psi.directory", "psi.d", PHP_INI_SYSTEM, OnUpdateString, directory, zend_psi_globals, psi_globals) PHP_INI_END(); @@ -629,6 +637,7 @@ static inline void psi_do_free(free_stmt *fre) f->decl->call.args[j] = &darg->let->out; } + /* FIXME: check in validate_* that free functions return scalar */ PSI_ContextCall(&PSI_G(context), &dummy, f->decl); } } @@ -709,14 +718,22 @@ void psi_call(zend_execute_data *execute_data, zval *return_value, impl *impl) PHP_MINIT_FUNCTION(psi) { - PSI_ContextOps *ops; + PSI_ContextOps *ops = NULL; REGISTER_INI_ENTRIES(); +#ifdef HAVE_LIBJIT if (!strcasecmp(PSI_G(engine), "jit")) { ops = PSI_Libjit(); - } else { + } else +#endif +#ifdef HAVE_LIBFFI ops = PSI_Libffi(); +#endif + + if (!ops) { + php_error(E_WARNING, "No PSI engine found"); + return FAILURE; } PSI_ContextInit(&PSI_G(context), ops, psi_error); diff --git a/src/validator.c b/src/validator.c deleted file mode 100644 index 128b2ac..0000000 --- a/src/validator.c +++ /dev/null @@ -1,510 +0,0 @@ -#include -#include -#include -#include -#include - -#include - -#include "php.h" -#include "php_psi.h" -#include "validator.h" - -PSI_Validator *PSI_ValidatorInit(PSI_Validator *V, PSI_Parser *P) -{ - if (!V) { - V = malloc(sizeof(*V)); - } - memset(V, 0, sizeof(*V)); - - PSI_DataExchange((PSI_Data *) V, (PSI_Data *) P); - - return V; -} - -void PSI_ValidatorDtor(PSI_Validator *V) -{ - PSI_DataDtor((PSI_Data *) V); - memset(V, 0, sizeof(*V)); -} - -void PSI_ValidatorFree(PSI_Validator **V) -{ - if (*V) { - PSI_ValidatorDtor(*V); - free(*V); - *V = NULL; - } -} - -static int validate_lib(PSI_Validator *V) { - char lib[MAXPATHLEN]; - const char *ptr = V->lib; - size_t len; - - if (!ptr) { - /* FIXME: assume stdlib */ - return 1; - } else if (!strchr(ptr, '/')) { -#ifdef DARWIN - len = snprintf(lib, MAXPATHLEN, "lib%s.dylib", ptr); -#else - len = snprintf(lib, MAXPATHLEN, "lib%s.so", ptr); -#endif - if (MAXPATHLEN == len) { - V->error(PSI_WARNING, "Library name too long: '%s'", ptr); - } - lib[len] = 0; - ptr = lib; - } - if (!(V->dlopened = dlopen(ptr, RTLD_LAZY|RTLD_LOCAL))) { - V->error(PSI_WARNING, "Could not open library '%s': %s.", V->lib, dlerror()); - return 0; - } - return 1; -} - -static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) { - size_t i; - - if (type->real) { - return 1; - } - for (i = 0; i < defs->count; ++i) { - if (!strcmp(defs->list[i]->alias, type->name)) { - type->real = defs->list[i]->type; - return 1; - } - } - return 0; -} -static inline int locate_decl_type_struct(decl_structs *structs, decl_type *type) { - size_t i; - - if (type->strct) { - return 1; - } - for (i = 0; i < structs->count; ++i) { - if (!strcmp(structs->list[i]->name, type->name)) { - type->strct = structs->list[i]; - return 1; - } - } - return 0; -} -static inline int validate_decl_type(PSI_Validator *V, decl_type *type) { - switch (type->type) { - case PSI_T_NAME: - if (!V->defs || !locate_decl_type_alias(V->defs, type)) { - return 0; - } - return validate_decl_type(V, type->real); - case PSI_T_STRUCT: - if (!V->structs || !locate_decl_type_struct(V->structs, type)) { - return 0; - } - break; - } - return 1; -} -static inline int validate_typedef(PSI_Validator *V, decl_typedef *def) { - /* FIXME: check def->alias */ - if (def->type->type == PSI_T_NAME) { - V->error(PSI_WARNING, "Type '%s' cannot be aliased to '%s'", - def->type->name, def->alias); - return 0; - } - return 1; -} -static inline int validate_typedefs(PSI_Validator *V) { - size_t i; - - for (i = 0; i < V->defs->count; ++i) { - if (!validate_typedef(V, V->defs->list[i])) { - return 0; - } - } - - return 1; -} -static const char * const abi_ccs[] = { - "default", /* \ */ - "extern", /* > - all the same */ - "cdecl", /* / */ - "stdcall", - "fastcall", -}; -static inline int validate_decl_abi(PSI_Validator *V, decl_abi *abi) { - size_t i; - - for (i = 0; i < sizeof(abi_ccs)/sizeof(char*); ++i) { - if (strcasecmp(abi->convention, abi_ccs[i])) { - return 1; - } - } - V->error(PSI_WARNING, "Invalid calling convention: '%s'", abi->convention); - return 0; -} -static inline int validate_decl_arg(PSI_Validator *V, decl_arg *arg) { - if (!validate_decl_type(V, arg->type)) { - V->error(PSI_WARNING, "Cannot use '%s' as type for '%s'", - arg->type->name, arg->var->name); - return 0; - } - return 1; -} -static inline int validate_decl_args(PSI_Validator *V, decl_args *args) { - size_t i; - - for (i = 0; i < args->count; ++i) { - if (!validate_decl_arg(V, args->args[i])) { - return 0; - } - } - return 1; -} -static inline int validate_decl_func(PSI_Validator *V, decl *decl, decl_arg *func) -{ - if (!strcmp(func->var->name, "dlsym")) { - V->error(PSI_WARNING, "Cannot dlsym dlsym (sic!)"); - return 0; - } - - if (!validate_decl_arg(V, func)) { - return 0; - } -#ifndef RTLD_NEXT -# define RTLD_NEXT ((void *) -1l) -#endif - decl->dlptr = dlsym(V->dlopened ?: RTLD_NEXT, func->var->name); - if (!decl->dlptr) { - V->error(PSI_WARNING, "Failed to located symbol '%s': %s", - func->var->name, dlerror()); - } - return 1; -} -static inline int validate_decl(PSI_Validator *V, decl *decl) { - if (!validate_decl_abi(V, decl->abi)) { - return 0; - } - if (!validate_decl_func(V, decl, decl->func)) { - return 0; - } - if (decl->args && !validate_decl_args(V, decl->args)) { - return 0; - } - return 1; -} -static inline int validate_decls(PSI_Validator *V) { - size_t i; - - for (i = 0; i < V->decls->count; ++i) { - if (!validate_decl(V, V->decls->list[i])) { - return 0; - } - } - return 1; -} -static inline int validate_struct(PSI_Validator *V, decl_struct *s) { - size_t i; - - if (!validate_decl_args(V, s->args)) { - return 0; - } - - s->layout = calloc(s->args->count, sizeof(*s->layout)); - for (i = 0; i < s->args->count; ++i) { - decl_arg *darg = s->args->args[i]; - token_t t; - - if (!validate_decl_arg(V, darg)) { - return 0; - } - - t = darg->var->pointer_level - ? PSI_T_POINTER - : real_decl_type(darg->type)->type; - - if (i) { - decl_struct_layout *l = &s->layout[i-1]; - s->layout[i].pos = psi_t_align(t, l->pos + l->len); - } else { - s->layout[i].pos = 0; - } - s->layout[i].len = psi_t_size(t); - } - return 1; -} -static inline int validate_structs(PSI_Validator *V) { - size_t i; - - for (i = 0; i < V->structs->count; ++i) { - if (!validate_struct(V, V->structs->list[i])) { - return 0; - } - } - return 1; -} - -static inline int validate_impl_type(PSI_Validator *V, impl *impl, impl_type *type) { - /* FIXME */ - return 1; -} -static inline int validate_impl_arg(PSI_Validator *V, impl *impl, impl_arg *arg) { - return 1; -} -static inline int validate_impl_args(PSI_Validator *V, impl *impl, impl_args *args) { - size_t i; - - for (i = 0; i < args->count; ++i) { - if (!validate_impl_arg(V, impl, args->args[i])) { - return 0; - } - } - return 1; -} -static inline int validate_impl_func(PSI_Validator *V, impl *impl, impl_func *func) { - /* FIXME: does name need any validation? */ - if (!validate_impl_type(V, impl, func->return_type)) { - return 0; - } - if (func->args && !validate_impl_args(V, impl, func->args)) { - return 0; - } - return 1; -} - -static inline decl *locate_impl_decl(decls *decls, return_stmt *ret) { - size_t i; - - for (i = 0; i < decls->count; ++i) { - if (!strcmp(decls->list[i]->func->var->name, ret->decl->name)) { - ret->decl->arg = decls->list[i]->func; - return decls->list[i]; - } - } - return NULL; -} -static inline int validate_impl_ret_stmt(PSI_Validator *V, impl *impl) { - /* we must have exactly one ret stmt delcaring the native func to call */ - /* and which type cast to apply */ - if (impl->stmts->ret.count != 1) { - if (impl->stmts->ret.count > 1) { - V->error(PSI_WARNING, "Too many `return` statements for implmentation %s;" - " found %zu, exactly one is needed", - impl->func->name, impl->stmts->ret.count); - } else { - V->error(PSI_WARNING, "Missing `return` statement for implementation %s", - impl->func->name); - } - return 0; - } - if (!(impl->decl = locate_impl_decl(V->decls, impl->stmts->ret.list[0]))) { - V->error(PSI_WARNING, "Missing declaration for implementation %s", - impl->func->name); - return 0; - } - - return 1; -} -static inline int validate_impl_let_stmts(PSI_Validator *V, impl *impl) { - size_t i, j; - /* we can have multiple let stmts */ - /* check that we have a let stmt for every decl arg */ - if (impl->decl->args) for (i = 0; i < impl->decl->args->count; ++i) { - decl_arg *darg = impl->decl->args->args[i]; - int check = 0; - - for (j = 0; j < impl->stmts->let.count; ++j) { - let_stmt *let = impl->stmts->let.list[j]; - - if (!strcmp(let->var->name, darg->var->name)) { - darg->let = let; - check = 1; - break; - } - } - if (!check) { - V->error(PSI_WARNING, "Missing `let` statement for arg '%s %.*s%s'" - " of declaration '%s' for implementation '%s'", - darg->type->name, (int) darg->var->pointer_level, "*****", - darg->var->name, impl->decl->func->var->name, impl->func->name); - return 0; - } - } - /* check that the let_value references a known variable or NULL */ - for (i = 0; i < impl->stmts->let.count; ++i) { - let_stmt *let = impl->stmts->let.list[i]; - int check = 0; - - if (let->val && let->val->func && let->val->func->alloc) { - if (!validate_decl_type(V, let->val->func->alloc->type)) { - V->error(PSI_WARNING, "Cannot use '%s' as type for calloc in `let` statement", - let->val->func->alloc->type->name); - return 0; - } - } - if (let->val && let->val->var) { - if (impl->func->args) for (j = 0; j < impl->func->args->count; ++j) { - impl_arg *iarg = impl->func->args->args[j]; - - if (!strcmp(let->val->var->name, iarg->var->name)) { - let->arg = iarg; - check = 1; - break; - } - } - if (!check) { - V->error(PSI_WARNING, "Unknown value '$%s' of `let` statement" - " for variable '%s' of implementation '%s'", - let->val->var->name, let->var->name, impl->func->name); - return 0; - } - } - } - return 1; -} -static inline int validate_impl_set_stmts(PSI_Validator *V, impl *impl) { - size_t i, j, k; - /* we can have any count of set stmts; processing out vars */ - /* check that set stmts reference known variables */ - for (i = 0; i < impl->stmts->set.count; ++i) { - set_stmt *set = impl->stmts->set.list[i]; - int check = 0; - - if (impl->func->args) for (j = 0; j < impl->func->args->count; ++j) { - impl_arg *iarg = impl->func->args->args[j]; - - if (!strcmp(set->var->name, iarg->var->name)) { - set->arg = iarg; - check = 1; - break; - } - } - if (!check) { - V->error(PSI_WARNING, "Unknown variable '$%s' of `set` statement" - " of implementation '%s'", - set->var->name, impl->func->name); - return 0; - } - - for (j = 0; j < set->val->vars->count; ++j) { - decl_var *set_var = set->val->vars->vars[j]; - - check = 0; - if (impl->decl->args) for (k = 0; k < impl->decl->args->count; ++k) { - decl_arg *set_arg = impl->decl->args->args[k]; - - if (!strcmp(set_var->name, set_arg->var->name)) { - check = 1; - set_var->arg = set_arg; - break; - } - } - - if (!check) { - V->error(PSI_WARNING, "Unknown value '%s' of `set` statement" - " for variable '$%s' of implementation '%s'", - set_var->name, set->arg->var->name, impl->func->name); - return 0; - } - } - } - return 1; -} -static inline int validate_impl_free_stmts(PSI_Validator *V, impl *impl) { - size_t i, j, k; - /* we can have any count of free stmts; freeing any out vars */ - for (i = 0; i < impl->stmts->fre.count; ++i) { - free_stmt *fre = impl->stmts->fre.list[i]; - - for (j = 0; j < fre->vars->count; ++j) { - decl_var *free_var = fre->vars->vars[j]; - int check = 0; - - if (!strcmp(free_var->name, impl->decl->func->var->name)) { - continue; - } - if (impl->decl->args) for (k = 0; k < impl->decl->args->count; ++k) { - decl_arg *free_arg = impl->decl->args->args[k]; - - if (!strcmp(free_var->name, free_arg->var->name)) { - check = 1; - free_var->arg = free_arg; - break; - } - } - - if (!check) { - V->error(PSI_WARNING, "Unknown variable '%s' of `free` statement" - " of implementation '%s'", - free_var->name, impl->func->name); - return 0; - } - } - } - return 1; -} -static inline int validate_impl_stmts(PSI_Validator *V, impl *impl) { - if (!impl->stmts) { - V->error(PSI_WARNING, "Missing body for implementation %s!", - impl->func->name); - return 0; - } - - if (!validate_impl_ret_stmt(V, impl)) { - return 0; - } - - if (!validate_impl_let_stmts(V, impl)) { - return 0; - } - if (!validate_impl_set_stmts(V, impl)) { - return 0; - } - if (!validate_impl_free_stmts(V, impl)) { - return 0; - } - - return 1; -} - -static inline int validate_impl(PSI_Validator *V, impl *impl) { - if (!validate_impl_func(V, impl, impl->func)) { - return 0; - } - if (!validate_impl_stmts(V, impl)) { - return 0; - } - return 1; -} -static inline int validate_impls(PSI_Validator *V) { - size_t i; - - for (i = 0; i < V->impls->count; ++i) { - if (!validate_impl(V, V->impls->list[i])) { - return 0; - } - } - return 1; -} - -int PSI_ValidatorValidate(PSI_Validator *V) -{ - if (!validate_lib(V)) { - return 0; - } - if (V->defs && !validate_typedefs(V)) { - return 0; - } - if (V->structs && !validate_structs(V)) { - return 0; - } - if (V->decls && !validate_decls(V)) { - return 0; - } - if (!V->impls || !validate_impls(V)) { - return 0; - } - return 1; -} diff --git a/src/validator.h b/src/validator.h deleted file mode 100644 index 8b373f6..0000000 --- a/src/validator.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _PSI_VALIDATOR_H -#define _PSI_VALIDATOR_H - -#include "parser.h" - -typedef struct PSI_Validator { - PSI_DATA_MEMBERS; - void *dlopened; -} PSI_Validator; - -PSI_Validator *PSI_ValidatorInit(PSI_Validator *V, PSI_Parser *P); -int PSI_ValidatorValidate(PSI_Validator *V); -void PSI_ValidatorFree(PSI_Validator **V); -void PSI_ValidatorDtor(PSI_Validator *V); - -#endif