+ if (args) {
+ size_t size = extract_decl_type_size(real, NULL);
+
+ mem = ecalloc(1, size + args->count * sizeof(void *));
+
+ for (i = 0; i < args->count; ++i) {
+ decl_arg *darg = args->args[i];
+ let_val *lval = locate_let_vals_val(func->inner, darg->var->name);
+ impl_val *ptr = NULL;
+
+ if (lval) {
+ if ((ptr = psi_let_val(lval, darg))) {
+ memcpy(mem + darg->layout->pos, ptr, darg->layout->len);
+ if (darg->mem) {
+ ((void **)(mem + size))[j++] = darg->mem;
+ }
+ }
+ if (real->type == PSI_T_UNION) {
+ break;
+ }
+ }
+ }
+ } else {
+ zval *zv;
+ let_val *inner = func->inner->vals[0];
+ decl_var *sub_var;
+ size_t size;
+
+ if (inner->var) {
+ sub_var = inner->var;
+ } else {
+ sub_var = copy_decl_var(dvar);
+ assert(sub_var->pointer_level);
+ --sub_var->pointer_level;
+ }
+
+ size = sub_var->pointer_level ? SIZEOF_VOID_P : extract_decl_type_size(real, NULL);
+ mem = ecalloc(1, size * (1 + zend_array_count(Z_ARRVAL_P(zvalue))));
+
+ ZEND_HASH_FOREACH_VAL_IND(Z_ARRVAL_P(zvalue), zv)
+ {
+ void *tmp = NULL;
+ impl_val val = {0}, *ptr, *sub;
+
+ ptr = psi_let_func_ex(inner->data.func, &val, real, dvar, 0, NULL, zv, &tmp);
+ sub = deref_impl_val(ptr, sub_var);
+
+ memcpy(&mem[size * j++], &sub, size);
+ }
+ ZEND_HASH_FOREACH_END();
+
+ if (sub_var != inner->var) {
+ free_decl_var(sub_var);
+ }
+ }
+ return *to_free = mem;