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;