Mercurial > vim
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; }