Mercurial > vim
comparison src/vim9execute.c @ 33532:f99f5a56ff27 v9.0.2015
patch 9.0.2015: Vim9: does not handle islocked() from a method correctly
Commit: https://github.com/vim/vim/commit/4c8da025ef8140168b7a09d9fe922ce4bb40f19d
Author: Ernie Rael <errael@raelity.com>
Date: Wed Oct 11 21:35:11 2023 +0200
patch 9.0.2015: Vim9: does not handle islocked() from a method correctly
Problem: Vim9: does not handle islocked() from a method correctly
Solution: Handle islocked() builtin from a method.
- Setup `lval_root` from `f_islocked()`.
- Add function `fill_exec_lval_root()` to get info about executing method.
- `sync_root` added in get_lval to handle method member access.
- Conservative approach to reference counting.
closes: #13309
Signed-off-by: Christian Brabandt <cb@256bit.org>
Co-authored-by: Ernie Rael <errael@raelity.com>
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Wed, 11 Oct 2023 21:45:04 +0200 |
parents | c7c630759e31 |
children | 86dbcbb94fdb |
comparison
equal
deleted
inserted
replaced
33531:1a769647d661 | 33532:f99f5a56ff27 |
---|---|
921 */ | 921 */ |
922 int | 922 int |
923 in_def_function(void) | 923 in_def_function(void) |
924 { | 924 { |
925 return current_ectx != NULL; | 925 return current_ectx != NULL; |
926 } | |
927 | |
928 /* | |
929 * If executing a class/object method, then fill in the lval_T. | |
930 * Set lr_tv to the executing item, and lr_exec_class to the executing class; | |
931 * use free_tv and class_unref when finished with the lval_root. | |
932 * For use by builtin functions. | |
933 * | |
934 * Return FAIL and do nothing if not executing in a class; otherwise OK. | |
935 */ | |
936 int | |
937 fill_exec_lval_root(lval_root_T *root) | |
938 { | |
939 ectx_T *ectx = current_ectx; | |
940 if (ectx != NULL) | |
941 { | |
942 dfunc_T *dfunc = ((dfunc_T *)def_functions.ga_data) | |
943 + current_ectx->ec_dfunc_idx; | |
944 ufunc_T *ufunc = dfunc->df_ufunc; | |
945 if (ufunc->uf_class != NULL) // executing a method? | |
946 { | |
947 typval_T *tv = alloc_tv(); | |
948 if (tv != NULL) | |
949 { | |
950 CLEAR_POINTER(root); | |
951 root->lr_tv = tv; | |
952 copy_tv(STACK_TV_VAR(0), root->lr_tv); | |
953 root->lr_cl_exec = ufunc->uf_class; | |
954 ++root->lr_cl_exec->class_refcount; | |
955 return OK; | |
956 } | |
957 } | |
958 } | |
959 | |
960 return FAIL; | |
926 } | 961 } |
927 | 962 |
928 /* | 963 /* |
929 * Clear "current_ectx" and return the previous value. To be used when calling | 964 * Clear "current_ectx" and return the previous value. To be used when calling |
930 * a user function. | 965 * a user function. |
4183 vim_unsetenv_ext(iptr->isn_arg.unlet.ul_name); | 4218 vim_unsetenv_ext(iptr->isn_arg.unlet.ul_name); |
4184 break; | 4219 break; |
4185 | 4220 |
4186 case ISN_LOCKUNLOCK: | 4221 case ISN_LOCKUNLOCK: |
4187 { | 4222 { |
4188 lval_root_T *lval_root_save = lval_root; | |
4189 int res; | |
4190 #ifdef LOG_LOCKVAR | 4223 #ifdef LOG_LOCKVAR |
4191 ch_log(NULL, "LKVAR: execute INS_LOCKUNLOCK isn_arg %s", | 4224 ch_log(NULL, "LKVAR: execute INS_LOCKUNLOCK isn_arg %s", |
4192 iptr->isn_arg.string); | 4225 iptr->isn_arg.string); |
4193 #endif | 4226 #endif |
4227 lval_root_T *lval_root_save = lval_root; | |
4194 | 4228 |
4195 // Stack has the local variable, argument the whole :lock | 4229 // Stack has the local variable, argument the whole :lock |
4196 // or :unlock command, like ISN_EXEC. | 4230 // or :unlock command, like ISN_EXEC. |
4197 --ectx->ec_stack.ga_len; | 4231 --ectx->ec_stack.ga_len; |
4198 lval_root_T root = { STACK_TV_BOT(0), | 4232 lval_root_T root = { .lr_tv = STACK_TV_BOT(0), |
4199 iptr->isn_arg.lockunlock.lu_cl_exec, | 4233 .lr_cl_exec = iptr->isn_arg.lockunlock.lu_cl_exec, |
4200 iptr->isn_arg.lockunlock.lu_is_arg }; | 4234 .lr_is_arg = iptr->isn_arg.lockunlock.lu_is_arg }; |
4201 lval_root = &root; | 4235 lval_root = &root; |
4202 res = exec_command(iptr, | 4236 int res = exec_command(iptr, |
4203 iptr->isn_arg.lockunlock.lu_string); | 4237 iptr->isn_arg.lockunlock.lu_string); |
4204 clear_tv(root.lr_tv); | 4238 clear_tv(root.lr_tv); |
4205 lval_root = lval_root_save; | 4239 lval_root = lval_root_save; |
4206 if (res == FAIL) | 4240 if (res == FAIL) |
4207 goto on_error; | 4241 goto on_error; |