+void exec_let_func_arrval_inner(struct psi_let_func *func,
+ struct psi_decl_arg *darg, struct psi_decl_arg *inner_decl_arg,
+ struct psi_call_frame_argument *frame_arg,
+ struct psi_let_exp *inner_let_exp, void *container,
+ struct psi_call_frame *frame)
+{
+ struct psi_let_func *inner_func = psi_let_exp_get_func(inner_let_exp);
+ struct psi_impl_var *inner_var = inner_func->var;
+
+ if (psi_decl_type_get_real(darg->type)->type == PSI_T_UNION) {
+ /* skip if there's no entry in the outer_zval;
+ * we only want to set supplied data on unions
+ */
+ if (!zend_symtable_str_exists(Z_ARRVAL_P(frame_arg->zval_ptr),
+ &inner_var->name[1], strlen(&inner_var->name[1]))) {
+ return;
+ }
+ }
+ psi_call_frame_sub_argument(frame, inner_var, frame_arg->zval_ptr,
+ inner_func->var->fqn);
+
+ /* example from dm_store/dbm_fetch with arrval($string) conversion:
+ let key = arrval($key,
+ dptr = strval($0),
+ dsize = strlen($0)
+ );
+ # ---
+ darg = key
+ frame_arg = $key
+ inner_var = $0
+ full_func_var_name = $key.0
+ inner_decl_arg = key.dptr
+ */
+ psi_let_exp_exec(inner_let_exp, inner_decl_arg,
+ ((char *) container) + inner_decl_arg->layout->pos,
+ inner_decl_arg->layout->len, frame);
+}
+
+static void *exec_let_func_arrval(struct psi_let_exp *val,
+ struct psi_let_func *func, struct psi_decl_arg *darg,
+ struct psi_call_frame *frame);
+
+void exec_let_func_arrval_seq(struct psi_let_func *func,
+ struct psi_decl_arg *darg,
+ struct psi_call_frame_argument *frame_arg,
+ struct psi_let_exp *inner_let_exp, void *container,
+ struct psi_call_frame *frame)
+{
+ zval *zval_ptr = NULL;
+ psi_marshal_let let_fn;
+ size_t i = 0, size;
+ struct psi_decl_var *dvar;