def METHOD_NAME(proc, argv, arg0_loc, mem, errfmt):
    # type: (Proc, List[str], loc_t, state.Mem, ui.ErrorFormatter) -> int
    UP_sig = proc.sig
    if UP_sig.tag() != proc_sig_e.Closed:  # proc is-closed ()
        return 0
    sig = cast(proc_sig.Closed, UP_sig)
    num_args = len(argv)
    for i, p in enumerate(sig.word_params):
        # proc p(out Ref)
        is_out_param = (p.type is not None and p.type.name == 'Ref')
        #log('is_out %s', is_out_param)
        param_name = p.name  # may get hidden __
        if i < num_args:
            arg_str = argv[i]
            # If we have myproc(p), and call it with myproc :arg, then bind
            # __p to 'arg'.  That is, the param has a prefix ADDED, and the arg
            # has a prefix REMOVED.
            #
            # This helps eliminate "nameref cycles".
            if is_out_param:
                param_name = '__' + param_name
                if not arg_str.startswith(':'):
                    # TODO: Point to the exact argument.  We got argv but not
                    # locations.
                    e_die('Ref param %r expected arg starting with colon : but got %r' %
                          (p.name, arg_str))
                arg_str = arg_str[1:]
            val = value.Str(arg_str)  # type: value_t
            #log('%s -> %s', param_name, val)
        else:
            # default args were evaluated on definition
            val = proc.defaults[i]
            if val is None:
                e_die("No value provided for param %r" % p.name, p.blame_tok)
        if is_out_param:
            flags = state.SetNameref
        else:
            flags = 0
        #log('flags %s', flags)
        mem.SetValue(lvalue.Named(param_name, p.blame_tok),
                     val,
                     scope_e.LocalOnly,
                     flags=flags)
    num_params = len(sig.word_params)
    if sig.rest_of_words:
        r = sig.rest_of_words
        lval = lvalue.Named(r.name, r.blame_tok)
        items = [value.Str(s) for s in argv[num_params:]]  # type: List[value_t]
        rest_val = value.List(items)
        mem.SetValue(lval, rest_val, scope_e.LocalOnly)
    else:
        if num_args > num_params:
            # TODO: Raise an exception?
            errfmt.Print_(
                "proc %r expected %d arguments, but got %d" %
                (proc.name, num_params, num_args), arg0_loc)
            # This should be status 2 because it's like a usage error.
            return 2
    return 0