• R/O
  • SSH

vim: Commit

Mirror of the Vim source from https://github.com/vim/vim


Commit MetaInfo

Revision6589dae9696ca885fffe441205be849230e9750f (tree)
Time2020-10-20 02:15:04
AuthorBram Moolenaar <Bram@vim....>
CommiterBram Moolenaar

Log Message

patch 8.2.1865: Vim9: add() does not check type of argument

Commit: https://github.com/vim/vim/commit/1dcae59957301b6b19aef49af648715f911a1378
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Oct 19 19:02:42 2020 +0200

patch 8.2.1865: Vim9: add() does not check type of argument
Problem: Vim9: add() does not check type of argument.
Solution: Inline the add() call. (closes https://github.com/vim/vim/issues/7160)

Change Summary

Incremental Difference

diff -r 89aa39d70c67 -r 6589dae9696c src/errors.h
--- a/src/errors.h Mon Oct 19 16:15:04 2020 +0200
+++ b/src/errors.h Mon Oct 19 19:15:04 2020 +0200
@@ -282,4 +282,6 @@
282282 INIT(= N_("E1128: } without {"));
283283 EXTERN char e_throw_with_empty_string[]
284284 INIT(= N_("E1129: Throw with empty string"));
285+EXTERN char e_cannot_add_to_null_list[]
286+ INIT(= N_("E1130: Cannot add to null list"));
285287 #endif
diff -r 89aa39d70c67 -r 6589dae9696c src/testdir/test_vim9_disassemble.vim
--- a/src/testdir/test_vim9_disassemble.vim Mon Oct 19 16:15:04 2020 +0200
+++ b/src/testdir/test_vim9_disassemble.vim Mon Oct 19 19:15:04 2020 +0200
@@ -273,6 +273,34 @@
273273 res)
274274 enddef
275275
276+def s:ListAdd()
277+ var l: list<number> = []
278+ add(l, 123)
279+ add(l, g:aNumber)
280+enddef
281+
282+def Test_disassemble_list_add()
283+ var res = execute('disass s:ListAdd')
284+ assert_match('<SNR>\d*_ListAdd\_s*' ..
285+ 'var l: list<number> = []\_s*' ..
286+ '\d NEWLIST size 0\_s*' ..
287+ '\d STORE $0\_s*' ..
288+ 'add(l, 123)\_s*' ..
289+ '\d LOAD $0\_s*' ..
290+ '\d PUSHNR 123\_s*' ..
291+ '\d LISTAPPEND\_s*' ..
292+ '\d DROP\_s*' ..
293+ 'add(l, g:aNumber)\_s*' ..
294+ '\d LOAD $0\_s*' ..
295+ '\d\+ LOADG g:aNumber\_s*' ..
296+ '\d\+ CHECKTYPE number stack\[-1\]\_s*' ..
297+ '\d\+ LISTAPPEND\_s*' ..
298+ '\d\+ DROP\_s*' ..
299+ '\d\+ PUSHNR 0\_s*' ..
300+ '\d\+ RETURN',
301+ res)
302+enddef
303+
276304 def s:ScriptFuncUnlet()
277305 g:somevar = "value"
278306 unlet g:somevar
@@ -803,7 +831,7 @@
803831 'res->add(i)\_s*' ..
804832 '\d LOAD $0\_s*' ..
805833 '\d LOAD $2\_s*' ..
806- '\d\+ BCALL add(argc 2)\_s*' ..
834+ '\d\+ LISTAPPEND\_s*' ..
807835 '\d\+ DROP\_s*' ..
808836 'endfor\_s*' ..
809837 '\d\+ JUMP -> \d\+\_s*' ..
diff -r 89aa39d70c67 -r 6589dae9696c src/testdir/test_vim9_func.vim
--- a/src/testdir/test_vim9_func.vim Mon Oct 19 16:15:04 2020 +0200
+++ b/src/testdir/test_vim9_func.vim Mon Oct 19 19:15:04 2020 +0200
@@ -1772,6 +1772,24 @@
17721772 list2str(l, true)->assert_equal(s)
17731773 enddef
17741774
1775+def Test_list_add()
1776+ var l: list<number> # defaults to empty list
1777+ add(l, 9)
1778+ assert_equal([9], l)
1779+
1780+ var lines =<< trim END
1781+ var l: list<number>
1782+ add(l, "x")
1783+ END
1784+ CheckDefFailure(lines, 'E1012:', 2)
1785+
1786+ lines =<< trim END
1787+ var l: list<number> = test_null_list()
1788+ add(l, 123)
1789+ END
1790+ CheckDefExecFailure(lines, 'E1130:', 2)
1791+enddef
1792+
17751793 def SID(): number
17761794 return expand('<SID>')
17771795 ->matchstr('<SNR>\zs\d\+\ze_$')
diff -r 89aa39d70c67 -r 6589dae9696c src/version.c
--- a/src/version.c Mon Oct 19 16:15:04 2020 +0200
+++ b/src/version.c Mon Oct 19 19:15:04 2020 +0200
@@ -751,6 +751,8 @@
751751 static int included_patches[] =
752752 { /* Add new patch number below this line */
753753 /**/
754+ 1865,
755+/**/
754756 1864,
755757 /**/
756758 1863,
diff -r 89aa39d70c67 -r 6589dae9696c src/vim9.h
--- a/src/vim9.h Mon Oct 19 16:15:04 2020 +0200
+++ b/src/vim9.h Mon Oct 19 19:15:04 2020 +0200
@@ -96,8 +96,8 @@
9696 ISN_ENDTRY, // take entry off from ec_trystack
9797
9898 // more expression operations
99- ISN_ADDLIST,
100- ISN_ADDBLOB,
99+ ISN_ADDLIST, // add two lists
100+ ISN_ADDBLOB, // add two blobs
101101
102102 // operation with two arguments; isn_arg.op.op_type is exptype_T
103103 ISN_OPNR,
@@ -120,6 +120,7 @@
120120 ISN_CONCAT,
121121 ISN_STRINDEX, // [expr] string index
122122 ISN_STRSLICE, // [expr:expr] string slice
123+ ISN_LISTAPPEND, // append to a list, like add()
123124 ISN_LISTINDEX, // [expr] list index
124125 ISN_LISTSLICE, // [expr:expr] list slice
125126 ISN_ANYINDEX, // [expr] runtime index
diff -r 89aa39d70c67 -r 6589dae9696c src/vim9compile.c
--- a/src/vim9compile.c Mon Oct 19 16:15:04 2020 +0200
+++ b/src/vim9compile.c Mon Oct 19 19:15:04 2020 +0200
@@ -1495,6 +1495,32 @@
14951495 }
14961496
14971497 /*
1498+ * Generate an ISN_LISTAPPEND instruction. Works like add().
1499+ * Argument count is already checked.
1500+ */
1501+ static int
1502+generate_LISTAPPEND(cctx_T *cctx)
1503+{
1504+ garray_T *stack = &cctx->ctx_type_stack;
1505+ type_T *list_type;
1506+ type_T *item_type;
1507+ type_T *expected;
1508+
1509+ // Caller already checked that list_type is a list.
1510+ list_type = ((type_T **)stack->ga_data)[stack->ga_len - 2];
1511+ item_type = ((type_T **)stack->ga_data)[stack->ga_len - 1];
1512+ expected = list_type->tt_member;
1513+ if (need_type(item_type, expected, -1, cctx, FALSE, FALSE) == FAIL)
1514+ return FAIL;
1515+
1516+ if (generate_instr(cctx, ISN_LISTAPPEND) == NULL)
1517+ return FAIL;
1518+
1519+ --stack->ga_len; // drop the argument
1520+ return OK;
1521+}
1522+
1523+/*
14981524 * Generate an ISN_DCALL or ISN_UCALL instruction.
14991525 * Return FAIL if the number of arguments is wrong.
15001526 */
@@ -2537,7 +2563,25 @@
25372563 // builtin function
25382564 idx = find_internal_func(name);
25392565 if (idx >= 0)
2540- res = generate_BCALL(cctx, idx, argcount, argcount_init == 1);
2566+ {
2567+ if (STRCMP(name, "add") == 0 && argcount == 2)
2568+ {
2569+ garray_T *stack = &cctx->ctx_type_stack;
2570+ type_T *type = ((type_T **)stack->ga_data)[
2571+ stack->ga_len - 2];
2572+
2573+ // TODO: also check for VAR_BLOB
2574+ if (type->tt_type == VAR_LIST)
2575+ {
2576+ // inline "add(list, item)" so that the type can be checked
2577+ res = generate_LISTAPPEND(cctx);
2578+ idx = -1;
2579+ }
2580+ }
2581+
2582+ if (idx >= 0)
2583+ res = generate_BCALL(cctx, idx, argcount, argcount_init == 1);
2584+ }
25412585 else
25422586 semsg(_(e_unknownfunc), namebuf);
25432587 goto theend;
@@ -7656,6 +7700,7 @@
76567700 case ISN_FOR:
76577701 case ISN_GETITEM:
76587702 case ISN_JUMP:
7703+ case ISN_LISTAPPEND:
76597704 case ISN_LISTINDEX:
76607705 case ISN_LISTSLICE:
76617706 case ISN_LOAD:
diff -r 89aa39d70c67 -r 6589dae9696c src/vim9execute.c
--- a/src/vim9execute.c Mon Oct 19 16:15:04 2020 +0200
+++ b/src/vim9execute.c Mon Oct 19 19:15:04 2020 +0200
@@ -2095,6 +2095,7 @@
20952095 || *skipwhite(tv->vval.v_string) == NUL)
20962096 {
20972097 vim_free(tv->vval.v_string);
2098+ SOURCING_LNUM = iptr->isn_lnum;
20982099 emsg(_(e_throw_with_empty_string));
20992100 goto failed;
21002101 }
@@ -2282,6 +2283,7 @@
22822283 typval_T *tv1 = STACK_TV_BOT(-2);
22832284 typval_T *tv2 = STACK_TV_BOT(-1);
22842285
2286+ // add two lists or blobs
22852287 if (iptr->isn_type == ISN_ADDLIST)
22862288 eval_addlist(tv1, tv2);
22872289 else
@@ -2291,6 +2293,25 @@
22912293 }
22922294 break;
22932295
2296+ case ISN_LISTAPPEND:
2297+ {
2298+ typval_T *tv1 = STACK_TV_BOT(-2);
2299+ typval_T *tv2 = STACK_TV_BOT(-1);
2300+ list_T *l = tv1->vval.v_list;
2301+
2302+ // add an item to a list
2303+ if (l == NULL)
2304+ {
2305+ SOURCING_LNUM = iptr->isn_lnum;
2306+ emsg(_(e_cannot_add_to_null_list));
2307+ goto on_error;
2308+ }
2309+ if (list_append_tv(l, tv2) == FAIL)
2310+ goto failed;
2311+ --ectx.ec_stack.ga_len;
2312+ }
2313+ break;
2314+
22942315 // Computation with two arguments of unknown type
22952316 case ISN_OPANY:
22962317 {
@@ -3410,6 +3431,7 @@
34103431 case ISN_CONCAT: smsg("%4d CONCAT", current); break;
34113432 case ISN_STRINDEX: smsg("%4d STRINDEX", current); break;
34123433 case ISN_STRSLICE: smsg("%4d STRSLICE", current); break;
3434+ case ISN_LISTAPPEND: smsg("%4d LISTAPPEND", current); break;
34133435 case ISN_LISTINDEX: smsg("%4d LISTINDEX", current); break;
34143436 case ISN_LISTSLICE: smsg("%4d LISTSLICE", current); break;
34153437 case ISN_ANYINDEX: smsg("%4d ANYINDEX", current); break;
Show on old repository browser