diff options
author | Bram Moolenaar <Bram@vim.org> | 2023-01-16 20:47:57 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2023-01-16 20:47:57 +0000 |
commit | f7d1c6e1884c76680980571f1cf15e0928d247b5 (patch) | |
tree | 15b36b84c50a3a6c9aa0a7cf407c2e11abf6dce0 | |
parent | b391e1f805fdd288cbe9103d92c21eff5dcc97c4 (diff) | |
download | vim-git-f7d1c6e1884c76680980571f1cf15e0928d247b5.tar.gz |
patch 9.0.1211: storing value in interface member does not always workv9.0.1211
Problem: Storing value in interface member does not always work.
Solution: Convert the index on the interface to the index on the object.
-rw-r--r-- | src/testdir/test_vim9_class.vim | 8 | ||||
-rw-r--r-- | src/version.c | 2 | ||||
-rw-r--r-- | src/vim9.h | 10 | ||||
-rw-r--r-- | src/vim9compile.c | 17 | ||||
-rw-r--r-- | src/vim9execute.c | 10 | ||||
-rw-r--r-- | src/vim9instr.c | 5 |
6 files changed, 44 insertions, 8 deletions
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index ee10a3c8d..dadd3e4df 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -876,14 +876,14 @@ def Test_class_implements_interface() vim9script interface Result - this.label: string + public this.label: string this.errpos: number endinterface # order of members is opposite of interface class Failure implements Result this.errpos: number = 42 - this.label: string = 'label' + public this.label: string = 'label' endclass def Test() @@ -891,6 +891,10 @@ def Test_class_implements_interface() assert_equal('label', result.label) assert_equal(42, result.errpos) + + result.label = 'different' + assert_equal('different', result.label) + assert_equal(42, result.errpos) enddef Test() diff --git a/src/version.c b/src/version.c index c489dba9e..a38801961 100644 --- a/src/version.c +++ b/src/version.c @@ -696,6 +696,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1211, +/**/ 1210, /**/ 1209, diff --git a/src/vim9.h b/src/vim9.h index 68bef2eb5..f1c453017 100644 --- a/src/vim9.h +++ b/src/vim9.h @@ -78,8 +78,8 @@ typedef enum { // ISN_STOREOTHER, // pop into other script variable isn_arg.other. ISN_STORENR, // store number into local variable isn_arg.storenr.stnr_idx - ISN_STOREINDEX, // store into list or dictionary, type isn_arg.vartype, - // value/index/variable on stack + ISN_STOREINDEX, // store into list or dictionary, using + // isn_arg.storeindex; value/index/variable on stack ISN_STORERANGE, // store into blob, // value/index 1/index 2/variable on stack @@ -486,6 +486,11 @@ typedef struct { class_T *cm_class; int cm_idx; } classmember_T; +// arguments to ISN_STOREINDEX +typedef struct { + vartype_T si_vartype; + class_T *si_class; +} storeindex_T; /* * Instruction @@ -540,6 +545,7 @@ struct isn_S { echowin_T echowin; construct_T construct; classmember_T classmember; + storeindex_T storeindex; } isn_arg; }; diff --git a/src/vim9compile.c b/src/vim9compile.c index 77945fbfd..c89c37aab 100644 --- a/src/vim9compile.c +++ b/src/vim9compile.c @@ -2178,7 +2178,22 @@ compile_assign_unlet( if (isn == NULL) return FAIL; - isn->isn_arg.vartype = dest_type; + isn->isn_arg.storeindex.si_vartype = dest_type; + isn->isn_arg.storeindex.si_class = NULL; + + if (dest_type == VAR_OBJECT) + { + class_T *cl = (class_T *)lhs->lhs_type->tt_member; + + if (cl->class_flags & CLASS_INTERFACE) + { + // "this.value": load "this" object and get the value + // at index for an object or class member get the type + // of the member + isn->isn_arg.storeindex.si_class = cl; + ++cl->class_refcount; + } + } } } else if (range) diff --git a/src/vim9execute.c b/src/vim9execute.c index dd2dbe0aa..d0dbefc43 100644 --- a/src/vim9execute.c +++ b/src/vim9execute.c @@ -2108,7 +2108,7 @@ handle_debug(isn_T *iptr, ectx_T *ectx) static int execute_storeindex(isn_T *iptr, ectx_T *ectx) { - vartype_T dest_type = iptr->isn_arg.vartype; + vartype_T dest_type = iptr->isn_arg.storeindex.si_vartype; typval_T *tv; typval_T *tv_idx = STACK_TV_BOT(-2); typval_T *tv_dest = STACK_TV_BOT(-1); @@ -2243,6 +2243,12 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx) long idx = (long)tv_idx->vval.v_number; object_T *obj = tv_dest->vval.v_object; typval_T *otv = (typval_T *)(obj + 1); + + class_T *itf = iptr->isn_arg.storeindex.si_class; + if (itf != NULL) + // convert interface member index to class member index + idx = object_index_from_itf_index(itf, idx, obj->obj_class); + clear_tv(&otv[idx]); otv[idx] = *tv; } @@ -6475,7 +6481,7 @@ list_instructions(char *pfx, isn_T *instr, int instr_count, ufunc_T *ufunc) case ISN_STOREINDEX: smsg("%s%4d STOREINDEX %s", pfx, current, - vartype_name(iptr->isn_arg.vartype)); + vartype_name(iptr->isn_arg.storeindex.si_vartype)); break; case ISN_STORERANGE: diff --git a/src/vim9instr.c b/src/vim9instr.c index 89f12430a..8b1170571 100644 --- a/src/vim9instr.c +++ b/src/vim9instr.c @@ -2521,6 +2521,10 @@ delete_instr(isn_T *isn) class_unref(isn->isn_arg.classmember.cm_class); break; + case ISN_STOREINDEX: + class_unref(isn->isn_arg.storeindex.si_class); + break; + case ISN_TRY: vim_free(isn->isn_arg.tryref.try_ref); break; @@ -2622,7 +2626,6 @@ delete_instr(isn_T *isn) case ISN_SLICE: case ISN_SOURCE: case ISN_STORE: - case ISN_STOREINDEX: case ISN_STORENR: case ISN_STOREOUTER: case ISN_STORE_THIS: |