Mercurial > vim
comparison src/vim9execute.c @ 24659:982516c8d692 v8.2.2868
patch 8.2.2868: Vim9: when executing compiled expression trylevel is changed
Commit: https://github.com/vim/vim/commit/cbe178e3dc4ad45d9b2ed5e713e7c4cc88bf8b8b
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue May 18 17:49:59 2021 +0200
patch 8.2.2868: Vim9: when executing compiled expression trylevel is changed
Problem: Vim9: When executing a compiled expression the trylevel at start
is changed but not restored. (closes https://github.com/vim/vim/issues/8214)
Solution: Restore the trylevel at start.
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Tue, 18 May 2021 18:00:04 +0200 |
parents | 668df21d8bc6 |
children | 7c1375eb1636 |
comparison
equal
deleted
inserted
replaced
24658:2a206965fff4 | 24659:982516c8d692 |
---|---|
1289 static int | 1289 static int |
1290 exec_instructions(ectx_T *ectx) | 1290 exec_instructions(ectx_T *ectx) |
1291 { | 1291 { |
1292 int breakcheck_count = 0; | 1292 int breakcheck_count = 0; |
1293 typval_T *tv; | 1293 typval_T *tv; |
1294 int ret = FAIL; | |
1295 int save_trylevel_at_start = ectx->ec_trylevel_at_start; | |
1294 | 1296 |
1295 // Start execution at the first instruction. | 1297 // Start execution at the first instruction. |
1296 ectx->ec_iidx = 0; | 1298 ectx->ec_iidx = 0; |
1297 | 1299 |
1298 // Only catch exceptions in this instruction list. | 1300 // Only catch exceptions in this instruction list. |
1310 if (got_int) | 1312 if (got_int) |
1311 { | 1313 { |
1312 // Turn CTRL-C into an exception. | 1314 // Turn CTRL-C into an exception. |
1313 got_int = FALSE; | 1315 got_int = FALSE; |
1314 if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) == FAIL) | 1316 if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) == FAIL) |
1315 return FAIL; | 1317 goto theend; |
1316 did_throw = TRUE; | 1318 did_throw = TRUE; |
1317 } | 1319 } |
1318 | 1320 |
1319 if (did_emsg && msg_list != NULL && *msg_list != NULL) | 1321 if (did_emsg && msg_list != NULL && *msg_list != NULL) |
1320 { | 1322 { |
1321 // Turn an error message into an exception. | 1323 // Turn an error message into an exception. |
1322 did_emsg = FALSE; | 1324 did_emsg = FALSE; |
1323 if (throw_exception(*msg_list, ET_ERROR, NULL) == FAIL) | 1325 if (throw_exception(*msg_list, ET_ERROR, NULL) == FAIL) |
1324 return FAIL; | 1326 goto theend; |
1325 did_throw = TRUE; | 1327 did_throw = TRUE; |
1326 *msg_list = NULL; | 1328 *msg_list = NULL; |
1327 } | 1329 } |
1328 | 1330 |
1329 if (did_throw && !ectx->ec_in_catch) | 1331 if (did_throw && !ectx->ec_in_catch) |
1344 else | 1346 else |
1345 { | 1347 { |
1346 // Not inside try or need to return from current functions. | 1348 // Not inside try or need to return from current functions. |
1347 // Push a dummy return value. | 1349 // Push a dummy return value. |
1348 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1350 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1349 return FAIL; | 1351 goto theend; |
1350 tv = STACK_TV_BOT(0); | 1352 tv = STACK_TV_BOT(0); |
1351 tv->v_type = VAR_NUMBER; | 1353 tv->v_type = VAR_NUMBER; |
1352 tv->vval.v_number = 0; | 1354 tv->vval.v_number = 0; |
1353 ++ectx->ec_stack.ga_len; | 1355 ++ectx->ec_stack.ga_len; |
1354 if (ectx->ec_frame_idx == ectx->ec_initial_frame_idx) | 1356 if (ectx->ec_frame_idx == ectx->ec_initial_frame_idx) |
1355 { | 1357 { |
1356 // At the toplevel we are done. | 1358 // At the toplevel we are done. |
1357 need_rethrow = TRUE; | 1359 need_rethrow = TRUE; |
1358 if (handle_closure_in_use(ectx, FALSE) == FAIL) | 1360 if (handle_closure_in_use(ectx, FALSE) == FAIL) |
1359 return FAIL; | 1361 goto theend; |
1360 goto done; | 1362 goto done; |
1361 } | 1363 } |
1362 | 1364 |
1363 if (func_return(ectx) == FAIL) | 1365 if (func_return(ectx) == FAIL) |
1364 return FAIL; | 1366 goto theend; |
1365 } | 1367 } |
1366 continue; | 1368 continue; |
1367 } | 1369 } |
1368 | 1370 |
1369 iptr = &ectx->ec_instr[ectx->ec_iidx++]; | 1371 iptr = &ectx->ec_instr[ectx->ec_iidx++]; |
1395 char_u *arg = iptr->isn_arg.string; | 1397 char_u *arg = iptr->isn_arg.string; |
1396 int res; | 1398 int res; |
1397 int save_flags = cmdmod.cmod_flags; | 1399 int save_flags = cmdmod.cmod_flags; |
1398 | 1400 |
1399 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1401 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1400 return FAIL; | 1402 goto theend; |
1401 tv = STACK_TV_BOT(0); | 1403 tv = STACK_TV_BOT(0); |
1402 init_tv(tv); | 1404 init_tv(tv); |
1403 cmdmod.cmod_flags |= CMOD_LEGACY; | 1405 cmdmod.cmod_flags |= CMOD_LEGACY; |
1404 res = eval0(arg, tv, NULL, &EVALARG_EVALUATE); | 1406 res = eval0(arg, tv, NULL, &EVALARG_EVALUATE); |
1405 cmdmod.cmod_flags = save_flags; | 1407 cmdmod.cmod_flags = save_flags; |
1411 | 1413 |
1412 // push typeval VAR_INSTR with instructions to be executed | 1414 // push typeval VAR_INSTR with instructions to be executed |
1413 case ISN_INSTR: | 1415 case ISN_INSTR: |
1414 { | 1416 { |
1415 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1417 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1416 return FAIL; | 1418 goto theend; |
1417 tv = STACK_TV_BOT(0); | 1419 tv = STACK_TV_BOT(0); |
1418 tv->vval.v_instr = ALLOC_ONE(instr_T); | 1420 tv->vval.v_instr = ALLOC_ONE(instr_T); |
1419 if (tv->vval.v_instr == NULL) | 1421 if (tv->vval.v_instr == NULL) |
1420 goto on_error; | 1422 goto on_error; |
1421 ++ectx->ec_stack.ga_len; | 1423 ++ectx->ec_stack.ga_len; |
1478 redir_vname = 0; | 1480 redir_vname = 0; |
1479 | 1481 |
1480 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1482 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1481 { | 1483 { |
1482 vim_free(res); | 1484 vim_free(res); |
1483 return FAIL; | 1485 goto theend; |
1484 } | 1486 } |
1485 tv = STACK_TV_BOT(0); | 1487 tv = STACK_TV_BOT(0); |
1486 tv->v_type = VAR_STRING; | 1488 tv->v_type = VAR_STRING; |
1487 tv->vval.v_string = res; | 1489 tv->vval.v_string = res; |
1488 ++ectx->ec_stack.ga_len; | 1490 ++ectx->ec_stack.ga_len; |
1543 } | 1545 } |
1544 if (pass == 1) | 1546 if (pass == 1) |
1545 { | 1547 { |
1546 cmd = alloc(len + 1); | 1548 cmd = alloc(len + 1); |
1547 if (cmd == NULL) | 1549 if (cmd == NULL) |
1548 return FAIL; | 1550 goto theend; |
1549 len = 0; | 1551 len = 0; |
1550 } | 1552 } |
1551 } | 1553 } |
1552 | 1554 |
1553 SOURCING_LNUM = iptr->isn_lnum; | 1555 SOURCING_LNUM = iptr->isn_lnum; |
1663 break; | 1665 break; |
1664 | 1666 |
1665 // load local variable or argument | 1667 // load local variable or argument |
1666 case ISN_LOAD: | 1668 case ISN_LOAD: |
1667 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1669 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1668 return FAIL; | 1670 goto theend; |
1669 copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0)); | 1671 copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0)); |
1670 ++ectx->ec_stack.ga_len; | 1672 ++ectx->ec_stack.ga_len; |
1671 break; | 1673 break; |
1672 | 1674 |
1673 // load v: variable | 1675 // load v: variable |
1674 case ISN_LOADV: | 1676 case ISN_LOADV: |
1675 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1677 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1676 return FAIL; | 1678 goto theend; |
1677 copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0)); | 1679 copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0)); |
1678 ++ectx->ec_stack.ga_len; | 1680 ++ectx->ec_stack.ga_len; |
1679 break; | 1681 break; |
1680 | 1682 |
1681 // load s: variable in Vim9 script | 1683 // load s: variable in Vim9 script |
1684 scriptref_T *sref = iptr->isn_arg.script.scriptref; | 1686 scriptref_T *sref = iptr->isn_arg.script.scriptref; |
1685 svar_T *sv; | 1687 svar_T *sv; |
1686 | 1688 |
1687 sv = get_script_svar(sref, ectx); | 1689 sv = get_script_svar(sref, ectx); |
1688 if (sv == NULL) | 1690 if (sv == NULL) |
1689 return FAIL; | 1691 goto theend; |
1690 allocate_if_null(sv->sv_tv); | 1692 allocate_if_null(sv->sv_tv); |
1691 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1693 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1692 return FAIL; | 1694 goto theend; |
1693 copy_tv(sv->sv_tv, STACK_TV_BOT(0)); | 1695 copy_tv(sv->sv_tv, STACK_TV_BOT(0)); |
1694 ++ectx->ec_stack.ga_len; | 1696 ++ectx->ec_stack.ga_len; |
1695 } | 1697 } |
1696 break; | 1698 break; |
1697 | 1699 |
1710 goto on_error; | 1712 goto on_error; |
1711 } | 1713 } |
1712 else | 1714 else |
1713 { | 1715 { |
1714 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1716 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1715 return FAIL; | 1717 goto theend; |
1716 copy_tv(&di->di_tv, STACK_TV_BOT(0)); | 1718 copy_tv(&di->di_tv, STACK_TV_BOT(0)); |
1717 ++ectx->ec_stack.ga_len; | 1719 ++ectx->ec_stack.ga_len; |
1718 } | 1720 } |
1719 } | 1721 } |
1720 break; | 1722 break; |
1746 case ISN_LOADT: | 1748 case ISN_LOADT: |
1747 ht = &curtab->tp_vars->dv_hashtab; | 1749 ht = &curtab->tp_vars->dv_hashtab; |
1748 namespace = 't'; | 1750 namespace = 't'; |
1749 break; | 1751 break; |
1750 default: // Cannot reach here | 1752 default: // Cannot reach here |
1751 return FAIL; | 1753 goto theend; |
1752 } | 1754 } |
1753 di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE); | 1755 di = find_var_in_ht(ht, 0, iptr->isn_arg.string, TRUE); |
1754 | 1756 |
1755 if (di == NULL) | 1757 if (di == NULL) |
1756 { | 1758 { |
1760 goto on_error; | 1762 goto on_error; |
1761 } | 1763 } |
1762 else | 1764 else |
1763 { | 1765 { |
1764 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1766 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1765 return FAIL; | 1767 goto theend; |
1766 copy_tv(&di->di_tv, STACK_TV_BOT(0)); | 1768 copy_tv(&di->di_tv, STACK_TV_BOT(0)); |
1767 ++ectx->ec_stack.ga_len; | 1769 ++ectx->ec_stack.ga_len; |
1768 } | 1770 } |
1769 } | 1771 } |
1770 break; | 1772 break; |
1773 case ISN_LOADAUTO: | 1775 case ISN_LOADAUTO: |
1774 { | 1776 { |
1775 char_u *name = iptr->isn_arg.string; | 1777 char_u *name = iptr->isn_arg.string; |
1776 | 1778 |
1777 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1779 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1778 return FAIL; | 1780 goto theend; |
1779 SOURCING_LNUM = iptr->isn_lnum; | 1781 SOURCING_LNUM = iptr->isn_lnum; |
1780 if (eval_variable(name, (int)STRLEN(name), | 1782 if (eval_variable(name, (int)STRLEN(name), |
1781 STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL) | 1783 STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL) |
1782 goto on_error; | 1784 goto on_error; |
1783 ++ectx->ec_stack.ga_len; | 1785 ++ectx->ec_stack.ga_len; |
1797 case ISN_LOADGDICT: d = get_globvar_dict(); break; | 1799 case ISN_LOADGDICT: d = get_globvar_dict(); break; |
1798 case ISN_LOADBDICT: d = curbuf->b_vars; break; | 1800 case ISN_LOADBDICT: d = curbuf->b_vars; break; |
1799 case ISN_LOADWDICT: d = curwin->w_vars; break; | 1801 case ISN_LOADWDICT: d = curwin->w_vars; break; |
1800 case ISN_LOADTDICT: d = curtab->tp_vars; break; | 1802 case ISN_LOADTDICT: d = curtab->tp_vars; break; |
1801 default: // Cannot reach here | 1803 default: // Cannot reach here |
1802 return FAIL; | 1804 goto theend; |
1803 } | 1805 } |
1804 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1806 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1805 return FAIL; | 1807 goto theend; |
1806 tv = STACK_TV_BOT(0); | 1808 tv = STACK_TV_BOT(0); |
1807 tv->v_type = VAR_DICT; | 1809 tv->v_type = VAR_DICT; |
1808 tv->v_lock = 0; | 1810 tv->v_lock = 0; |
1809 tv->vval.v_dict = d; | 1811 tv->vval.v_dict = d; |
1810 ++d->dv_refcount; | 1812 ++d->dv_refcount; |
1819 char_u *name = iptr->isn_arg.string; | 1821 char_u *name = iptr->isn_arg.string; |
1820 | 1822 |
1821 // This is not expected to fail, name is checked during | 1823 // This is not expected to fail, name is checked during |
1822 // compilation: don't set SOURCING_LNUM. | 1824 // compilation: don't set SOURCING_LNUM. |
1823 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1825 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1824 return FAIL; | 1826 goto theend; |
1825 if (eval_option(&name, &optval, TRUE) == FAIL) | 1827 if (eval_option(&name, &optval, TRUE) == FAIL) |
1826 return FAIL; | 1828 goto theend; |
1827 *STACK_TV_BOT(0) = optval; | 1829 *STACK_TV_BOT(0) = optval; |
1828 ++ectx->ec_stack.ga_len; | 1830 ++ectx->ec_stack.ga_len; |
1829 } | 1831 } |
1830 break; | 1832 break; |
1831 | 1833 |
1834 { | 1836 { |
1835 typval_T optval; | 1837 typval_T optval; |
1836 char_u *name = iptr->isn_arg.string; | 1838 char_u *name = iptr->isn_arg.string; |
1837 | 1839 |
1838 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1840 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1839 return FAIL; | 1841 goto theend; |
1840 // name is always valid, checked when compiling | 1842 // name is always valid, checked when compiling |
1841 (void)eval_env_var(&name, &optval, TRUE); | 1843 (void)eval_env_var(&name, &optval, TRUE); |
1842 *STACK_TV_BOT(0) = optval; | 1844 *STACK_TV_BOT(0) = optval; |
1843 ++ectx->ec_stack.ga_len; | 1845 ++ectx->ec_stack.ga_len; |
1844 } | 1846 } |
1845 break; | 1847 break; |
1846 | 1848 |
1847 // load @register | 1849 // load @register |
1848 case ISN_LOADREG: | 1850 case ISN_LOADREG: |
1849 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 1851 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
1850 return FAIL; | 1852 goto theend; |
1851 tv = STACK_TV_BOT(0); | 1853 tv = STACK_TV_BOT(0); |
1852 tv->v_type = VAR_STRING; | 1854 tv->v_type = VAR_STRING; |
1853 tv->v_lock = 0; | 1855 tv->v_lock = 0; |
1854 // This may result in NULL, which should be equivalent to an | 1856 // This may result in NULL, which should be equivalent to an |
1855 // empty string. | 1857 // empty string. |
1897 scriptref_T *sref = iptr->isn_arg.script.scriptref; | 1899 scriptref_T *sref = iptr->isn_arg.script.scriptref; |
1898 svar_T *sv; | 1900 svar_T *sv; |
1899 | 1901 |
1900 sv = get_script_svar(sref, ectx); | 1902 sv = get_script_svar(sref, ectx); |
1901 if (sv == NULL) | 1903 if (sv == NULL) |
1902 return FAIL; | 1904 goto theend; |
1903 --ectx->ec_stack.ga_len; | 1905 --ectx->ec_stack.ga_len; |
1904 | 1906 |
1905 // "const" and "final" are checked at compile time, locking | 1907 // "const" and "final" are checked at compile time, locking |
1906 // the value needs to be checked here. | 1908 // the value needs to be checked here. |
1907 SOURCING_LNUM = iptr->isn_lnum; | 1909 SOURCING_LNUM = iptr->isn_lnum; |
1999 break; | 2001 break; |
2000 case ISN_STORET: | 2002 case ISN_STORET: |
2001 ht = &curtab->tp_vars->dv_hashtab; | 2003 ht = &curtab->tp_vars->dv_hashtab; |
2002 break; | 2004 break; |
2003 default: // Cannot reach here | 2005 default: // Cannot reach here |
2004 return FAIL; | 2006 goto theend; |
2005 } | 2007 } |
2006 | 2008 |
2007 --ectx->ec_stack.ga_len; | 2009 --ectx->ec_stack.ga_len; |
2008 di = find_var_in_ht(ht, 0, name, TRUE); | 2010 di = find_var_in_ht(ht, 0, name, TRUE); |
2009 if (di == NULL) | 2011 if (di == NULL) |
2104 if (error_if_locked(list->lv_lock, | 2106 if (error_if_locked(list->lv_lock, |
2105 e_cannot_change_list)) | 2107 e_cannot_change_list)) |
2106 goto on_error; | 2108 goto on_error; |
2107 // append to list, only fails when out of memory | 2109 // append to list, only fails when out of memory |
2108 if (list_append_tv(list, tv) == FAIL) | 2110 if (list_append_tv(list, tv) == FAIL) |
2109 return FAIL; | 2111 goto theend; |
2110 clear_tv(tv); | 2112 clear_tv(tv); |
2111 } | 2113 } |
2112 } | 2114 } |
2113 else if (status == OK && dest_type == VAR_DICT) | 2115 else if (status == OK && dest_type == VAR_DICT) |
2114 { | 2116 { |
2139 if (error_if_locked(dict->dv_lock, | 2141 if (error_if_locked(dict->dv_lock, |
2140 e_cannot_change_dict)) | 2142 e_cannot_change_dict)) |
2141 goto on_error; | 2143 goto on_error; |
2142 // add to dict, only fails when out of memory | 2144 // add to dict, only fails when out of memory |
2143 if (dict_add_tv(dict, (char *)key, tv) == FAIL) | 2145 if (dict_add_tv(dict, (char *)key, tv) == FAIL) |
2144 return FAIL; | 2146 goto theend; |
2145 clear_tv(tv); | 2147 clear_tv(tv); |
2146 } | 2148 } |
2147 } | 2149 } |
2148 else if (status == OK && dest_type == VAR_BLOB) | 2150 else if (status == OK && dest_type == VAR_BLOB) |
2149 { | 2151 { |
2272 } | 2274 } |
2273 if (outer == NULL) | 2275 if (outer == NULL) |
2274 { | 2276 { |
2275 SOURCING_LNUM = iptr->isn_lnum; | 2277 SOURCING_LNUM = iptr->isn_lnum; |
2276 iemsg("LOADOUTER depth more than scope levels"); | 2278 iemsg("LOADOUTER depth more than scope levels"); |
2277 return FAIL; | 2279 goto theend; |
2278 } | 2280 } |
2279 tv = ((typval_T *)outer->out_stack->ga_data) | 2281 tv = ((typval_T *)outer->out_stack->ga_data) |
2280 + outer->out_frame_idx + STACK_FRAME_SIZE | 2282 + outer->out_frame_idx + STACK_FRAME_SIZE |
2281 + iptr->isn_arg.outer.outer_idx; | 2283 + iptr->isn_arg.outer.outer_idx; |
2282 if (iptr->isn_type == ISN_LOADOUTER) | 2284 if (iptr->isn_type == ISN_LOADOUTER) |
2283 { | 2285 { |
2284 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2286 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2285 return FAIL; | 2287 goto theend; |
2286 copy_tv(tv, STACK_TV_BOT(0)); | 2288 copy_tv(tv, STACK_TV_BOT(0)); |
2287 ++ectx->ec_stack.ga_len; | 2289 ++ectx->ec_stack.ga_len; |
2288 } | 2290 } |
2289 else | 2291 else |
2290 { | 2292 { |
2442 case ISN_PUSHBLOB: | 2444 case ISN_PUSHBLOB: |
2443 case ISN_PUSHFUNC: | 2445 case ISN_PUSHFUNC: |
2444 case ISN_PUSHCHANNEL: | 2446 case ISN_PUSHCHANNEL: |
2445 case ISN_PUSHJOB: | 2447 case ISN_PUSHJOB: |
2446 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2448 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2447 return FAIL; | 2449 goto theend; |
2448 tv = STACK_TV_BOT(0); | 2450 tv = STACK_TV_BOT(0); |
2449 tv->v_lock = 0; | 2451 tv->v_lock = 0; |
2450 ++ectx->ec_stack.ga_len; | 2452 ++ectx->ec_stack.ga_len; |
2451 switch (iptr->isn_type) | 2453 switch (iptr->isn_type) |
2452 { | 2454 { |
2518 | 2520 |
2519 // create a list from items on the stack; uses a single allocation | 2521 // create a list from items on the stack; uses a single allocation |
2520 // for the list header and the items | 2522 // for the list header and the items |
2521 case ISN_NEWLIST: | 2523 case ISN_NEWLIST: |
2522 if (exe_newlist(iptr->isn_arg.number, ectx) == FAIL) | 2524 if (exe_newlist(iptr->isn_arg.number, ectx) == FAIL) |
2523 return FAIL; | 2525 goto theend; |
2524 break; | 2526 break; |
2525 | 2527 |
2526 // create a dict from items on the stack | 2528 // create a dict from items on the stack |
2527 case ISN_NEWDICT: | 2529 case ISN_NEWDICT: |
2528 { | 2530 { |
2531 dictitem_T *item; | 2533 dictitem_T *item; |
2532 char_u *key; | 2534 char_u *key; |
2533 int idx; | 2535 int idx; |
2534 | 2536 |
2535 if (dict == NULL) | 2537 if (dict == NULL) |
2536 return FAIL; | 2538 goto theend; |
2537 for (idx = 0; idx < count; ++idx) | 2539 for (idx = 0; idx < count; ++idx) |
2538 { | 2540 { |
2539 // have already checked key type is VAR_STRING | 2541 // have already checked key type is VAR_STRING |
2540 tv = STACK_TV_BOT(2 * (idx - count)); | 2542 tv = STACK_TV_BOT(2 * (idx - count)); |
2541 // check key is unique | 2543 // check key is unique |
2552 item = dictitem_alloc(key); | 2554 item = dictitem_alloc(key); |
2553 clear_tv(tv); | 2555 clear_tv(tv); |
2554 if (item == NULL) | 2556 if (item == NULL) |
2555 { | 2557 { |
2556 dict_unref(dict); | 2558 dict_unref(dict); |
2557 return FAIL; | 2559 goto theend; |
2558 } | 2560 } |
2559 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1); | 2561 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1); |
2560 item->di_tv.v_lock = 0; | 2562 item->di_tv.v_lock = 0; |
2561 if (dict_add(dict, item) == FAIL) | 2563 if (dict_add(dict, item) == FAIL) |
2562 { | 2564 { |
2563 // can this ever happen? | 2565 // can this ever happen? |
2564 dict_unref(dict); | 2566 dict_unref(dict); |
2565 return FAIL; | 2567 goto theend; |
2566 } | 2568 } |
2567 } | 2569 } |
2568 | 2570 |
2569 if (count > 0) | 2571 if (count > 0) |
2570 ectx->ec_stack.ga_len -= 2 * count - 1; | 2572 ectx->ec_stack.ga_len -= 2 * count - 1; |
2571 else if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2573 else if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2572 return FAIL; | 2574 goto theend; |
2573 else | 2575 else |
2574 ++ectx->ec_stack.ga_len; | 2576 ++ectx->ec_stack.ga_len; |
2575 tv = STACK_TV_BOT(-1); | 2577 tv = STACK_TV_BOT(-1); |
2576 tv->v_type = VAR_DICT; | 2578 tv->v_type = VAR_DICT; |
2577 tv->v_lock = 0; | 2579 tv->v_lock = 0; |
2649 break; | 2651 break; |
2650 | 2652 |
2651 // return from a :def function call | 2653 // return from a :def function call |
2652 case ISN_RETURN_ZERO: | 2654 case ISN_RETURN_ZERO: |
2653 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2655 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2654 return FAIL; | 2656 goto theend; |
2655 tv = STACK_TV_BOT(0); | 2657 tv = STACK_TV_BOT(0); |
2656 ++ectx->ec_stack.ga_len; | 2658 ++ectx->ec_stack.ga_len; |
2657 tv->v_type = VAR_NUMBER; | 2659 tv->v_type = VAR_NUMBER; |
2658 tv->vval.v_number = 0; | 2660 tv->vval.v_number = 0; |
2659 tv->v_lock = 0; | 2661 tv->v_lock = 0; |
2688 partial_T *pt = ALLOC_CLEAR_ONE(partial_T); | 2690 partial_T *pt = ALLOC_CLEAR_ONE(partial_T); |
2689 dfunc_T *pt_dfunc = ((dfunc_T *)def_functions.ga_data) | 2691 dfunc_T *pt_dfunc = ((dfunc_T *)def_functions.ga_data) |
2690 + iptr->isn_arg.funcref.fr_func; | 2692 + iptr->isn_arg.funcref.fr_func; |
2691 | 2693 |
2692 if (pt == NULL) | 2694 if (pt == NULL) |
2693 return FAIL; | 2695 goto theend; |
2694 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2696 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2695 { | 2697 { |
2696 vim_free(pt); | 2698 vim_free(pt); |
2697 return FAIL; | 2699 goto theend; |
2698 } | 2700 } |
2699 if (fill_partial_and_closure(pt, pt_dfunc->df_ufunc, | 2701 if (fill_partial_and_closure(pt, pt_dfunc->df_ufunc, |
2700 ectx) == FAIL) | 2702 ectx) == FAIL) |
2701 return FAIL; | 2703 goto theend; |
2702 | 2704 |
2703 tv = STACK_TV_BOT(0); | 2705 tv = STACK_TV_BOT(0); |
2704 ++ectx->ec_stack.ga_len; | 2706 ++ectx->ec_stack.ga_len; |
2705 tv->vval.v_partial = pt; | 2707 tv->vval.v_partial = pt; |
2706 tv->v_type = VAR_PARTIAL; | 2708 tv->v_type = VAR_PARTIAL; |
2713 { | 2715 { |
2714 newfunc_T *newfunc = &iptr->isn_arg.newfunc; | 2716 newfunc_T *newfunc = &iptr->isn_arg.newfunc; |
2715 | 2717 |
2716 if (copy_func(newfunc->nf_lambda, newfunc->nf_global, | 2718 if (copy_func(newfunc->nf_lambda, newfunc->nf_global, |
2717 ectx) == FAIL) | 2719 ectx) == FAIL) |
2718 return FAIL; | 2720 goto theend; |
2719 } | 2721 } |
2720 break; | 2722 break; |
2721 | 2723 |
2722 // List functions | 2724 // List functions |
2723 case ISN_DEF: | 2725 case ISN_DEF: |
2786 typval_T *ltv = STACK_TV_BOT(-1); | 2788 typval_T *ltv = STACK_TV_BOT(-1); |
2787 typval_T *idxtv = | 2789 typval_T *idxtv = |
2788 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx); | 2790 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx); |
2789 | 2791 |
2790 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2792 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2791 return FAIL; | 2793 goto theend; |
2792 if (ltv->v_type == VAR_LIST) | 2794 if (ltv->v_type == VAR_LIST) |
2793 { | 2795 { |
2794 list_T *list = ltv->vval.v_list; | 2796 list_T *list = ltv->vval.v_list; |
2795 | 2797 |
2796 // push the next item from the list | 2798 // push the next item from the list |
2882 } | 2884 } |
2883 else | 2885 else |
2884 { | 2886 { |
2885 semsg(_(e_for_loop_on_str_not_supported), | 2887 semsg(_(e_for_loop_on_str_not_supported), |
2886 vartype_name(ltv->v_type)); | 2888 vartype_name(ltv->v_type)); |
2887 return FAIL; | 2889 goto theend; |
2888 } | 2890 } |
2889 } | 2891 } |
2890 break; | 2892 break; |
2891 | 2893 |
2892 // start of ":try" block | 2894 // start of ":try" block |
2893 case ISN_TRY: | 2895 case ISN_TRY: |
2894 { | 2896 { |
2895 trycmd_T *trycmd = NULL; | 2897 trycmd_T *trycmd = NULL; |
2896 | 2898 |
2897 if (GA_GROW(&ectx->ec_trystack, 1) == FAIL) | 2899 if (GA_GROW(&ectx->ec_trystack, 1) == FAIL) |
2898 return FAIL; | 2900 goto theend; |
2899 trycmd = ((trycmd_T *)ectx->ec_trystack.ga_data) | 2901 trycmd = ((trycmd_T *)ectx->ec_trystack.ga_data) |
2900 + ectx->ec_trystack.ga_len; | 2902 + ectx->ec_trystack.ga_len; |
2901 ++ectx->ec_trystack.ga_len; | 2903 ++ectx->ec_trystack.ga_len; |
2902 ++trylevel; | 2904 ++trylevel; |
2903 CLEAR_POINTER(trycmd); | 2905 CLEAR_POINTER(trycmd); |
2915 case ISN_PUSHEXC: | 2917 case ISN_PUSHEXC: |
2916 if (current_exception == NULL) | 2918 if (current_exception == NULL) |
2917 { | 2919 { |
2918 SOURCING_LNUM = iptr->isn_lnum; | 2920 SOURCING_LNUM = iptr->isn_lnum; |
2919 iemsg("Evaluating catch while current_exception is NULL"); | 2921 iemsg("Evaluating catch while current_exception is NULL"); |
2920 return FAIL; | 2922 goto theend; |
2921 } | 2923 } |
2922 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 2924 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
2923 return FAIL; | 2925 goto theend; |
2924 tv = STACK_TV_BOT(0); | 2926 tv = STACK_TV_BOT(0); |
2925 ++ectx->ec_stack.ga_len; | 2927 ++ectx->ec_stack.ga_len; |
2926 tv->v_type = VAR_STRING; | 2928 tv->v_type = VAR_STRING; |
2927 tv->v_lock = 0; | 2929 tv->v_lock = 0; |
2928 tv->vval.v_string = vim_strsave( | 2930 tv->vval.v_string = vim_strsave( |
2956 | 2958 |
2957 if (trystack->ga_len < trycont->tct_levels) | 2959 if (trystack->ga_len < trycont->tct_levels) |
2958 { | 2960 { |
2959 siemsg("TRYCONT: expected %d levels, found %d", | 2961 siemsg("TRYCONT: expected %d levels, found %d", |
2960 trycont->tct_levels, trystack->ga_len); | 2962 trycont->tct_levels, trystack->ga_len); |
2961 return FAIL; | 2963 goto theend; |
2962 } | 2964 } |
2963 // Make :endtry jump to any outer try block and the last | 2965 // Make :endtry jump to any outer try block and the last |
2964 // :endtry inside the loop to the loop start. | 2966 // :endtry inside the loop to the loop start. |
2965 for (i = trycont->tct_levels; i > 0; --i) | 2967 for (i = trycont->tct_levels; i > 0; --i) |
2966 { | 2968 { |
3047 || *skipwhite(tv->vval.v_string) == NUL) | 3049 || *skipwhite(tv->vval.v_string) == NUL) |
3048 { | 3050 { |
3049 vim_free(tv->vval.v_string); | 3051 vim_free(tv->vval.v_string); |
3050 SOURCING_LNUM = iptr->isn_lnum; | 3052 SOURCING_LNUM = iptr->isn_lnum; |
3051 emsg(_(e_throw_with_empty_string)); | 3053 emsg(_(e_throw_with_empty_string)); |
3052 return FAIL; | 3054 goto theend; |
3053 } | 3055 } |
3054 | 3056 |
3055 // Inside a "catch" we need to first discard the caught | 3057 // Inside a "catch" we need to first discard the caught |
3056 // exception. | 3058 // exception. |
3057 if (trystack->ga_len > 0) | 3059 if (trystack->ga_len > 0) |
3070 | 3072 |
3071 if (throw_exception(tv->vval.v_string, ET_USER, NULL) | 3073 if (throw_exception(tv->vval.v_string, ET_USER, NULL) |
3072 == FAIL) | 3074 == FAIL) |
3073 { | 3075 { |
3074 vim_free(tv->vval.v_string); | 3076 vim_free(tv->vval.v_string); |
3075 return FAIL; | 3077 goto theend; |
3076 } | 3078 } |
3077 did_throw = TRUE; | 3079 did_throw = TRUE; |
3078 } | 3080 } |
3079 break; | 3081 break; |
3080 | 3082 |
3275 SOURCING_LNUM = iptr->isn_lnum; | 3277 SOURCING_LNUM = iptr->isn_lnum; |
3276 emsg(_(e_cannot_add_to_null_list)); | 3278 emsg(_(e_cannot_add_to_null_list)); |
3277 goto on_error; | 3279 goto on_error; |
3278 } | 3280 } |
3279 if (list_append_tv(l, tv2) == FAIL) | 3281 if (list_append_tv(l, tv2) == FAIL) |
3280 return FAIL; | 3282 goto theend; |
3281 clear_tv(tv2); | 3283 clear_tv(tv2); |
3282 --ectx->ec_stack.ga_len; | 3284 --ectx->ec_stack.ga_len; |
3283 } | 3285 } |
3284 break; | 3286 break; |
3285 | 3287 |
3575 // List type and length is checked for when compiling. | 3577 // List type and length is checked for when compiling. |
3576 tv = STACK_TV_BOT(-1); | 3578 tv = STACK_TV_BOT(-1); |
3577 li = list_find(tv->vval.v_list, index); | 3579 li = list_find(tv->vval.v_list, index); |
3578 | 3580 |
3579 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 3581 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
3580 return FAIL; | 3582 goto theend; |
3581 ++ectx->ec_stack.ga_len; | 3583 ++ectx->ec_stack.ga_len; |
3582 copy_tv(&li->li_tv, STACK_TV_BOT(-1)); | 3584 copy_tv(&li->li_tv, STACK_TV_BOT(-1)); |
3583 | 3585 |
3584 // Useful when used in unpack assignment. Reset at | 3586 // Useful when used in unpack assignment. Reset at |
3585 // ISN_DROP. | 3587 // ISN_DROP. |
3808 ea.skip = FALSE; | 3810 ea.skip = FALSE; |
3809 if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL) | 3811 if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL) |
3810 goto on_error; | 3812 goto on_error; |
3811 | 3813 |
3812 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) | 3814 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) |
3813 return FAIL; | 3815 goto theend; |
3814 ++ectx->ec_stack.ga_len; | 3816 ++ectx->ec_stack.ga_len; |
3815 tv = STACK_TV_BOT(-1); | 3817 tv = STACK_TV_BOT(-1); |
3816 tv->v_type = VAR_NUMBER; | 3818 tv->v_type = VAR_NUMBER; |
3817 tv->v_lock = 0; | 3819 tv->v_lock = 0; |
3818 if (ea.addr_count == 0) | 3820 if (ea.addr_count == 0) |
3910 goto on_error; | 3912 goto on_error; |
3911 } | 3913 } |
3912 | 3914 |
3913 CHECK_LIST_MATERIALIZE(l); | 3915 CHECK_LIST_MATERIALIZE(l); |
3914 if (GA_GROW(&ectx->ec_stack, count - 1) == FAIL) | 3916 if (GA_GROW(&ectx->ec_stack, count - 1) == FAIL) |
3915 return FAIL; | 3917 goto theend; |
3916 ectx->ec_stack.ga_len += count - 1; | 3918 ectx->ec_stack.ga_len += count - 1; |
3917 | 3919 |
3918 // Variable after semicolon gets a list with the remaining | 3920 // Variable after semicolon gets a list with the remaining |
3919 // items. | 3921 // items. |
3920 if (semicolon) | 3922 if (semicolon) |
3921 { | 3923 { |
3922 list_T *rem_list = | 3924 list_T *rem_list = |
3923 list_alloc_with_items(l->lv_len - count + 1); | 3925 list_alloc_with_items(l->lv_len - count + 1); |
3924 | 3926 |
3925 if (rem_list == NULL) | 3927 if (rem_list == NULL) |
3926 return FAIL; | 3928 goto theend; |
3927 tv = STACK_TV_BOT(-count); | 3929 tv = STACK_TV_BOT(-count); |
3928 tv->vval.v_list = rem_list; | 3930 tv->vval.v_list = rem_list; |
3929 ++rem_list->lv_refcount; | 3931 ++rem_list->lv_refcount; |
3930 tv->v_lock = 0; | 3932 tv->v_lock = 0; |
3931 li = l->lv_first; | 3933 li = l->lv_first; |
4005 if (ectx->ec_frame_idx == ectx->ec_initial_frame_idx) | 4007 if (ectx->ec_frame_idx == ectx->ec_initial_frame_idx) |
4006 goto done; | 4008 goto done; |
4007 | 4009 |
4008 if (func_return(ectx) == FAIL) | 4010 if (func_return(ectx) == FAIL) |
4009 // only fails when out of memory | 4011 // only fails when out of memory |
4010 return FAIL; | 4012 goto theend; |
4011 continue; | 4013 continue; |
4012 | 4014 |
4013 on_error: | 4015 on_error: |
4014 // Jump here for an error that does not require aborting execution. | 4016 // Jump here for an error that does not require aborting execution. |
4015 // If "emsg_silent" is set then ignore the error, unless it was set | 4017 // If "emsg_silent" is set then ignore the error, unless it was set |
4035 } | 4037 } |
4036 on_fatal_error: | 4038 on_fatal_error: |
4037 // Jump here for an error that messes up the stack. | 4039 // Jump here for an error that messes up the stack. |
4038 // If we are not inside a try-catch started here, abort execution. | 4040 // If we are not inside a try-catch started here, abort execution. |
4039 if (trylevel <= ectx->ec_trylevel_at_start) | 4041 if (trylevel <= ectx->ec_trylevel_at_start) |
4040 return FAIL; | 4042 goto theend; |
4041 } | 4043 } |
4042 | 4044 |
4043 done: | 4045 done: |
4044 return OK; | 4046 ret = OK; |
4047 theend: | |
4048 ectx->ec_trylevel_at_start = save_trylevel_at_start; | |
4049 return ret; | |
4045 } | 4050 } |
4046 | 4051 |
4047 /* | 4052 /* |
4048 * Execute the instructions from a VAR_INSTR typeval and put the result in | 4053 * Execute the instructions from a VAR_INSTR typeval and put the result in |
4049 * "rettv". | 4054 * "rettv". |