patch 8.2.2677: Vim9: cannot use only some of the default arguments

Problem:    Vim9: cannot use only some of the default arguments.
Solution:   Use v:none to use default argument value.  Remove
            uf_def_arg_idx[], use JUMP_IF_ARG_SET. (closes #6504)
diff --git a/src/vim9execute.c b/src/vim9execute.c
index b80d533..f15b93d 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -97,35 +97,6 @@
 }
 
 /*
- * Set the instruction index, depending on omitted arguments, where the default
- * values are to be computed.  If all optional arguments are present, start
- * with the function body.
- * The expression evaluation is at the start of the instructions:
- *  0 ->  EVAL default1
- *	       STORE arg[-2]
- *  1 ->  EVAL default2
- *	       STORE arg[-1]
- *  2 ->  function body
- */
-    static void
-init_instr_idx(ufunc_T *ufunc, int argcount, ectx_T *ectx)
-{
-    if (ufunc->uf_def_args.ga_len == 0)
-	ectx->ec_iidx = 0;
-    else
-    {
-	int	defcount = ufunc->uf_args.ga_len - argcount;
-
-	// If there is a varargs argument defcount can be negative, no defaults
-	// to evaluate then.
-	if (defcount < 0)
-	    defcount = 0;
-	ectx->ec_iidx = ufunc->uf_def_arg_idx[
-					 ufunc->uf_def_args.ga_len - defcount];
-    }
-}
-
-/*
  * Create a new list from "count" items at the bottom of the stack.
  * When "count" is zero an empty list is added to the stack.
  */
@@ -363,8 +334,8 @@
 	current_sctx.sc_sid = ufunc->uf_script_ctx.sc_sid;
     }
 
-    // Decide where to start execution, handles optional arguments.
-    init_instr_idx(ufunc, argcount, ectx);
+    // Start execution at the first instruction.
+    ectx->ec_iidx = 0;
 
     return OK;
 }
@@ -1367,11 +1338,21 @@
 	    && (ufunc->uf_va_name != NULL || idx < ufunc->uf_args.ga_len);
 									 ++idx)
     {
-	if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len
-		&& check_typval_arg_type(ufunc->uf_arg_types[idx], &argv[idx],
-							      idx + 1) == FAIL)
-	    goto failed_early;
-	copy_tv(&argv[idx], STACK_TV_BOT(0));
+	if (idx >= ufunc->uf_args.ga_len - ufunc->uf_def_args.ga_len
+		&& argv[idx].v_type == VAR_SPECIAL
+		&& argv[idx].vval.v_number == VVAL_NONE)
+	{
+	    // Use the default value.
+	    STACK_TV_BOT(0)->v_type = VAR_UNKNOWN;
+	}
+	else
+	{
+	    if (ufunc->uf_arg_types != NULL && idx < ufunc->uf_args.ga_len
+		    && check_typval_arg_type(
+			ufunc->uf_arg_types[idx], &argv[idx], idx + 1) == FAIL)
+		goto failed_early;
+	    copy_tv(&argv[idx], STACK_TV_BOT(0));
+	}
 	++ectx.ec_stack.ga_len;
     }
 
@@ -1505,8 +1486,8 @@
     where.wt_index = 0;
     where.wt_variable = FALSE;
 
-    // Decide where to start execution, handles optional arguments.
-    init_instr_idx(ufunc, argc, &ectx);
+    // Start execution at the first instruction.
+    ectx.ec_iidx = 0;
 
     for (;;)
     {
@@ -2738,6 +2719,16 @@
 		}
 		break;
 
+	    // Jump if an argument with a default value was already set and not
+	    // v:none.
+	    case ISN_JUMP_IF_ARG_SET:
+		tv = STACK_TV_VAR(iptr->isn_arg.jumparg.jump_arg_off);
+		if (tv->v_type != VAR_UNKNOWN
+			&& !(tv->v_type == VAR_SPECIAL
+					    && tv->vval.v_number == VVAL_NONE))
+		    ectx.ec_iidx = iptr->isn_arg.jumparg.jump_where;
+		break;
+
 	    // top of a for loop
 	    case ISN_FOR:
 		{
@@ -4517,6 +4508,12 @@
 		}
 		break;
 
+	    case ISN_JUMP_IF_ARG_SET:
+		smsg("%4d JUMP_IF_ARG_SET arg[%d] -> %d", current,
+			 iptr->isn_arg.jumparg.jump_arg_off + STACK_FRAME_SIZE,
+						iptr->isn_arg.jump.jump_where);
+		break;
+
 	    case ISN_FOR:
 		{
 		    forloop_T *forloop = &iptr->isn_arg.forloop;