-PHP_ARG_ENABLE(psi, whether to enable psi support,
+PHP_ARG_ENABLE(psi, whether to enable PHP System Interface support,
[ --enable-psi Enable PHP System Interface support])
PHP_ARG_WITH(psi-libjit, where to find libjit,
-[ --with-psi-libjit=DIR PSI: path to libjit])
+[ --with-psi-libjit=DIR PSI: path to libjit], [], no)
PHP_ARG_WITH(psi-libffi, where to find libjit,
-[ --with-psi-libffi=DIR PSI: path to libffi])
+[ --with-psi-libffi=DIR PSI: path to libffi], [], no)
if test "$PHP_PSI" != "no"; then
AC_ARG_VAR(LEMON, The lemon parser generator of the SQLite project)
fi])
if $PSI_cv_LIBFFI
then
+ AC_MSG_CHECKING(for libffi)
+ PSI_cv_LIBFFI_DIR=`$PKG_CONFIG --variable=prefix libffi`
+ AC_MSG_RESULT($PSI_cv_LIBFFI_DIR)
PHP_EVAL_INCLINE(`$PKG_CONFIG --cflags libffi`)
PHP_EVAL_LIBLINE(`$PKG_CONFIG --libs libffi`, PSI_SHARED_LIBADD)
else
done])
if test -n "$PSI_cv_LIBFFI_DIR"
then
- PHP_CHECK_LIBRARY(ffi, ffi_closure_alloc, [
- AC_DEFINE(PSI_HAVE_FFI_CLOSURE_ALLOC, 1, [ ])
- ], [
- ], -L$PSI_cv_LIBFFI_DIR/$PHP_LIBDIR)
- PHP_CHECK_LIBRARY(ffi, ffi_closure_free, [
- AC_DEFINE(PSI_HAVE_FFI_CLOSURE_FREE, 1, [ ])
- ], [
- ], -L$PSI_cv_LIBFFI_DIR/$PHP_LIBDIR)
- PHP_CHECK_LIBRARY(ffi, ffi_prep_closure, [
- AC_DEFINE(PSI_HAVE_FFI_PREP_CLOSURE, 1, [ ])
- ], [
- ], -L$PSI_cv_LIBFFI_DIR/$PHP_LIBDIR)
PHP_ADD_INCLUDE($PSI_cv_LIBFFI_DIR/include/ffi)
PHP_ADD_LIBRARY_WITH_PATH(ffi, $PSI_cv_LIBFFI_DIR/$PHP_LIBDIR, PSI_SHARED_LIBADD)
else
AC_MSG_WARN([Could not find libffi, please provide the base install path])
fi
fi
+ PHP_CHECK_LIBRARY(ffi, ffi_closure_alloc, [
+ PHP_CHECK_LIBRARY(ffi, ffi_prep_closure_loc, [
+ AC_DEFINE(PSI_HAVE_FFI_PREP_CLOSURE_LOC, 1, [ ])
+ ], [], -L$PSI_cv_LIBFFI_DIR/$PHP_LIBDIR)
+ AC_DEFINE(PSI_HAVE_FFI_CLOSURE_ALLOC, 1, [ ])
+ ], [
+ PHP_CHECK_LIBRARY(ffi, ffi_prep_closure, [
+ AC_CHECK_HEADERS(sys/mman.h)
+ PHP_CHECK_FUNC(mmap)
+ AC_DEFINE(PSI_HAVE_FFI_PREP_CLOSURE, 1, [ ])
+ ], [
+ ], -L$PSI_cv_LIBFFI_DIR/$PHP_LIBDIR)
+ ], -L$PSI_cv_LIBFFI_DIR/$PHP_LIBDIR)
AC_CACHE_CHECK(for libjit, PSI_cv_LIBJIT_DIR, [
for PSI_cv_LIBJIT_DIR in $PHP_PSI_LIBJIT {/usr{,/local},/opt}{,/libjit}
else
AC_MSG_WARN([Could not find libjit, please provide the base install path])
fi
-
+
PHP_SUBST(PSI_SHARED_LIBADD)
PHP_PSI_SRCDIR=PHP_EXT_SRCDIR(psi)
#include <ffi.h>
#ifndef PSI_HAVE_FFI_CLOSURE_ALLOC
-# include <unistd.h>
-# include <sys/mman.h>
+# if HAVE_UNISTD_H
+# include <unistd.h>
+# endif
+# if HAVE_SYS_MMAN_H
+# include <sys/mman.h>
+# endif
#endif
+static void *psi_ffi_closure_alloc(size_t s, void **code)
+{
+#ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
+ return ffi_closure_alloc(s, code);
+#elif HAVE_MMAP
+ *code = mmap(NULL, s, PROT_EXEC|PROT_WRITE|PROT_READ,
+ MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ if (MAP_FAILED == *code) {
+ return NULL;
+ }
+ return *code;
+#else
+ return NULL;
+#endif
+}
+
+static void psi_ffi_closure_free(void *c)
+{
+#ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
+ ffi_closure_free(c);
+#elif HAVE_MMAP
+ munmap(c, sizeof(ffi_closure));
+#endif
+}
+
static void handler(ffi_cif *signature, void *_result, void **_args, void *_data);
static inline ffi_abi psi_ffi_abi(const char *convention) {
data->params);
ZEND_ASSERT(FFI_OK == rc);
-#ifdef PSI_HAVE_FFI_CLOSURE_ALLOC
- data->closure = ffi_closure_alloc(sizeof(ffi_closure), &data->code);
+ data->closure = psi_ffi_closure_alloc(sizeof(ffi_closure), &data->code);
+ ZEND_ASSERT(data->closure != NULL);
+#if PSI_HAVE_FFI_PREP_CLOSURE_LOC
rc = ffi_prep_closure_loc(
data->closure,
&context->signature,
data,
data->code);
ZEND_ASSERT(FFI_OK == rc);
-#else
- i = getpagesize();
- data->closure = malloc(sizeof(ffi_closure) + i);
- data->code = (void *) (((intptr_t) data->closure + i - 1) & ~((intptr_t) i - 1));
- rc = mprotect(data->code, sizeof(ffi_closure), PROT_EXEC|PROT_WRITE);
- ZEND_ASSERT(rc == 0);
+#elif PSI_HAVE_FFI_PREP_CLOSURE
rc = ffi_prep_closure(data->code, &context->signature, handler, data);
ZEND_ASSERT(FFI_OK == rc);
+#else
+# error "Neither ffi_prep_closure() nor ffi_prep_closure_loc() available"
#endif
context->data.list = realloc(context->data.list, ++context->data.count * sizeof(*context->data.list));
}
static inline void PSI_LibffiDataFree(PSI_LibffiData *data) {
+ psi_ffi_closure_free(data->closure);
free(data->arginfo);
-#ifdef PSI_HAVE_FFI_CLOSURE_FREE
- ffi_closure_free(data->closure);
-#else
- free(data->closure);
-#endif
free(data);
}
static inline void free_let_stmt(let_stmt *stmt) {
free_decl_var(stmt->var);
- free_let_value(stmt->val);
+ if (stmt->val) {
+ free_let_value(stmt->val);
+ }
free(stmt);
}
TO_FLOAT = 'to_float';
TO_BOOL = 'to_bool';
NUMBER = [+-]? [0-9]* "."? [0-9]+ ([eE] [+-]? [0-9]+)?;
- DIGITS = [0-9]+;
"#" .* "\n" { ++P->line; RETURN(PSI_T_COMMENT);}
"(" {RETURN(PSI_T_LPAREN);}
TO_FLOAT {RETURN(PSI_T_TO_FLOAT);}
TO_BOOL {RETURN(PSI_T_TO_BOOL);}
NUMBER {RETURN(PSI_T_NUMBER);}
- DIGITS {RETURN(PSI_T_DIGITS);}
NAME {RETURN(PSI_T_NAME);}
NSNAME {RETURN(PSI_T_NSNAME);}
QUOTED_STRING {RETURN(PSI_T_QUOTED_STRING);}
#define PSI_T_NAME 13
#define PSI_T_LPAREN 14
#define PSI_T_RPAREN 15
-#define PSI_T_COMMA 16
-#define PSI_T_VOID 17
-#define PSI_T_CHAR 18
-#define PSI_T_SHORT 19
-#define PSI_T_LONG 20
-#define PSI_T_DOUBLE 21
-#define PSI_T_SINT8 22
-#define PSI_T_UINT8 23
-#define PSI_T_SINT16 24
-#define PSI_T_UINT16 25
-#define PSI_T_SINT32 26
-#define PSI_T_UINT32 27
-#define PSI_T_SINT64 28
-#define PSI_T_UINT64 29
-#define PSI_T_LBRACE 30
-#define PSI_T_RBRACE 31
-#define PSI_T_FUNCTION 32
-#define PSI_T_COLON 33
-#define PSI_T_REFERENCE 34
-#define PSI_T_NULL 35
-#define PSI_T_NUMBER 36
-#define PSI_T_TRUE 37
-#define PSI_T_FALSE 38
-#define PSI_T_DOLLAR 39
-#define PSI_T_LET 40
-#define PSI_T_STRLEN 41
-#define PSI_T_STRVAL 42
-#define PSI_T_INTVAL 43
-#define PSI_T_FLOATVAL 44
-#define PSI_T_BOOLVAL 45
-#define PSI_T_SET 46
-#define PSI_T_TO_STRING 47
-#define PSI_T_TO_INT 48
-#define PSI_T_TO_FLOAT 49
-#define PSI_T_TO_BOOL 50
-#define PSI_T_RETURN 51
-#define PSI_T_FREE 52
-#define PSI_T_MIXED 53
-#define PSI_T_ARRAY 54
-#define PSI_T_POINTER 55
+#define PSI_T_LBRACKET 16
+#define PSI_T_NUMBER 17
+#define PSI_T_RBRACKET 18
+#define PSI_T_DIGITS 19
+#define PSI_T_COMMA 20
+#define PSI_T_VOID 21
+#define PSI_T_CHAR 22
+#define PSI_T_SHORT 23
+#define PSI_T_LONG 24
+#define PSI_T_DOUBLE 25
+#define PSI_T_SINT8 26
+#define PSI_T_UINT8 27
+#define PSI_T_SINT16 28
+#define PSI_T_UINT16 29
+#define PSI_T_SINT32 30
+#define PSI_T_UINT32 31
+#define PSI_T_SINT64 32
+#define PSI_T_UINT64 33
+#define PSI_T_LBRACE 34
+#define PSI_T_RBRACE 35
+#define PSI_T_FUNCTION 36
+#define PSI_T_COLON 37
+#define PSI_T_REFERENCE 38
+#define PSI_T_NULL 39
+#define PSI_T_TRUE 40
+#define PSI_T_FALSE 41
+#define PSI_T_DOLLAR 42
+#define PSI_T_LET 43
+#define PSI_T_STRLEN 44
+#define PSI_T_STRVAL 45
+#define PSI_T_INTVAL 46
+#define PSI_T_FLOATVAL 47
+#define PSI_T_BOOLVAL 48
+#define PSI_T_SET 49
+#define PSI_T_TO_STRING 50
+#define PSI_T_TO_INT 51
+#define PSI_T_TO_FLOAT 52
+#define PSI_T_TO_BOOL 53
+#define PSI_T_RETURN 54
+#define PSI_T_FREE 55
+#define PSI_T_MIXED 56
+#define PSI_T_ARRAY 57
+#define PSI_T_POINTER 58
var = init_decl_var(T->text, p, 0);
free(T);
}
-decl_var(var) ::= NAME(T) LBRACKET DIGITS(D) RBRACKET. {
+decl_var(var) ::= NAME(T) LBRACKET NUMBER(D) RBRACKET. {
var = init_decl_var(T->text, 1, atol(D->text));
free(T);
free(D);
if (V->decls && !validate_decls(V)) {
return 0;
}
- if (V->impls && !validate_impls(V)) {
+ if (!V->impls || !validate_impls(V)) {
return 0;
}
return 1;