assert(FFI_OK == rc);
}
+#if HAVE_INT128
+static ffi_type *ffi_type_sint128;
+static ffi_type *ffi_type_uint128;
+#endif
+
static inline ffi_type *psi_ffi_decl_arg_type(struct psi_decl_arg *darg);
static inline ffi_type *psi_ffi_token_type(token_t t) {
return &ffi_type_sint64;
case PSI_T_UINT64:
return &ffi_type_uint64;
+#if HAVE_INT128
+ case PSI_T_INT128:
+ return ffi_type_sint128;
+ case PSI_T_UINT128:
+ return ffi_type_uint128;
+#endif
case PSI_T_BOOL:
return &ffi_type_uchar;
- case PSI_T_INT:
case PSI_T_ENUM:
return &ffi_type_sint;
- case PSI_T_LONG:
- return &ffi_type_slong;
case PSI_T_FLOAT:
return &ffi_type_float;
case PSI_T_DOUBLE:
}
}
+static void psi_ffi_extvar_get(ffi_cif *sig, void *result, void **args, void *data) {
+ struct psi_decl_extvar *evar = data;
+
+ psi_decl_extvar_get(evar, result);
+}
+
+static void psi_ffi_extvar_set(ffi_cif *sig, void *result, void **args, void *data) {
+ struct psi_decl_extvar *evar = data;
+
+ psi_decl_extvar_set(evar, args[0]);
+}
+
+struct psi_ffi_extvar_info {
+ struct {
+ ffi_cif signature;
+ void *code;
+ ffi_closure *closure;
+ } get;
+ struct {
+ ffi_cif signature;
+ ffi_type *params[1];
+ void *code;
+ ffi_closure *closure;
+ } set;
+};
+
+static inline ffi_status psi_ffi_extvar_init(struct psi_decl_extvar *evar,
+ ffi_type *type) {
+ struct psi_ffi_extvar_info *info = calloc(1, sizeof(*info));
+ ffi_status rc;
+
+ rc = ffi_prep_cif(&info->get.signature, FFI_DEFAULT_ABI, 0,
+ type, NULL);
+ if (FFI_OK != rc) {
+ return rc;
+ }
+ rc = psi_ffi_prep_closure(&info->get.closure, &info->get.code,
+ &info->get.signature, psi_ffi_extvar_get, evar);
+ if (FFI_OK != rc) {
+ return rc;
+ }
+
+ info->set.params[0] = type;
+ rc = ffi_prep_cif(&info->set.signature, FFI_DEFAULT_ABI, 1,
+ &ffi_type_void, info->set.params);
+ if (FFI_OK != rc) {
+ return rc;
+ }
+ rc = psi_ffi_prep_closure(&info->set.closure, &info->set.code,
+ &info->set.signature, psi_ffi_extvar_set, evar);
+ if (FFI_OK != rc) {
+ return rc;
+ }
+
+ evar->info = info;
+ evar->getter->sym = info->get.code;
+ evar->setter->sym = info->set.code;
+
+ return FFI_OK;
+}
+
+static inline void psi_ffi_extvar_dtor(struct psi_decl_extvar *evar) {
+ if (evar->info) {
+ free(evar->info);
+ evar->info = NULL;
+ }
+}
static inline struct psi_ffi_context *psi_ffi_context_init(struct psi_ffi_context *L) {
ffi_status rc;
}
}
+ if (C->vars) {
+ size_t i = 0;
+ struct psi_decl_extvar *evar;
+
+ while (psi_plist_get(C->vars, i++, &evar)) {
+ psi_ffi_extvar_dtor(evar);
+ }
+ }
if (C->impls) {
size_t i = 0;
struct psi_impl *impl;
static zend_function_entry *psi_ffi_compile(struct psi_context *C)
{
- size_t i = 0, d = 0, nf = 0;
+ size_t i = 0, d = 0, v = 0, nf = 0;
struct psi_impl *impl;
struct psi_decl *decl;
- zend_function_entry *zfe;
+ struct psi_decl_extvar *evar;
+ zend_function_entry *zfe = NULL;
- if (!C->impls) {
- return NULL;
+ while (psi_plist_get(C->vars, v++, &evar)) {
+ ffi_type *type = psi_ffi_decl_arg_type(evar->arg);
+
+ if (FFI_OK == psi_ffi_extvar_init(evar, type)) {
+ /* */
+ }
}
- zfe = calloc(psi_plist_count(C->impls) + 1, sizeof(*zfe));
+ if (C->impls) {
+ zfe = calloc(psi_plist_count(C->impls) + 1, sizeof(*zfe));
- while (psi_plist_get(C->impls, i++, &impl)) {
- zend_function_entry *zf = &zfe[nf];
+ while (psi_plist_get(C->impls, i++, &impl)) {
+ zend_function_entry *zf = &zfe[nf];
- if (!impl->decl) {
- continue;
- }
- if (!psi_ffi_decl_init(impl->decl)) {
- continue;
- }
- if (!psi_ffi_impl_init(impl, C)) {
- continue;
- }
+ if (!impl->decl) {
+ continue;
+ }
+ if (!psi_ffi_decl_init(impl->decl)) {
+ continue;
+ }
+ if (!psi_ffi_impl_init(impl, C)) {
+ continue;
+ }
- zf->fname = impl->func->name + (impl->func->name[0] == '\\');
- zf->handler = ((struct psi_ffi_impl_info *) impl->info)->code;
- zf->num_args = psi_plist_count(impl->func->args);
- zf->arg_info = psi_internal_arginfo(impl);
- ++nf;
+ zf->fname = impl->func->name + (impl->func->name[0] == '\\');
+ zf->handler = ((struct psi_ffi_impl_info *) impl->info)->code;
+ zf->num_args = psi_plist_count(impl->func->args);
+ zf->arg_info = psi_internal_arginfo(impl);
+ ++nf;
+ }
}
while (psi_plist_get(C->decls, d++, &decl)) {
return NULL;
}
+static ZEND_RESULT_CODE psi_ffi_load()
+{
+#if HAVE_INT128
+ ffi_type *i128, *u128;
+
+ i128 = calloc(1, 3*sizeof(ffi_type));
+ i128->type = FFI_TYPE_STRUCT;
+ i128->size = 0;
+ i128->elements = (ffi_type **) (i128 + 1);
+ i128->elements[0] = &ffi_type_sint64;
+ i128->elements[1] = &ffi_type_sint64;
+
+ ffi_type_sint128 = i128;
+
+ u128 = calloc(1, 3*sizeof(ffi_type));
+ u128->type = FFI_TYPE_STRUCT;
+ u128->size = 0;
+ u128->elements = (ffi_type **) (u128 + 1);
+ u128->elements[0] = &ffi_type_uint64;
+ u128->elements[1] = &ffi_type_uint64;
+
+ ffi_type_uint128 = u128;
+#endif
+ return SUCCESS;
+}
+
+static void psi_ffi_free()
+{
+#if HAVE_INT128
+ free(ffi_type_sint128);
+ free(ffi_type_uint128);
+#endif
+}
+
static struct psi_context_ops ops = {
+ psi_ffi_load,
+ psi_ffi_free,
psi_ffi_init,
psi_ffi_dtor,
psi_ffi_compile,