summaryrefslogtreecommitdiffstats
path: root/src/vim9cmds.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/vim9cmds.c')
-rw-r--r--src/vim9cmds.c43
1 files changed, 31 insertions, 12 deletions
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index 0d6dc01f9f..0be207795f 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -212,11 +212,20 @@ compile_lock_unlock(
if (p[1] != ':')
{
char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START);
- // If name is is locally accessible, except for local var,
+
+ // The most important point is that something like
+ // name[idx].member... needs to be resolved at runtime, get_lval(),
+ // starting from the root "name".
+
+ // These checks are reminiscent of the variable_exists function.
+ // But most of the matches require special handling.
+
+ // If bare name is is locally accessible, except for local var,
// then put it on the stack to use with ISN_LOCKUNLOCK.
// This could be v.memb, v[idx_key]; bare class variable,
- // function arg. The local variable on the stack, will be passed
- // to ex_lockvar() indirectly.
+ // function arg. The item on the stack, will be passed
+ // to ex_lockvar() indirectly and be used as the root for get_lval.
+ // A bare script variable name needs no special handling.
char_u *name = NULL;
int len = end - p;
@@ -233,7 +242,7 @@ compile_lock_unlock(
// Push the local on the stack, could be "this".
name = p;
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... lookup_local: name %s", name);
+ ch_log(NULL, "LKVAR: ... lookup_local: name %s", name);
#endif
}
if (name == NULL)
@@ -247,7 +256,7 @@ compile_lock_unlock(
name = cl->class_name;
len = STRLEN(name);
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... cctx_class_member: name %s",
+ ch_log(NULL, "LKVAR: ... cctx_class_member: name %s",
name);
#endif
}
@@ -255,23 +264,33 @@ compile_lock_unlock(
}
if (name == NULL)
{
- int idx;
- type_T *type;
// Can lockvar any function arg.
- // TODO: test arg[idx]/arg.member
- if (arg_exists(p, len, &idx, &type, NULL, cctx) == OK)
+ if (arg_exists(p, len, NULL, NULL, NULL, cctx) == OK)
{
name = p;
is_arg = TRUE;
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... arg_exists: name %s", name);
+ ch_log(NULL, "LKVAR: ... arg_exists: name %s", name);
+#endif
+ }
+ }
+ if (name == NULL)
+ {
+ // No special handling for a bare script variable; but
+ // if followed by '[' or '.', it's a root for get_lval().
+ if (script_var_exists(p, len, cctx, NULL) == OK
+ && (*end == '.' || *end == '['))
+ {
+ name = p;
+#ifdef LOG_LOCKVAR
+ ch_log(NULL, "LKVAR: ... script_var_exists: name %s", name);
#endif
}
}
if (name != NULL)
{
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... INS_LOCKUNLOCK %s", name);
+ ch_log(NULL, "LKVAR: ... INS_LOCKUNLOCK %s", name);
#endif
if (compile_load(&name, name + len, cctx, FALSE, FALSE) == FAIL)
return FAIL;
@@ -292,7 +311,7 @@ compile_lock_unlock(
else
vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p);
#ifdef LOG_LOCKVAR
- ch_log(NULL, "LKVAR: compile... buf %s", buf);
+ ch_log(NULL, "LKVAR: ... buf %s", buf);
#endif
if (isn == ISN_LOCKUNLOCK)
ret = generate_LOCKUNLOCK(cctx, buf, is_arg);