-static inline void psi_do_set(zval *return_value, set_value *set)
-{
- ZVAL_DEREF(return_value);
- zval_dtor(return_value);
-
- set->func->handler(return_value, set, set->vars->vars[0]->arg->let->ptr);
-}
-
-static inline void psi_do_return(zval *return_value, return_stmt *ret, impl_val *ret_val)
-{
- ret->set->func->handler(return_value, ret->set, ret_val);
-}
-
-static inline void psi_do_free(free_stmt *fre)
-{
- size_t i, j;
- impl_val dummy;
-
- for (i = 0; i < fre->calls->count; ++i) {
- free_call *f = fre->calls->list[i];
-
- for (j = 0; j < f->vars->count; ++j) {
- decl_var *dvar = f->vars->vars[j];
- decl_arg *darg = dvar->arg;
-
- 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);
- }
-}
-
-static inline void psi_do_clean(impl *impl)
-{
- size_t i;
-
- for (i = 0; i < impl->func->args->count; ++i ) {
- impl_arg *iarg = impl->func->args->args[i];
-
- switch (iarg->type->type) {
- case PSI_T_STRING:
- if (iarg->val.zend.str) {
- zend_string_release(iarg->val.zend.str);
- }
- break;
- }
- }
-
- if (impl->decl->args) for (i = 0; i < impl->decl->args->count; ++i) {
- decl_arg *darg = impl->decl->args->args[i];
-
- if (darg->let && darg->let->mem) {
- decl_type *type = real_decl_type(darg->type);
-
- if (type->type == PSI_T_STRUCT) {
- void **ptr = (void **) ((char *) darg->let->mem + type->strct->size);
-
- while (*ptr) {
- efree(*ptr++);
- }
- }
- efree(darg->let->mem);
- darg->let->mem = NULL;
- }
- }
-}
-
-void psi_call(zend_execute_data *execute_data, zval *return_value, impl *impl)
-{
- impl_val ret_val;
- size_t i;
-
- if (SUCCESS != psi_parse_args(execute_data, impl)) {
- return;
- }
-
- if (impl->decl->args) {
- for (i = 0; i < impl->decl->args->count; ++i) {
- decl_arg *darg = impl->decl->args->args[i];
-
- if (!(impl->decl->call.args[i] = psi_do_let(darg))) {
- goto cleanup;
- }
- }
- }
-
- memset(&ret_val, 0, sizeof(ret_val));
- PSI_ContextCall(&PSI_G(context), &ret_val, impl->decl);
-
- psi_do_return(return_value, impl->stmts->ret.list[0], &ret_val);
-
- for (i = 0; i < impl->stmts->set.count; ++i) {
- set_stmt *set = impl->stmts->set.list[i];
-
- if (set->arg->_zv) {
- psi_do_set(set->arg->_zv, set->val);
- }
- }
-
- for (i = 0; i < impl->stmts->fre.count; ++i) {
- free_stmt *fre = impl->stmts->fre.list[i];
-
- psi_do_free(fre);
- }
- psi_do_clean(impl);
- return;
-
-cleanup:
- memset(&ret_val, 0, sizeof(ret_val));
- psi_do_return(return_value, impl->stmts->ret.list[0], &ret_val);
- psi_do_clean(impl);
-}
-
-static void psi_object_free(zend_object *o)
-{
- psi_object *obj = PSI_OBJ(NULL, o);
-
- if (obj->data) {
- // free(obj->data);
- obj->data = NULL;
- }
- zend_object_std_dtor(o);
-}
-
-static zend_object *psi_object_init(zend_class_entry *ce)
-{
- psi_object *o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce));
-
- zend_object_std_init(&o->std, ce);
- object_properties_init(&o->std, ce);
- o->std.handlers = &psi_object_handlers;
- return &o->std;
-}
-
-PHP_MINIT_FUNCTION(psi)