comparison src/vim9execute.c @ 28217:662d2d5db9a6

patch 8.2.4634: Vim9: cannot initialize a variable to null_list Commit: https://github.com/vim/vim/commit/ec15b1cfdc5faadb529dedda58adf7fc98c839ed Author: Bram Moolenaar <Bram@vim.org> Date: Sun Mar 27 16:29:53 2022 +0100 patch 8.2.4634: Vim9: cannot initialize a variable to null_list Problem: Vim9: cannot initialize a variable to null_list. Solution: Give negative count to NEWLIST. (closes https://github.com/vim/vim/issues/10027) Also fix inconsistencies in comparing with null values.
author Bram Moolenaar <Bram@vim.org>
date Sun, 27 Mar 2022 17:30:04 +0200
parents 088d8dc22045
children 66b245d84f37
comparison
equal deleted inserted replaced
28216:b6a02697f304 28217:662d2d5db9a6
120 } 120 }
121 121
122 /* 122 /*
123 * Create a new list from "count" items at the bottom of the stack. 123 * Create a new list from "count" items at the bottom of the stack.
124 * When "count" is zero an empty list is added to the stack. 124 * When "count" is zero an empty list is added to the stack.
125 * When "count" is -1 a NULL list is added to the stack.
125 */ 126 */
126 static int 127 static int
127 exe_newlist(int count, ectx_T *ectx) 128 exe_newlist(int count, ectx_T *ectx)
128 { 129 {
129 list_T *list = list_alloc_with_items(count); 130 list_T *list = NULL;
130 int idx; 131 int idx;
131 typval_T *tv; 132 typval_T *tv;
132 133
133 if (list == NULL) 134 if (count >= 0)
134 return FAIL; 135 {
135 for (idx = 0; idx < count; ++idx) 136 list = list_alloc_with_items(count);
136 list_set_item(list, idx, STACK_TV_BOT(idx - count)); 137 if (list == NULL)
138 return FAIL;
139 for (idx = 0; idx < count; ++idx)
140 list_set_item(list, idx, STACK_TV_BOT(idx - count));
141 }
137 142
138 if (count > 0) 143 if (count > 0)
139 ectx->ec_stack.ga_len -= count - 1; 144 ectx->ec_stack.ga_len -= count - 1;
145 else if (GA_GROW_FAILS(&ectx->ec_stack, 1))
146 {
147 list_unref(list);
148 return FAIL;
149 }
150 else
151 ++ectx->ec_stack.ga_len;
152 tv = STACK_TV_BOT(-1);
153 tv->v_type = VAR_LIST;
154 tv->vval.v_list = list;
155 if (list != NULL)
156 ++list->lv_refcount;
157 return OK;
158 }
159
160 /*
161 * Implementation of ISN_NEWDICT.
162 * Returns FAIL on total failure, MAYBE on error.
163 */
164 static int
165 exe_newdict(int count, ectx_T *ectx)
166 {
167 dict_T *dict = NULL;
168 dictitem_T *item;
169 char_u *key;
170 int idx;
171 typval_T *tv;
172
173 if (count >= 0)
174 {
175 dict = dict_alloc();
176 if (unlikely(dict == NULL))
177 return FAIL;
178 for (idx = 0; idx < count; ++idx)
179 {
180 // have already checked key type is VAR_STRING
181 tv = STACK_TV_BOT(2 * (idx - count));
182 // check key is unique
183 key = tv->vval.v_string == NULL
184 ? (char_u *)"" : tv->vval.v_string;
185 item = dict_find(dict, key, -1);
186 if (item != NULL)
187 {
188 semsg(_(e_duplicate_key_in_dicitonary), key);
189 dict_unref(dict);
190 return MAYBE;
191 }
192 item = dictitem_alloc(key);
193 clear_tv(tv);
194 if (unlikely(item == NULL))
195 {
196 dict_unref(dict);
197 return FAIL;
198 }
199 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
200 item->di_tv.v_lock = 0;
201 if (dict_add(dict, item) == FAIL)
202 {
203 // can this ever happen?
204 dict_unref(dict);
205 return FAIL;
206 }
207 }
208 }
209
210 if (count > 0)
211 ectx->ec_stack.ga_len -= 2 * count - 1;
140 else if (GA_GROW_FAILS(&ectx->ec_stack, 1)) 212 else if (GA_GROW_FAILS(&ectx->ec_stack, 1))
141 return FAIL; 213 return FAIL;
142 else 214 else
143 ++ectx->ec_stack.ga_len; 215 ++ectx->ec_stack.ga_len;
144 tv = STACK_TV_BOT(-1); 216 tv = STACK_TV_BOT(-1);
145 tv->v_type = VAR_LIST; 217 tv->v_type = VAR_DICT;
146 tv->vval.v_list = list; 218 tv->v_lock = 0;
147 ++list->lv_refcount; 219 tv->vval.v_dict = dict;
220 if (dict != NULL)
221 ++dict->dv_refcount;
148 return OK; 222 return OK;
149 } 223 }
150 224
151 /* 225 /*
152 * If debug_tick changed check if "ufunc" has a breakpoint and update 226 * If debug_tick changed check if "ufunc" has a breakpoint and update
3355 break; 3429 break;
3356 3430
3357 // create a dict from items on the stack 3431 // create a dict from items on the stack
3358 case ISN_NEWDICT: 3432 case ISN_NEWDICT:
3359 { 3433 {
3360 int count = iptr->isn_arg.number; 3434 int res;
3361 dict_T *dict = dict_alloc(); 3435
3362 dictitem_T *item; 3436 SOURCING_LNUM = iptr->isn_lnum;
3363 char_u *key; 3437 res = exe_newdict(iptr->isn_arg.number, ectx);
3364 int idx; 3438 if (res == FAIL)
3365
3366 if (unlikely(dict == NULL))
3367 goto theend; 3439 goto theend;
3368 for (idx = 0; idx < count; ++idx) 3440 if (res == MAYBE)
3369 { 3441 goto on_error;
3370 // have already checked key type is VAR_STRING
3371 tv = STACK_TV_BOT(2 * (idx - count));
3372 // check key is unique
3373 key = tv->vval.v_string == NULL
3374 ? (char_u *)"" : tv->vval.v_string;
3375 item = dict_find(dict, key, -1);
3376 if (item != NULL)
3377 {
3378 SOURCING_LNUM = iptr->isn_lnum;
3379 semsg(_(e_duplicate_key_in_dicitonary), key);
3380 dict_unref(dict);
3381 goto on_error;
3382 }
3383 item = dictitem_alloc(key);
3384 clear_tv(tv);
3385 if (unlikely(item == NULL))
3386 {
3387 dict_unref(dict);
3388 goto theend;
3389 }
3390 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
3391 item->di_tv.v_lock = 0;
3392 if (dict_add(dict, item) == FAIL)
3393 {
3394 // can this ever happen?
3395 dict_unref(dict);
3396 goto theend;
3397 }
3398 }
3399
3400 if (count > 0)
3401 ectx->ec_stack.ga_len -= 2 * count - 1;
3402 else if (GA_GROW_FAILS(&ectx->ec_stack, 1))
3403 goto theend;
3404 else
3405 ++ectx->ec_stack.ga_len;
3406 tv = STACK_TV_BOT(-1);
3407 tv->v_type = VAR_DICT;
3408 tv->v_lock = 0;
3409 tv->vval.v_dict = dict;
3410 ++dict->dv_refcount;
3411 } 3442 }
3412 break; 3443 break;
3413 3444
3414 // create a partial with NULL value 3445 // create a partial with NULL value
3415 case ISN_NEWPARTIAL: 3446 case ISN_NEWPARTIAL: