patch 8.2.3339: Vim9: cannot lock a member in a local dict
Problem: Vim9: cannot lock a member in a local dict.
Solution: Get the local dict from the stack and pass it to get_lval().
diff --git a/src/vim9execute.c b/src/vim9execute.c
index 84de4fe..04d5e5f 100644
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1396,6 +1396,27 @@
return OK;
}
+/*
+ * Execute iptr->isn_arg.string as an Ex command.
+ */
+ static int
+exec_command(isn_T *iptr)
+{
+ source_cookie_T cookie;
+
+ SOURCING_LNUM = iptr->isn_lnum;
+ // Pass getsourceline to get an error for a missing ":end"
+ // command.
+ CLEAR_FIELD(cookie);
+ cookie.sourcing_lnum = iptr->isn_lnum - 1;
+ if (do_cmdline(iptr->isn_arg.string,
+ getsourceline, &cookie,
+ DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED) == FAIL
+ || did_emsg)
+ return FAIL;
+ return OK;
+}
+
// used for v_instr of typval of VAR_INSTR
struct instr_S {
ectx_T *instr_ectx;
@@ -1637,21 +1658,8 @@
{
// execute Ex command line
case ISN_EXEC:
- {
- source_cookie_T cookie;
-
- SOURCING_LNUM = iptr->isn_lnum;
- // Pass getsourceline to get an error for a missing ":end"
- // command.
- CLEAR_FIELD(cookie);
- cookie.sourcing_lnum = iptr->isn_lnum - 1;
- if (do_cmdline(iptr->isn_arg.string,
- getsourceline, &cookie,
- DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED)
- == FAIL
- || did_emsg)
- goto on_error;
- }
+ if (exec_command(iptr) == FAIL)
+ goto on_error;
break;
// execute Ex command line split at NL characters.
@@ -2880,6 +2888,23 @@
vim_unsetenv(iptr->isn_arg.unlet.ul_name);
break;
+ case ISN_LOCKUNLOCK:
+ {
+ typval_T *lval_root_save = lval_root;
+ int res;
+
+ // Stack has the local variable, argument the whole :lock
+ // or :unlock command, like ISN_EXEC.
+ --ectx->ec_stack.ga_len;
+ lval_root = STACK_TV_BOT(0);
+ res = exec_command(iptr);
+ clear_tv(lval_root);
+ lval_root = lval_root_save;
+ if (res == FAIL)
+ goto on_error;
+ }
+ break;
+
case ISN_LOCKCONST:
item_lock(STACK_TV_BOT(-1), 100, TRUE, TRUE);
break;
@@ -5244,6 +5269,9 @@
case ISN_UNLETRANGE:
smsg("%s%4d UNLETRANGE", pfx, current);
break;
+ case ISN_LOCKUNLOCK:
+ smsg("%s%4d LOCKUNLOCK %s", pfx, current, iptr->isn_arg.string);
+ break;
case ISN_LOCKCONST:
smsg("%s%4d LOCKCONST", pfx, current);
break;