diff src/vim9execute.c @ 33393:016d8f863230 v9.0.1955

patch 9.0.1955: Vim9: lockvar issues with objects/classes Commit: https://github.com/vim/vim/commit/ee865f37acab6cac2cee6a171d60e1b365f852b0 Author: Ernie Rael <errael@raelity.com> Date: Fri Sep 29 19:53:55 2023 +0200 patch 9.0.1955: Vim9: lockvar issues with objects/classes Problem: Vim9: lockvar issues with objects/classes Solution: fix `get_lhs()` object/class access and avoid `SEGV`, make error messages more accurate. - `get_lval()` detects/returns object/class access - `compile_lock_unlock()` generate code for bare static and obj_arg access - `do_lock_var()` check lval for `ll_object`/`ll_class` and fail if so. Details: - Add `ll_object`/`ll_class`/`ll_oi` to `lval_T`. - Add `lockunlock_T` to `isn_T` for `is_arg` to specify handling of `lval_root` in `get_lval()`. - In `get_lval()`, fill in `ll_object`/`ll_class`/`ll_oi` as needed; when no `[idx] or .key`, check lval_root on the way out. - In `do_lock_var()` check for `ll_object`/`ll_class`; also bullet proof ll_dict case and give `Dictionay required` if problem. (not needed to avoid lockvar crash anymore) - In `compile_lock_unlock()` compile for the class variable and func arg cases. closes: #13174 Signed-off-by: Christian Brabandt <cb@256bit.org> Co-authored-by: Ernie Rael <errael@raelity.com>
author Christian Brabandt <cb@256bit.org>
date Fri, 29 Sep 2023 20:00:07 +0200
parents 577ef266309d
children 4a62e78803db
line wrap: on
line diff
--- a/src/vim9execute.c
+++ b/src/vim9execute.c
@@ -1957,7 +1957,7 @@ fill_partial_and_closure(
  * Execute iptr->isn_arg.string as an Ex command.
  */
     static int
-exec_command(isn_T *iptr)
+exec_command(isn_T *iptr, char_u *cmd_string)
 {
     source_cookie_T cookie;
 
@@ -1965,8 +1965,7 @@ exec_command(isn_T *iptr)
     // 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,
+    if (do_cmdline(cmd_string, getsourceline, &cookie,
 			     DOCMD_VERBOSE|DOCMD_NOWAIT|DOCMD_KEYTYPED) == FAIL
 		|| did_emsg)
 	return FAIL;
@@ -3182,7 +3181,7 @@ exec_instructions(ectx_T *ectx)
 
 	    // execute Ex command line
 	    case ISN_EXEC:
-		if (exec_command(iptr) == FAIL)
+		if (exec_command(iptr, iptr->isn_arg.string) == FAIL)
 		    goto on_error;
 		break;
 
@@ -4179,16 +4178,24 @@ exec_instructions(ectx_T *ectx)
 
 	    case ISN_LOCKUNLOCK:
 		{
+		    // TODO: could put lval_root info in struct
 		    typval_T	*lval_root_save = lval_root;
+		    int		lval_root_is_arg_save = lval_root_is_arg;
 		    int		res;
+#ifdef LOG_LOCKVAR
+		    ch_log(NULL, "LKVAR: execute INS_LOCKUNLOCK isn_arg %s",
+							iptr->isn_arg.string);
+#endif
 
 		    // 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);
+		    lval_root_is_arg = iptr->isn_arg.lockunlock.is_arg;
+		    res = exec_command(iptr, iptr->isn_arg.lockunlock.string);
 		    clear_tv(lval_root);
 		    lval_root = lval_root_save;
+		    lval_root_is_arg = lval_root_is_arg_save;
 		    if (res == FAIL)
 			goto on_error;
 		}