patch 8.2.1900: Vim9: command modifiers do not work

Problem:    Vim9: command modifiers do not work.
Solution:   Make most command modifiers work.
diff --git a/src/vim9compile.c b/src/vim9compile.c
index 7ce55d0..60b55d5 100644
--- a/src/vim9compile.c
+++ b/src/vim9compile.c
@@ -142,7 +142,7 @@
     garray_T	ctx_type_stack;	    // type of each item on the stack
     garray_T	*ctx_type_list;	    // list of pointers to allocated types
 
-    int		ctx_silent;	    // set when ISN_SILENT was generated
+    int		ctx_has_cmdmod;	    // ISN_CMDMOD was generated
 };
 
 static void delete_def_function_contents(dfunc_T *dfunc);
@@ -1823,36 +1823,45 @@
 }
 
 /*
- * Generate any instructions for side effects of "cmdmod".
+ * Generate an instruction for any command modifiers.
  */
     static int
 generate_cmdmods(cctx_T *cctx, cmdmod_T *cmod)
 {
     isn_T	*isn;
 
-    // TODO: use more modifiers in the command
-    if (cmod->cmod_flags & (CMOD_SILENT | CMOD_ERRSILENT))
+    if (cmod->cmod_flags != 0
+	    || cmod->cmod_split != 0
+	    || cmod->cmod_verbose != 0
+	    || cmod->cmod_tab != 0
+	    || cmod->cmod_filter_regmatch.regprog != NULL)
     {
-	if ((isn = generate_instr(cctx, ISN_SILENT)) == NULL)
+	cctx->ctx_has_cmdmod = TRUE;
+
+	if ((isn = generate_instr(cctx, ISN_CMDMOD)) == NULL)
 	    return FAIL;
-	isn->isn_arg.number = (cmod->cmod_flags & CMOD_ERRSILENT) != 0;
-	cctx->ctx_silent = (cmod->cmod_flags & CMOD_ERRSILENT) ? 2 : 1;
+	isn->isn_arg.cmdmod.cf_cmdmod = ALLOC_ONE(cmdmod_T);
+	if (isn->isn_arg.cmdmod.cf_cmdmod == NULL)
+	    return FAIL;
+	mch_memmove(isn->isn_arg.cmdmod.cf_cmdmod, cmod, sizeof(cmdmod_T));
+	// filter progam now belongs to the instruction
+	cmod->cmod_filter_regmatch.regprog = NULL;
     }
+
     return OK;
 }
 
     static int
-generate_restore_cmdmods(cctx_T *cctx)
+generate_undo_cmdmods(cctx_T *cctx)
 {
     isn_T	*isn;
 
-    if (cctx->ctx_silent > 0)
+    if (cctx->ctx_has_cmdmod)
     {
-	if ((isn = generate_instr(cctx, ISN_UNSILENT)) == NULL)
+	if ((isn = generate_instr(cctx, ISN_CMDMOD_REV)) == NULL)
 	    return FAIL;
-	isn->isn_arg.number = cctx->ctx_silent == 2;
-	cctx->ctx_silent = 0;
     }
+
     return OK;
 }
 
@@ -7092,9 +7101,9 @@
     for (;;)
     {
 	exarg_T	    ea;
-	cmdmod_T    local_cmdmod;
 	int	    starts_with_colon = FALSE;
 	char_u	    *cmd;
+	cmdmod_T    local_cmdmod;
 
 	// Bail out on the first error to avoid a flood of errors and report
 	// the right line number when inside try/catch.
@@ -7175,7 +7184,7 @@
 	/*
 	 * COMMAND MODIFIERS
 	 */
-	CLEAR_FIELD(local_cmdmod);
+	cctx.ctx_has_cmdmod = FALSE;
 	if (parse_command_modifiers(&ea, &errormsg, &local_cmdmod, FALSE)
 								       == FAIL)
 	{
@@ -7497,7 +7506,7 @@
 	line = skipwhite(line);
 
 	// Undo any command modifiers.
-	generate_restore_cmdmods(&cctx);
+	generate_undo_cmdmods(&cctx);
 
 	if (cctx.ctx_type_stack.ga_len < 0)
 	{
@@ -7742,6 +7751,12 @@
 	    free_type(isn->isn_arg.type.ct_type);
 	    break;
 
+	case ISN_CMDMOD:
+	    vim_regfree(isn->isn_arg.cmdmod.cf_cmdmod
+					       ->cmod_filter_regmatch.regprog);
+	    vim_free(isn->isn_arg.cmdmod.cf_cmdmod);
+	    break;
+
 	case ISN_2BOOL:
 	case ISN_2STRING:
 	case ISN_2STRING_ANY:
@@ -7754,6 +7769,7 @@
 	case ISN_CATCH:
 	case ISN_CHECKLEN:
 	case ISN_CHECKNR:
+	case ISN_CMDMOD_REV:
 	case ISN_COMPAREANY:
 	case ISN_COMPAREBLOB:
 	case ISN_COMPAREBOOL:
@@ -7805,7 +7821,6 @@
 	case ISN_PUT:
 	case ISN_RETURN:
 	case ISN_SHUFFLE:
-	case ISN_SILENT:
 	case ISN_SLICE:
 	case ISN_STORE:
 	case ISN_STOREDICT:
@@ -7819,7 +7834,6 @@
 	case ISN_STRSLICE:
 	case ISN_THROW:
 	case ISN_TRY:
-	case ISN_UNSILENT:
 	    // nothing allocated
 	    break;
     }