+ return psi_array_to_struct_ex(s, arr, psi_from_zval_ex, NULL);
+}
+
+void *psi_array_to_union_ex(decl_union *u, HashTable *arr, psi_marshal_zval cb, void *cb_ctx) {
+ size_t i;
+ char *mem = ecalloc(1, u->size + sizeof(void *));
+
+ if (arr) for (i = 0; i < u->args->count; ++i) {
+ decl_arg *darg = u->args->args[i];
+ zval *entry = zend_hash_str_find_ind(arr, darg->var->name, strlen(darg->var->name));
+
+ if (entry) {
+ impl_val val, *ptr = &val;
+ void *tmp = NULL;
+
+ memset(&val, 0, sizeof(val));
+ cb(cb_ctx, &ptr, darg, /*FIXME*/0, entry, &tmp);
+ memcpy(mem, &val, darg->layout->len);
+ if (tmp) {
+ ((void **)(mem + u->size))[0] = tmp;
+ }
+ /* first found entry wins */
+ break;
+ }
+ }
+
+ return mem;
+}
+
+void *psi_array_to_union(decl_union *u, HashTable *arr) {
+ return psi_array_to_union_ex(u, arr, psi_from_zval_ex, NULL);
+}
+
+void psi_to_recursive(zval *return_value, set_value *set, impl_val *r_val) {