#include "php.h"
-#include <stdio.h>
-#ifdef HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-#ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-# include <stddef.h>
-#else
-# ifdef HAVE_STDLIB_H
-# include <stdlib.h>
-# endif
-#endif
-#ifdef HAVE_STRING_H
-# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
-# include <memory.h>
-# endif
-# include <string.h>
-#endif
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-#ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
-#endif
-#ifdef HAVE_STDINT_H
-# include <stdint.h>
-#endif
-#ifdef HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-#ifdef HAVE_GLOB_H
-# include <glob.h>
-#endif
-#ifdef HAVE_NETINET_IN_H
-# include <netinet/in.h>
-#endif
-#ifdef HAVE_ARPA_NAMESER_H
-# include <arpa/nameser.h>
-#endif
-#ifdef HAVE_NETDB_H
-# include <netdb.h>
-#endif
-#ifdef HAVE_RESOLV_H
-# include <resolv.h>
-#endif
-#ifdef HAVE_SYS_SELECT_H
-# include <sys/select.h>
-#endif
-#ifdef HAVE_SYS_SOCKET_H
-# include <sys/socket.h>
-#endif
-#ifdef HAVE_SYS_TIME_H
-# include <sys/time.h>
-#endif
-#ifdef HAVE_SYS_TIMES_H
-# include <sys/times.h>
-#endif
-#ifdef HAVE_SYS_UIO_H
-# include <sys/uio.h>
-#endif
-#ifdef HAVE_SYS_UTSNAME_H
-# include <sys/utsname.h>
-#endif
-#ifdef HAVE_TIME_H
-# include <time.h>
-#endif
-#ifdef HAVE_SYSLOG_H
-# include <syslog.h>
-#endif
-#ifdef HAVE_WCHAR_H
-# include <wchar.h>
-#endif
+#include "php_psi_stdinc.h"
#ifdef HAVE_DIRENT_H
# include <dirent.h>
#include "libjit.h"
#include "libffi.h"
-static struct psi_std_type {
- token_t type_tag;
- const char *type_name;
-} psi_std_types[] = {
- {PSI_T_FLOAT, "float"},
- {PSI_T_DOUBLE, "double"},
- {PSI_T_INT8, "int8_t"},
- {PSI_T_INT16, "int16_t"},
- {PSI_T_INT32, "int32_t"},
- {PSI_T_INT64, "int64_t"},
- {PSI_T_UINT8, "uint8_t"},
- {PSI_T_UINT16, "uint16_t"},
- {PSI_T_UINT32, "uint32_t"},
- {PSI_T_UINT64, "uint64_t"},
- {0}
-};
-
+#include "php_psi_stdtypes.h"
#include "php_psi_types.h"
#include "php_psi_consts.h"
#include "php_psi_macros.h"
#include "php_psi_va_decls.h"
#include "php_psi_structs.h"
-/*
-static struct psi_predef_type {
- token_t type_tag;
- const char *type_name;
- const char *alias;
-} psi_predef_types[] = {
- PSI_TYPES
- {0}
-};
-
-static struct psi_predef_const {
- token_t type_tag;
- const char *type_name;
- const char *var_name;
- const char *val_text;
- token_t val_type_tag;
-} psi_predef_consts[] = {
- PSI_CONSTS
- {0}
-};
-
-PSI_MACROS
-
-struct utsname *uname2() {
- struct utsname *u = calloc(1, sizeof(*u));
- uname(u);
- return u;
-}
-
-int psi_glob(const char *pattern, int flags,
- int (*errfunc) (const char *epath, int eerrno),
- glob_t *pglob) {
- size_t offs = flags & GLOB_DOOFFS ? pglob->gl_offs : 0;
- int rv = glob(pattern, flags, errfunc, pglob);
- if (pglob->gl_pathv) {
- while (offs--) {
- pglob->gl_pathv[offs] = NULL;
- }
- }
- return rv;
-}
-
-static struct psi_func_redir {
- const char *name;
- void (*func)(void);
-} psi_func_redirs[] = {
- {"glob", (void (*)(void)) psi_glob},
- {"uname2", (void (*)(void)) uname2},
- PSI_REDIRS
- {0}
-};
-
-static struct psi_predef_decl {
- token_t type_tag;
- const char *type_name;
- const char *var_name;
- size_t pointer_level;
- size_t array_size;
-} psi_predef_decls[] = {
- PSI_DECLS
- {0}
-};
-static struct psi_predef_decl psi_predef_vararg_decls[] = {
- PSI_VA_DECLS
- {0}
-};
-
-static struct psi_predef_struct {
- token_t type_tag;
- const char *type_name;
- const char *var_name;
- size_t offset;
- size_t size;
- size_t pointer_level;
- size_t array_size;
-} psi_predef_structs[] = {
- PSI_STRUCTS
- {0}
-};
-*/
static int validate_lib(PSI_Data *data, void **dlopened) {
char lib[MAXPATHLEN];
const char *ptr = data->psi.file.ln;
static inline int locate_decl_type_alias(decl_typedefs *defs, decl_type *type) {
size_t i;
- struct psi_std_type *stdtyp;
+ struct psi_predef_type *stdtyp;
if (type->real) {
return 1;
}
}
for (stdtyp = &psi_std_types[0]; stdtyp->type_tag; ++stdtyp) {
- if (!strcmp(type->name, stdtyp->type_name)) {
+ if (!strcmp(type->name, stdtyp->alias ?: stdtyp->type_name)) {
type->type = stdtyp->type_tag;
return 1;
}
static inline int validate_decl_type(PSI_Data *data, decl_type *type) {
switch (type->type) {
+ case PSI_T_CHAR:
+ case PSI_T_SHORT:
+ case PSI_T_INT:
+ case PSI_T_LONG:
case PSI_T_NAME:
if (!data->defs || !locate_decl_type_alias(data->defs, type)) {
return 0;
return 1;
}
+static int psi_sort_struct_arg_cmp(const void *_a, const void *_b) {
+ decl_arg *a = *(decl_arg **)_a, *b = *(decl_arg **)_b;
+
+ if (a->layout->pos == b->layout->pos) {
+ if (a->layout->len == b->layout->len) {
+ return 0;
+ } else if (a->layout->len > b->layout->len) {
+ return -1;
+ } else {
+ return 1;
+ }
+ } else if (a->layout->pos > b->layout->pos) {
+ return 1;
+ } else {
+ return -1;
+ }
+}
+static void psi_sort_struct_arg_swp(void *a, void *b) {
+ decl_arg **_a = a, **_b = b, *_c;
+
+ _c = *_b;
+ *_b = *_a;
+ *_a = _c;
+}
+static inline void psi_sort_struct_args(decl_struct *s) {
+ zend_insert_sort(s->args->args, s->args->count, sizeof(*s->args->args),
+ psi_sort_struct_arg_cmp, psi_sort_struct_arg_swp);
+}
+
static inline int validate_decl_struct(PSI_Data *data, decl_struct *s) {
size_t i;
ZEND_ASSERT(!darg->var->arg || darg->var->arg == darg);
darg->var->arg = darg;
- if (!darg->layout) {
+ if (darg->layout) {
+ size_t size;
+
+ if (darg->var->array_size) {
+ size = psi_t_size(real_decl_type(darg->type)->type) * darg->var->array_size;
+ } else if (darg->var->pointer_level) {
+ size = psi_t_size(PSI_T_POINTER);
+ } else {
+ decl_type *real = real_decl_type(darg->type);
+
+ if (real->type == PSI_T_STRUCT) {
+ size = real->strct->size;
+ } else {
+ size = psi_t_size(real->type);
+ }
+ }
+ if (darg->layout->len != size) {
+ data->error(darg->token, PSI_WARNING,
+ "Computed length %zu of %s.%s does not match"
+ " pre-defined length %zu of type '%s'",
+ darg->layout->len, s->name, darg->var->name, size,
+ darg->type->name);
+ return 0;
+ }
+ } else {
token_t t;
if (darg->var->pointer_level && (!darg->var->array_size || darg->var->pointer_level == 1)) {
s->size = darg->layout->pos + darg->layout->len;
}
}
+
+ psi_sort_struct_args(s);
+
return 1;
}
}
}
-static inline void dump_impl_set_value(int fd, set_value *set, unsigned level) {
+static inline void dump_impl_set_value(int fd, set_value *set, unsigned level, int last) {
size_t i;
if (level > 1) {
dprintf(fd, ", ");
dump_num_exp(fd, set->num);
}
- if (set->inner) {
+ if (set->inner && set->func->type != PSI_T_ELLIPSIS) {
dprintf(fd, ",\n");
for (i = 0; i < set->count; ++i) {
- dump_impl_set_value(fd, set->inner[i], level+1);
+ dump_impl_set_value(fd, set->inner[i], level+1, i == (set->count - 1));
}
/* only if inner stmts, i.e. with new lines, were dumped */
dump_level(fd, level);
}
if (level > 1) {
- dprintf(fd, "),\n");
+ dprintf(fd, ")%s\n", last ? "" : ",");
} else {
dprintf(fd, ");\n");
}
dprintf(fd, "typedef ");
dump_decl_type(fd, tdef->type);
- dprintf(fd, " %s;\n", tdef->alias);
+ dprintf(fd, " %s%s;\n", tdef->type->type == PSI_T_POINTER ? "*":"",
+ tdef->alias);
}
dprintf(fd, "\n");
}
for (i = 0; i < C->structs->count; ++i) {
decl_struct *strct = C->structs->list[i];
- dprintf(fd, "struct %s::(%zu) {\n", strct->name, strct->size);
- if (strct->args) for (j = 0; j < strct->args->count; ++j) {
- decl_arg *sarg = strct->args->args[j];
+ dprintf(fd, "struct %s::(%zu)", strct->name, strct->size);
+ if (strct->args && strct->args->count) {
+ dprintf(fd, " {\n");
+ for (j = 0; j < strct->args->count; ++j) {
+ decl_arg *sarg = strct->args->args[j];
- dprintf(fd, "\t");
- dump_decl_arg(fd, sarg);
- dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len);
+ dprintf(fd, "\t");
+ dump_decl_arg(fd, sarg);
+ dprintf(fd, "::(%zu, %zu);\n", sarg->layout->pos, sarg->layout->len);
+ }
+ dprintf(fd, "}");
+ } else {
+ dprintf(fd, ";");
}
- dprintf(fd, "}\n");
+ dprintf(fd, "\n");
+
}
dprintf(fd, "\n");
}
dprintf(fd, "%s($%s)", let->val->data.func->name,
let->val->data.func->var->name);
break;
+ case PSI_LET_NUMEXP:
+ dump_num_exp(fd, let->val->data.num);
+ break;
EMPTY_SWITCH_DEFAULT_CASE();
}
return_stmt *ret = impl->stmts->ret.list[j];
dprintf(fd, "\treturn ");
- dump_impl_set_value(fd, ret->set, 1);
+ dump_impl_set_value(fd, ret->set, 1, 0);
}
for (j = 0; j < impl->stmts->set.count; ++j) {
set_stmt *set = impl->stmts->set.list[j];
dprintf(fd, "\tset $%s = ", set->var->name);
- dump_impl_set_value(fd, set->val, 1);
+ dump_impl_set_value(fd, set->val, 1, 0);
}
for (j = 0; j < impl->stmts->fre.count; ++j) {
free_stmt *fre = impl->stmts->fre.list[j];