Mercurial > vim
comparison src/vim9execute.c @ 24796:7c1375eb1636 v8.2.2936
patch 8.2.2936: Vim9: converting number to bool uses wrong stack offset
Commit: https://github.com/vim/vim/commit/5fa9b24440d677c1aa00084d0cf84638b1e1a0d5
Author: Bram Moolenaar <Bram@vim.org>
Date: Fri Jun 4 21:00:32 2021 +0200
patch 8.2.2936: Vim9: converting number to bool uses wrong stack offset
Problem: Vim9: converting number to bool uses wrong stack offset. (Salman
Halim)
Solution: Include the offset in the 2BOOL command.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Fri, 04 Jun 2021 21:15:04 +0200 |
parents | 982516c8d692 |
children | 28127371aa18 |
comparison
equal
deleted
inserted
replaced
24795:05a337d1fe73 | 24796:7c1375eb1636 |
---|---|
978 /* | 978 /* |
979 * Convert "tv" to a string. | 979 * Convert "tv" to a string. |
980 * Return FAIL if not allowed. | 980 * Return FAIL if not allowed. |
981 */ | 981 */ |
982 static int | 982 static int |
983 do_2string(typval_T *tv, int is_2string_any) | 983 do_2string(typval_T *tv, int is_2string_any, int tolerant) |
984 { | 984 { |
985 if (tv->v_type != VAR_STRING) | 985 if (tv->v_type != VAR_STRING) |
986 { | 986 { |
987 char_u *str; | 987 char_u *str; |
988 | 988 |
993 case VAR_SPECIAL: | 993 case VAR_SPECIAL: |
994 case VAR_BOOL: | 994 case VAR_BOOL: |
995 case VAR_NUMBER: | 995 case VAR_NUMBER: |
996 case VAR_FLOAT: | 996 case VAR_FLOAT: |
997 case VAR_BLOB: break; | 997 case VAR_BLOB: break; |
998 | |
999 case VAR_LIST: | |
1000 if (tolerant) | |
1001 { | |
1002 char_u *p; | |
1003 | |
1004 str = typval2string(tv, TRUE); | |
1005 clear_tv(tv); | |
1006 tv->v_type = VAR_STRING; | |
1007 tv->vval.v_string = str; | |
1008 // TODO: escaping | |
1009 while ((p = vim_strchr(str, '\n')) != NULL) | |
1010 *p = ' '; | |
1011 return OK; | |
1012 } | |
1013 // FALLTHROUGH | |
998 default: to_string_error(tv->v_type); | 1014 default: to_string_error(tv->v_type); |
999 return FAIL; | 1015 return FAIL; |
1000 } | 1016 } |
1001 } | 1017 } |
1002 str = typval_tostring(tv, TRUE); | 1018 str = typval_tostring(tv, TRUE); |
2053 SOURCING_LNUM = iptr->isn_lnum; | 2069 SOURCING_LNUM = iptr->isn_lnum; |
2054 if (dest_type == VAR_ANY) | 2070 if (dest_type == VAR_ANY) |
2055 { | 2071 { |
2056 dest_type = tv_dest->v_type; | 2072 dest_type = tv_dest->v_type; |
2057 if (dest_type == VAR_DICT) | 2073 if (dest_type == VAR_DICT) |
2058 status = do_2string(tv_idx, TRUE); | 2074 status = do_2string(tv_idx, TRUE, FALSE); |
2059 else if (dest_type == VAR_LIST | 2075 else if (dest_type == VAR_LIST |
2060 && tv_idx->v_type != VAR_NUMBER) | 2076 && tv_idx->v_type != VAR_NUMBER) |
2061 { | 2077 { |
2062 emsg(_(e_number_exp)); | 2078 emsg(_(e_number_exp)); |
2063 status = FAIL; | 2079 status = FAIL; |
3768 case ISN_COND2BOOL: | 3784 case ISN_COND2BOOL: |
3769 { | 3785 { |
3770 int n; | 3786 int n; |
3771 int error = FALSE; | 3787 int error = FALSE; |
3772 | 3788 |
3773 tv = STACK_TV_BOT(-1); | |
3774 if (iptr->isn_type == ISN_2BOOL) | 3789 if (iptr->isn_type == ISN_2BOOL) |
3775 { | 3790 { |
3791 tv = STACK_TV_BOT(iptr->isn_arg.tobool.offset); | |
3776 n = tv2bool(tv); | 3792 n = tv2bool(tv); |
3777 if (iptr->isn_arg.number) // invert | 3793 if (iptr->isn_arg.tobool.invert) |
3778 n = !n; | 3794 n = !n; |
3779 } | 3795 } |
3780 else | 3796 else |
3781 { | 3797 { |
3798 tv = STACK_TV_BOT(-1); | |
3782 SOURCING_LNUM = iptr->isn_lnum; | 3799 SOURCING_LNUM = iptr->isn_lnum; |
3783 n = tv_get_bool_chk(tv, &error); | 3800 n = tv_get_bool_chk(tv, &error); |
3784 if (error) | 3801 if (error) |
3785 goto on_error; | 3802 goto on_error; |
3786 } | 3803 } |
3791 break; | 3808 break; |
3792 | 3809 |
3793 case ISN_2STRING: | 3810 case ISN_2STRING: |
3794 case ISN_2STRING_ANY: | 3811 case ISN_2STRING_ANY: |
3795 SOURCING_LNUM = iptr->isn_lnum; | 3812 SOURCING_LNUM = iptr->isn_lnum; |
3796 if (do_2string(STACK_TV_BOT(iptr->isn_arg.number), | 3813 if (do_2string(STACK_TV_BOT(iptr->isn_arg.tostring.offset), |
3797 iptr->isn_type == ISN_2STRING_ANY) == FAIL) | 3814 iptr->isn_type == ISN_2STRING_ANY, |
3815 iptr->isn_arg.tostring.tolerant) == FAIL) | |
3798 goto on_error; | 3816 goto on_error; |
3799 break; | 3817 break; |
3800 | 3818 |
3801 case ISN_RANGE: | 3819 case ISN_RANGE: |
3802 { | 3820 { |
5120 type_name(iptr->isn_arg.type.ct_type, &tofree)); | 5138 type_name(iptr->isn_arg.type.ct_type, &tofree)); |
5121 vim_free(tofree); | 5139 vim_free(tofree); |
5122 break; | 5140 break; |
5123 } | 5141 } |
5124 case ISN_COND2BOOL: smsg("%s%4d COND2BOOL", pfx, current); break; | 5142 case ISN_COND2BOOL: smsg("%s%4d COND2BOOL", pfx, current); break; |
5125 case ISN_2BOOL: if (iptr->isn_arg.number) | 5143 case ISN_2BOOL: if (iptr->isn_arg.tobool.invert) |
5126 smsg("%s%4d INVERT (!val)", pfx, current); | 5144 smsg("%s%4d INVERT %d (!val)", pfx, current, |
5145 iptr->isn_arg.tobool.offset); | |
5127 else | 5146 else |
5128 smsg("%s%4d 2BOOL (!!val)", pfx, current); | 5147 smsg("%s%4d 2BOOL %d (!!val)", pfx, current, |
5148 iptr->isn_arg.tobool.offset); | |
5129 break; | 5149 break; |
5130 case ISN_2STRING: smsg("%s%4d 2STRING stack[%lld]", pfx, current, | 5150 case ISN_2STRING: smsg("%s%4d 2STRING stack[%lld]", pfx, current, |
5131 (varnumber_T)(iptr->isn_arg.number)); | 5151 (varnumber_T)(iptr->isn_arg.tostring.offset)); |
5132 break; | 5152 break; |
5133 case ISN_2STRING_ANY: smsg("%s%4d 2STRING_ANY stack[%lld]", pfx, current, | 5153 case ISN_2STRING_ANY: smsg("%s%4d 2STRING_ANY stack[%lld]", |
5134 (varnumber_T)(iptr->isn_arg.number)); | 5154 pfx, current, |
5155 (varnumber_T)(iptr->isn_arg.tostring.offset)); | |
5135 break; | 5156 break; |
5136 case ISN_RANGE: smsg("%s%4d RANGE %s", pfx, current, iptr->isn_arg.string); | 5157 case ISN_RANGE: smsg("%s%4d RANGE %s", pfx, current, |
5158 iptr->isn_arg.string); | |
5137 break; | 5159 break; |
5138 case ISN_PUT: | 5160 case ISN_PUT: |
5139 if (iptr->isn_arg.put.put_lnum == LNUM_VARIABLE_RANGE_ABOVE) | 5161 if (iptr->isn_arg.put.put_lnum == LNUM_VARIABLE_RANGE_ABOVE) |
5140 smsg("%s%4d PUT %c above range", | 5162 smsg("%s%4d PUT %c above range", |
5141 pfx, current, iptr->isn_arg.put.put_regname); | 5163 pfx, current, iptr->isn_arg.put.put_regname); |
5142 else if (iptr->isn_arg.put.put_lnum == LNUM_VARIABLE_RANGE) | 5164 else if (iptr->isn_arg.put.put_lnum == LNUM_VARIABLE_RANGE) |
5143 smsg("%s%4d PUT %c range", | 5165 smsg("%s%4d PUT %c range", |
5144 pfx, current, iptr->isn_arg.put.put_regname); | 5166 pfx, current, iptr->isn_arg.put.put_regname); |
5145 else | 5167 else |
5146 smsg("%s%4d PUT %c %ld", pfx, current, | 5168 smsg("%s%4d PUT %c %ld", pfx, current, |
5147 iptr->isn_arg.put.put_regname, | 5169 iptr->isn_arg.put.put_regname, |
5148 (long)iptr->isn_arg.put.put_lnum); | 5170 (long)iptr->isn_arg.put.put_lnum); |
5149 break; | 5171 break; |