comparison src/vim9execute.c @ 25350:0c5b84c5862a v8.2.3212

patch 8.2.3212: Vim9: execution speed can be improved Commit: https://github.com/vim/vim/commit/5a9e5845e1539592e94963fcdf5b3ad4fdc59db4 Author: Dominique Pelle <dominique.pelle@gmail.com> Date: Sat Jul 24 19:32:12 2021 +0200 patch 8.2.3212: Vim9: execution speed can be improved Problem: Vim9: execution speed can be improved. Solution: Use __builtin_expect() to have the compiler produce better code. (Dominique Pell?, closes #8613)
author Bram Moolenaar <Bram@vim.org>
date Sat, 24 Jul 2021 19:45:04 +0200
parents 820395d1137b
children effe5f2b4d01
comparison
equal deleted inserted replaced
25349:d631e1a737d2 25350:0c5b84c5862a
19 #ifdef VMS 19 #ifdef VMS
20 # include <float.h> 20 # include <float.h>
21 #endif 21 #endif
22 22
23 #include "vim9.h" 23 #include "vim9.h"
24
25 #if defined(__GNUC__) || defined(__clang__)
26 # define likely(x) __builtin_expect((x), 1)
27 # define unlikely(x) __builtin_expect((x), 0)
28 #else
29 # define unlikely(x) (x)
30 # define likely(x) (x)
31 #endif
24 32
25 // Structure put on ec_trystack when ISN_TRY is encountered. 33 // Structure put on ec_trystack when ISN_TRY is encountered.
26 typedef struct { 34 typedef struct {
27 int tcd_frame_idx; // ec_frame_idx at ISN_TRY 35 int tcd_frame_idx; // ec_frame_idx at ISN_TRY
28 int tcd_stack_len; // size of ectx.ec_stack at ISN_TRY 36 int tcd_stack_len; // size of ectx.ec_stack at ISN_TRY
135 for (idx = 0; idx < count; ++idx) 143 for (idx = 0; idx < count; ++idx)
136 list_set_item(list, idx, STACK_TV_BOT(idx - count)); 144 list_set_item(list, idx, STACK_TV_BOT(idx - count));
137 145
138 if (count > 0) 146 if (count > 0)
139 ectx->ec_stack.ga_len -= count - 1; 147 ectx->ec_stack.ga_len -= count - 1;
140 else if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 148 else if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
141 return FAIL; 149 return FAIL;
142 else 150 else
143 ++ectx->ec_stack.ga_len; 151 ++ectx->ec_stack.ga_len;
144 tv = STACK_TV_BOT(-1); 152 tv = STACK_TV_BOT(-1);
145 tv->v_type = VAR_LIST; 153 tv->v_type = VAR_LIST;
208 } 216 }
209 217
210 #ifdef FEAT_PROFILE 218 #ifdef FEAT_PROFILE
211 if (do_profiling == PROF_YES) 219 if (do_profiling == PROF_YES)
212 { 220 {
213 if (ga_grow(&profile_info_ga, 1) == OK) 221 if (likely(ga_grow(&profile_info_ga, 1) == OK))
214 { 222 {
215 profinfo_T *info = ((profinfo_T *)profile_info_ga.ga_data) 223 profinfo_T *info = ((profinfo_T *)profile_info_ga.ga_data)
216 + profile_info_ga.ga_len; 224 + profile_info_ga.ga_len;
217 ++profile_info_ga.ga_len; 225 ++profile_info_ga.ga_len;
218 CLEAR_POINTER(info); 226 CLEAR_POINTER(info);
287 // - stack frame 295 // - stack frame
288 // - local variables 296 // - local variables
289 // - if needed: a counter for number of closures created in 297 // - if needed: a counter for number of closures created in
290 // ectx->ec_funcrefs. 298 // ectx->ec_funcrefs.
291 varcount = dfunc->df_varcount + dfunc->df_has_closure; 299 varcount = dfunc->df_varcount + dfunc->df_has_closure;
292 if (ga_grow(&ectx->ec_stack, arg_to_add + STACK_FRAME_SIZE + varcount) 300 if (unlikely(ga_grow(&ectx->ec_stack, arg_to_add + STACK_FRAME_SIZE
293 == FAIL) 301 + varcount) == FAIL))
294 return FAIL; 302 return FAIL;
295 303
296 // If depth of calling is getting too high, don't execute the function. 304 // If depth of calling is getting too high, don't execute the function.
297 if (funcdepth_increment() == FAIL) 305 if (funcdepth_increment() == FAIL)
298 return FAIL; 306 return FAIL;
359 ref->or_partial = ufunc->uf_partial; 367 ref->or_partial = ufunc->uf_partial;
360 } 368 }
361 else 369 else
362 { 370 {
363 ref->or_outer = ALLOC_CLEAR_ONE(outer_T); 371 ref->or_outer = ALLOC_CLEAR_ONE(outer_T);
364 if (ref->or_outer == NULL) 372 if (unlikely(ref->or_outer == NULL))
365 { 373 {
366 vim_free(ref); 374 vim_free(ref);
367 return FAIL; 375 return FAIL;
368 } 376 }
369 ref->or_outer_allocated = TRUE; 377 ref->or_outer_allocated = TRUE;
701 argvars[argcount].v_type = VAR_UNKNOWN; 709 argvars[argcount].v_type = VAR_UNKNOWN;
702 710
703 // Result replaces the arguments on the stack. 711 // Result replaces the arguments on the stack.
704 if (argcount > 0) 712 if (argcount > 0)
705 ectx->ec_stack.ga_len -= argcount - 1; 713 ectx->ec_stack.ga_len -= argcount - 1;
706 else if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 714 else if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
707 return FAIL; 715 return FAIL;
708 else 716 else
709 ++ectx->ec_stack.ga_len; 717 ++ectx->ec_stack.ga_len;
710 718
711 // Default return value is zero. 719 // Default return value is zero.
939 947
940 if (pt->pt_argc > 0) 948 if (pt->pt_argc > 0)
941 { 949 {
942 // Make space for arguments from the partial, shift the "argcount" 950 // Make space for arguments from the partial, shift the "argcount"
943 // arguments up. 951 // arguments up.
944 if (ga_grow(&ectx->ec_stack, pt->pt_argc) == FAIL) 952 if (unlikely(ga_grow(&ectx->ec_stack, pt->pt_argc) == FAIL))
945 return FAIL; 953 return FAIL;
946 for (i = 1; i <= argcount; ++i) 954 for (i = 1; i <= argcount; ++i)
947 *STACK_TV_BOT(-i + pt->pt_argc) = *STACK_TV_BOT(-i); 955 *STACK_TV_BOT(-i + pt->pt_argc) = *STACK_TV_BOT(-i);
948 ectx->ec_stack.ga_len += pt->pt_argc; 956 ectx->ec_stack.ga_len += pt->pt_argc;
949 argcount += pt->pt_argc; 957 argcount += pt->pt_argc;
1369 } 1377 }
1370 1378
1371 // If this function returns and the closure is still being used, we 1379 // If this function returns and the closure is still being used, we
1372 // need to make a copy of the context (arguments and local variables). 1380 // need to make a copy of the context (arguments and local variables).
1373 // Store a reference to the partial so we can handle that. 1381 // Store a reference to the partial so we can handle that.
1374 if (ga_grow(&ectx->ec_funcrefs, 1) == FAIL) 1382 if (unlikely(ga_grow(&ectx->ec_funcrefs, 1) == FAIL))
1375 { 1383 {
1376 vim_free(pt); 1384 vim_free(pt);
1377 return FAIL; 1385 return FAIL;
1378 } 1386 }
1379 // Extra variable keeps the count of closures created in the current 1387 // Extra variable keeps the count of closures created in the current
1502 if (p == NULL) 1510 if (p == NULL)
1503 continue; // left over from continuation line 1511 continue; // left over from continuation line
1504 p = skipwhite(p); 1512 p = skipwhite(p);
1505 if (*p == '#') 1513 if (*p == '#')
1506 break; 1514 break;
1507 if (ga_grow(&ga, 1) == OK) 1515 if (likely(ga_grow(&ga, 1) == OK))
1508 ((char_u **)(ga.ga_data))[ga.ga_len++] = p; 1516 ((char_u **)(ga.ga_data))[ga.ga_len++] = p;
1509 if (STRNCMP(p, "def ", 4) == 0) 1517 if (STRNCMP(p, "def ", 4) == 0)
1510 break; 1518 break;
1511 } 1519 }
1512 line = ga_concat_strings(&ga, " "); 1520 line = ga_concat_strings(&ga, " ");
1542 { 1550 {
1543 static int breakcheck_count = 0; // using "static" makes it faster 1551 static int breakcheck_count = 0; // using "static" makes it faster
1544 isn_T *iptr; 1552 isn_T *iptr;
1545 typval_T *tv; 1553 typval_T *tv;
1546 1554
1547 if (++breakcheck_count >= 100) 1555 if (unlikely(++breakcheck_count >= 100))
1548 { 1556 {
1549 line_breakcheck(); 1557 line_breakcheck();
1550 breakcheck_count = 0; 1558 breakcheck_count = 0;
1551 } 1559 }
1552 if (got_int) 1560 if (unlikely(got_int))
1553 { 1561 {
1554 // Turn CTRL-C into an exception. 1562 // Turn CTRL-C into an exception.
1555 got_int = FALSE; 1563 got_int = FALSE;
1556 if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) == FAIL) 1564 if (throw_exception("Vim:Interrupt", ET_INTERRUPT, NULL) == FAIL)
1557 goto theend; 1565 goto theend;
1558 did_throw = TRUE; 1566 did_throw = TRUE;
1559 } 1567 }
1560 1568
1561 if (did_emsg && msg_list != NULL && *msg_list != NULL) 1569 if (unlikely(did_emsg && msg_list != NULL && *msg_list != NULL))
1562 { 1570 {
1563 // Turn an error message into an exception. 1571 // Turn an error message into an exception.
1564 did_emsg = FALSE; 1572 did_emsg = FALSE;
1565 if (throw_exception(*msg_list, ET_ERROR, NULL) == FAIL) 1573 if (throw_exception(*msg_list, ET_ERROR, NULL) == FAIL)
1566 goto theend; 1574 goto theend;
1567 did_throw = TRUE; 1575 did_throw = TRUE;
1568 *msg_list = NULL; 1576 *msg_list = NULL;
1569 } 1577 }
1570 1578
1571 if (did_throw) 1579 if (unlikely(did_throw))
1572 { 1580 {
1573 garray_T *trystack = &ectx->ec_trystack; 1581 garray_T *trystack = &ectx->ec_trystack;
1574 trycmd_T *trycmd = NULL; 1582 trycmd_T *trycmd = NULL;
1575 int index = trystack->ga_len; 1583 int index = trystack->ga_len;
1576 1584
1603 } 1611 }
1604 else 1612 else
1605 { 1613 {
1606 // Not inside try or need to return from current functions. 1614 // Not inside try or need to return from current functions.
1607 // Push a dummy return value. 1615 // Push a dummy return value.
1608 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1616 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1609 goto theend; 1617 goto theend;
1610 tv = STACK_TV_BOT(0); 1618 tv = STACK_TV_BOT(0);
1611 tv->v_type = VAR_NUMBER; 1619 tv->v_type = VAR_NUMBER;
1612 tv->vval.v_number = 0; 1620 tv->vval.v_number = 0;
1613 ++ectx->ec_stack.ga_len; 1621 ++ectx->ec_stack.ga_len;
1678 { 1686 {
1679 char_u *arg = iptr->isn_arg.string; 1687 char_u *arg = iptr->isn_arg.string;
1680 int res; 1688 int res;
1681 int save_flags = cmdmod.cmod_flags; 1689 int save_flags = cmdmod.cmod_flags;
1682 1690
1683 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1691 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1684 goto theend; 1692 goto theend;
1685 tv = STACK_TV_BOT(0); 1693 tv = STACK_TV_BOT(0);
1686 init_tv(tv); 1694 init_tv(tv);
1687 cmdmod.cmod_flags |= CMOD_LEGACY; 1695 cmdmod.cmod_flags |= CMOD_LEGACY;
1688 res = eval0(arg, tv, NULL, &EVALARG_EVALUATE); 1696 res = eval0(arg, tv, NULL, &EVALARG_EVALUATE);
1694 break; 1702 break;
1695 1703
1696 // push typeval VAR_INSTR with instructions to be executed 1704 // push typeval VAR_INSTR with instructions to be executed
1697 case ISN_INSTR: 1705 case ISN_INSTR:
1698 { 1706 {
1699 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1707 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1700 goto theend; 1708 goto theend;
1701 tv = STACK_TV_BOT(0); 1709 tv = STACK_TV_BOT(0);
1702 tv->vval.v_instr = ALLOC_ONE(instr_T); 1710 tv->vval.v_instr = ALLOC_ONE(instr_T);
1703 if (tv->vval.v_instr == NULL) 1711 if (tv->vval.v_instr == NULL)
1704 goto on_error; 1712 goto on_error;
1759 1767
1760 // End redirection, put redirected text on the stack. 1768 // End redirection, put redirected text on the stack.
1761 clear_redir_lval(); 1769 clear_redir_lval();
1762 redir_vname = 0; 1770 redir_vname = 0;
1763 1771
1764 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1772 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1765 { 1773 {
1766 vim_free(res); 1774 vim_free(res);
1767 goto theend; 1775 goto theend;
1768 } 1776 }
1769 tv = STACK_TV_BOT(0); 1777 tv = STACK_TV_BOT(0);
1826 clear_tv(tv); 1834 clear_tv(tv);
1827 } 1835 }
1828 if (pass == 1) 1836 if (pass == 1)
1829 { 1837 {
1830 cmd = alloc(len + 1); 1838 cmd = alloc(len + 1);
1831 if (cmd == NULL) 1839 if (unlikely(cmd == NULL))
1832 goto theend; 1840 goto theend;
1833 len = 0; 1841 len = 0;
1834 } 1842 }
1835 } 1843 }
1836 1844
1895 } 1903 }
1896 else 1904 else
1897 p = tv_stringify(tv, buf); 1905 p = tv_stringify(tv, buf);
1898 1906
1899 len = (int)STRLEN(p); 1907 len = (int)STRLEN(p);
1900 if (ga_grow(&ga, len + 2) == FAIL) 1908 if (unlikely(ga_grow(&ga, len + 2) == FAIL))
1901 failed = TRUE; 1909 failed = TRUE;
1902 else 1910 else
1903 { 1911 {
1904 if (ga.ga_len > 0) 1912 if (ga.ga_len > 0)
1905 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' '; 1913 ((char_u *)(ga.ga_data))[ga.ga_len++] = ' ';
1946 } 1954 }
1947 break; 1955 break;
1948 1956
1949 // load local variable or argument 1957 // load local variable or argument
1950 case ISN_LOAD: 1958 case ISN_LOAD:
1951 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1959 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1952 goto theend; 1960 goto theend;
1953 copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0)); 1961 copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0));
1954 ++ectx->ec_stack.ga_len; 1962 ++ectx->ec_stack.ga_len;
1955 break; 1963 break;
1956 1964
1957 // load v: variable 1965 // load v: variable
1958 case ISN_LOADV: 1966 case ISN_LOADV:
1959 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1967 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1960 goto theend; 1968 goto theend;
1961 copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0)); 1969 copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0));
1962 ++ectx->ec_stack.ga_len; 1970 ++ectx->ec_stack.ga_len;
1963 break; 1971 break;
1964 1972
1970 1978
1971 sv = get_script_svar(sref, ectx); 1979 sv = get_script_svar(sref, ectx);
1972 if (sv == NULL) 1980 if (sv == NULL)
1973 goto theend; 1981 goto theend;
1974 allocate_if_null(sv->sv_tv); 1982 allocate_if_null(sv->sv_tv);
1975 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 1983 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1976 goto theend; 1984 goto theend;
1977 copy_tv(sv->sv_tv, STACK_TV_BOT(0)); 1985 copy_tv(sv->sv_tv, STACK_TV_BOT(0));
1978 ++ectx->ec_stack.ga_len; 1986 ++ectx->ec_stack.ga_len;
1979 } 1987 }
1980 break; 1988 break;
1993 semsg(_(e_undefined_variable_str), name); 2001 semsg(_(e_undefined_variable_str), name);
1994 goto on_error; 2002 goto on_error;
1995 } 2003 }
1996 else 2004 else
1997 { 2005 {
1998 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2006 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
1999 goto theend; 2007 goto theend;
2000 copy_tv(&di->di_tv, STACK_TV_BOT(0)); 2008 copy_tv(&di->di_tv, STACK_TV_BOT(0));
2001 ++ectx->ec_stack.ga_len; 2009 ++ectx->ec_stack.ga_len;
2002 } 2010 }
2003 } 2011 }
2043 namespace, iptr->isn_arg.string); 2051 namespace, iptr->isn_arg.string);
2044 goto on_error; 2052 goto on_error;
2045 } 2053 }
2046 else 2054 else
2047 { 2055 {
2048 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2056 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2049 goto theend; 2057 goto theend;
2050 copy_tv(&di->di_tv, STACK_TV_BOT(0)); 2058 copy_tv(&di->di_tv, STACK_TV_BOT(0));
2051 ++ectx->ec_stack.ga_len; 2059 ++ectx->ec_stack.ga_len;
2052 } 2060 }
2053 } 2061 }
2056 // load autoload variable 2064 // load autoload variable
2057 case ISN_LOADAUTO: 2065 case ISN_LOADAUTO:
2058 { 2066 {
2059 char_u *name = iptr->isn_arg.string; 2067 char_u *name = iptr->isn_arg.string;
2060 2068
2061 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2069 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2062 goto theend; 2070 goto theend;
2063 SOURCING_LNUM = iptr->isn_lnum; 2071 SOURCING_LNUM = iptr->isn_lnum;
2064 if (eval_variable(name, (int)STRLEN(name), 2072 if (eval_variable(name, (int)STRLEN(name),
2065 STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL) 2073 STACK_TV_BOT(0), NULL, EVAL_VAR_VERBOSE) == FAIL)
2066 goto on_error; 2074 goto on_error;
2083 case ISN_LOADWDICT: d = curwin->w_vars; break; 2091 case ISN_LOADWDICT: d = curwin->w_vars; break;
2084 case ISN_LOADTDICT: d = curtab->tp_vars; break; 2092 case ISN_LOADTDICT: d = curtab->tp_vars; break;
2085 default: // Cannot reach here 2093 default: // Cannot reach here
2086 goto theend; 2094 goto theend;
2087 } 2095 }
2088 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2096 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2089 goto theend; 2097 goto theend;
2090 tv = STACK_TV_BOT(0); 2098 tv = STACK_TV_BOT(0);
2091 tv->v_type = VAR_DICT; 2099 tv->v_type = VAR_DICT;
2092 tv->v_lock = 0; 2100 tv->v_lock = 0;
2093 tv->vval.v_dict = d; 2101 tv->vval.v_dict = d;
2102 typval_T optval; 2110 typval_T optval;
2103 char_u *name = iptr->isn_arg.string; 2111 char_u *name = iptr->isn_arg.string;
2104 2112
2105 // This is not expected to fail, name is checked during 2113 // This is not expected to fail, name is checked during
2106 // compilation: don't set SOURCING_LNUM. 2114 // compilation: don't set SOURCING_LNUM.
2107 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2115 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2108 goto theend; 2116 goto theend;
2109 if (eval_option(&name, &optval, TRUE) == FAIL) 2117 if (eval_option(&name, &optval, TRUE) == FAIL)
2110 goto theend; 2118 goto theend;
2111 *STACK_TV_BOT(0) = optval; 2119 *STACK_TV_BOT(0) = optval;
2112 ++ectx->ec_stack.ga_len; 2120 ++ectx->ec_stack.ga_len;
2117 case ISN_LOADENV: 2125 case ISN_LOADENV:
2118 { 2126 {
2119 typval_T optval; 2127 typval_T optval;
2120 char_u *name = iptr->isn_arg.string; 2128 char_u *name = iptr->isn_arg.string;
2121 2129
2122 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2130 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2123 goto theend; 2131 goto theend;
2124 // name is always valid, checked when compiling 2132 // name is always valid, checked when compiling
2125 (void)eval_env_var(&name, &optval, TRUE); 2133 (void)eval_env_var(&name, &optval, TRUE);
2126 *STACK_TV_BOT(0) = optval; 2134 *STACK_TV_BOT(0) = optval;
2127 ++ectx->ec_stack.ga_len; 2135 ++ectx->ec_stack.ga_len;
2128 } 2136 }
2129 break; 2137 break;
2130 2138
2131 // load @register 2139 // load @register
2132 case ISN_LOADREG: 2140 case ISN_LOADREG:
2133 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2141 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2134 goto theend; 2142 goto theend;
2135 tv = STACK_TV_BOT(0); 2143 tv = STACK_TV_BOT(0);
2136 tv->v_type = VAR_STRING; 2144 tv->v_type = VAR_STRING;
2137 tv->v_lock = 0; 2145 tv->v_lock = 0;
2138 // This may result in NULL, which should be equivalent to an 2146 // This may result in NULL, which should be equivalent to an
2563 tv = ((typval_T *)outer->out_stack->ga_data) 2571 tv = ((typval_T *)outer->out_stack->ga_data)
2564 + outer->out_frame_idx + STACK_FRAME_SIZE 2572 + outer->out_frame_idx + STACK_FRAME_SIZE
2565 + iptr->isn_arg.outer.outer_idx; 2573 + iptr->isn_arg.outer.outer_idx;
2566 if (iptr->isn_type == ISN_LOADOUTER) 2574 if (iptr->isn_type == ISN_LOADOUTER)
2567 { 2575 {
2568 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2576 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2569 goto theend; 2577 goto theend;
2570 copy_tv(tv, STACK_TV_BOT(0)); 2578 copy_tv(tv, STACK_TV_BOT(0));
2571 ++ectx->ec_stack.ga_len; 2579 ++ectx->ec_stack.ga_len;
2572 } 2580 }
2573 else 2581 else
2751 case ISN_PUSHS: 2759 case ISN_PUSHS:
2752 case ISN_PUSHBLOB: 2760 case ISN_PUSHBLOB:
2753 case ISN_PUSHFUNC: 2761 case ISN_PUSHFUNC:
2754 case ISN_PUSHCHANNEL: 2762 case ISN_PUSHCHANNEL:
2755 case ISN_PUSHJOB: 2763 case ISN_PUSHJOB:
2756 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2764 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2757 goto theend; 2765 goto theend;
2758 tv = STACK_TV_BOT(0); 2766 tv = STACK_TV_BOT(0);
2759 tv->v_lock = 0; 2767 tv->v_lock = 0;
2760 ++ectx->ec_stack.ga_len; 2768 ++ectx->ec_stack.ga_len;
2761 switch (iptr->isn_type) 2769 switch (iptr->isn_type)
2840 dict_T *dict = dict_alloc(); 2848 dict_T *dict = dict_alloc();
2841 dictitem_T *item; 2849 dictitem_T *item;
2842 char_u *key; 2850 char_u *key;
2843 int idx; 2851 int idx;
2844 2852
2845 if (dict == NULL) 2853 if (unlikely(dict == NULL))
2846 goto theend; 2854 goto theend;
2847 for (idx = 0; idx < count; ++idx) 2855 for (idx = 0; idx < count; ++idx)
2848 { 2856 {
2849 // have already checked key type is VAR_STRING 2857 // have already checked key type is VAR_STRING
2850 tv = STACK_TV_BOT(2 * (idx - count)); 2858 tv = STACK_TV_BOT(2 * (idx - count));
2859 dict_unref(dict); 2867 dict_unref(dict);
2860 goto on_error; 2868 goto on_error;
2861 } 2869 }
2862 item = dictitem_alloc(key); 2870 item = dictitem_alloc(key);
2863 clear_tv(tv); 2871 clear_tv(tv);
2864 if (item == NULL) 2872 if (unlikely(item == NULL))
2865 { 2873 {
2866 dict_unref(dict); 2874 dict_unref(dict);
2867 goto theend; 2875 goto theend;
2868 } 2876 }
2869 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1); 2877 item->di_tv = *STACK_TV_BOT(2 * (idx - count) + 1);
2876 } 2884 }
2877 } 2885 }
2878 2886
2879 if (count > 0) 2887 if (count > 0)
2880 ectx->ec_stack.ga_len -= 2 * count - 1; 2888 ectx->ec_stack.ga_len -= 2 * count - 1;
2881 else if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2889 else if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2882 goto theend; 2890 goto theend;
2883 else 2891 else
2884 ++ectx->ec_stack.ga_len; 2892 ++ectx->ec_stack.ga_len;
2885 tv = STACK_TV_BOT(-1); 2893 tv = STACK_TV_BOT(-1);
2886 tv->v_type = VAR_DICT; 2894 tv->v_type = VAR_DICT;
2958 } 2966 }
2959 break; 2967 break;
2960 2968
2961 // return from a :def function call without a value 2969 // return from a :def function call without a value
2962 case ISN_RETURN_VOID: 2970 case ISN_RETURN_VOID:
2963 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 2971 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
2964 goto theend; 2972 goto theend;
2965 tv = STACK_TV_BOT(0); 2973 tv = STACK_TV_BOT(0);
2966 ++ectx->ec_stack.ga_len; 2974 ++ectx->ec_stack.ga_len;
2967 tv->v_type = VAR_VOID; 2975 tv->v_type = VAR_VOID;
2968 tv->vval.v_number = 0; 2976 tv->vval.v_number = 0;
3000 dfunc_T *pt_dfunc = ((dfunc_T *)def_functions.ga_data) 3008 dfunc_T *pt_dfunc = ((dfunc_T *)def_functions.ga_data)
3001 + iptr->isn_arg.funcref.fr_func; 3009 + iptr->isn_arg.funcref.fr_func;
3002 3010
3003 if (pt == NULL) 3011 if (pt == NULL)
3004 goto theend; 3012 goto theend;
3005 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 3013 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
3006 { 3014 {
3007 vim_free(pt); 3015 vim_free(pt);
3008 goto theend; 3016 goto theend;
3009 } 3017 }
3010 if (fill_partial_and_closure(pt, pt_dfunc->df_ufunc, 3018 if (fill_partial_and_closure(pt, pt_dfunc->df_ufunc,
3095 { 3103 {
3096 typval_T *ltv = STACK_TV_BOT(-1); 3104 typval_T *ltv = STACK_TV_BOT(-1);
3097 typval_T *idxtv = 3105 typval_T *idxtv =
3098 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx); 3106 STACK_TV_VAR(iptr->isn_arg.forloop.for_idx);
3099 3107
3100 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 3108 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
3101 goto theend; 3109 goto theend;
3102 if (ltv->v_type == VAR_LIST) 3110 if (ltv->v_type == VAR_LIST)
3103 { 3111 {
3104 list_T *list = ltv->vval.v_list; 3112 list_T *list = ltv->vval.v_list;
3105 3113
3202 // start of ":try" block 3210 // start of ":try" block
3203 case ISN_TRY: 3211 case ISN_TRY:
3204 { 3212 {
3205 trycmd_T *trycmd = NULL; 3213 trycmd_T *trycmd = NULL;
3206 3214
3207 if (GA_GROW(&ectx->ec_trystack, 1) == FAIL) 3215 if (unlikely(GA_GROW(&ectx->ec_trystack, 1) == FAIL))
3208 goto theend; 3216 goto theend;
3209 trycmd = ((trycmd_T *)ectx->ec_trystack.ga_data) 3217 trycmd = ((trycmd_T *)ectx->ec_trystack.ga_data)
3210 + ectx->ec_trystack.ga_len; 3218 + ectx->ec_trystack.ga_len;
3211 ++ectx->ec_trystack.ga_len; 3219 ++ectx->ec_trystack.ga_len;
3212 ++trylevel; 3220 ++trylevel;
3227 { 3235 {
3228 SOURCING_LNUM = iptr->isn_lnum; 3236 SOURCING_LNUM = iptr->isn_lnum;
3229 iemsg("Evaluating catch while current_exception is NULL"); 3237 iemsg("Evaluating catch while current_exception is NULL");
3230 goto theend; 3238 goto theend;
3231 } 3239 }
3232 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 3240 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
3233 goto theend; 3241 goto theend;
3234 tv = STACK_TV_BOT(0); 3242 tv = STACK_TV_BOT(0);
3235 ++ectx->ec_stack.ga_len; 3243 ++ectx->ec_stack.ga_len;
3236 tv->v_type = VAR_STRING; 3244 tv->v_type = VAR_STRING;
3237 tv->v_lock = 0; 3245 tv->v_lock = 0;
3886 // Get list item: list is at stack-1, push item. 3894 // Get list item: list is at stack-1, push item.
3887 // List type and length is checked for when compiling. 3895 // List type and length is checked for when compiling.
3888 tv = STACK_TV_BOT(-1 - gi->gi_with_op); 3896 tv = STACK_TV_BOT(-1 - gi->gi_with_op);
3889 li = list_find(tv->vval.v_list, gi->gi_index); 3897 li = list_find(tv->vval.v_list, gi->gi_index);
3890 3898
3891 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 3899 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
3892 goto theend; 3900 goto theend;
3893 ++ectx->ec_stack.ga_len; 3901 ++ectx->ec_stack.ga_len;
3894 copy_tv(&li->li_tv, STACK_TV_BOT(-1)); 3902 copy_tv(&li->li_tv, STACK_TV_BOT(-1));
3895 3903
3896 // Useful when used in unpack assignment. Reset at 3904 // Useful when used in unpack assignment. Reset at
4121 ea.cmd = iptr->isn_arg.string; 4129 ea.cmd = iptr->isn_arg.string;
4122 ea.skip = FALSE; 4130 ea.skip = FALSE;
4123 if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL) 4131 if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL)
4124 goto on_error; 4132 goto on_error;
4125 4133
4126 if (GA_GROW(&ectx->ec_stack, 1) == FAIL) 4134 if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
4127 goto theend; 4135 goto theend;
4128 ++ectx->ec_stack.ga_len; 4136 ++ectx->ec_stack.ga_len;
4129 tv = STACK_TV_BOT(-1); 4137 tv = STACK_TV_BOT(-1);
4130 tv->v_type = VAR_NUMBER; 4138 tv->v_type = VAR_NUMBER;
4131 tv->v_lock = 0; 4139 tv->v_lock = 0;
4223 emsg(_(e_list_value_has_more_items_than_targets)); 4231 emsg(_(e_list_value_has_more_items_than_targets));
4224 goto on_error; 4232 goto on_error;
4225 } 4233 }
4226 4234
4227 CHECK_LIST_MATERIALIZE(l); 4235 CHECK_LIST_MATERIALIZE(l);
4228 if (GA_GROW(&ectx->ec_stack, count - 1) == FAIL) 4236 if (unlikely(GA_GROW(&ectx->ec_stack, count - 1) == FAIL))
4229 goto theend; 4237 goto theend;
4230 ectx->ec_stack.ga_len += count - 1; 4238 ectx->ec_stack.ga_len += count - 1;
4231 4239
4232 // Variable after semicolon gets a list with the remaining 4240 // Variable after semicolon gets a list with the remaining
4233 // items. 4241 // items.
4497 return FAIL; 4505 return FAIL;
4498 4506
4499 CLEAR_FIELD(ectx); 4507 CLEAR_FIELD(ectx);
4500 ectx.ec_dfunc_idx = ufunc->uf_dfunc_idx; 4508 ectx.ec_dfunc_idx = ufunc->uf_dfunc_idx;
4501 ga_init2(&ectx.ec_stack, sizeof(typval_T), 500); 4509 ga_init2(&ectx.ec_stack, sizeof(typval_T), 500);
4502 if (ga_grow(&ectx.ec_stack, 20) == FAIL) 4510 if (unlikely(ga_grow(&ectx.ec_stack, 20) == FAIL))
4503 { 4511 {
4504 funcdepth_decrement(); 4512 funcdepth_decrement();
4505 return FAIL; 4513 return FAIL;
4506 } 4514 }
4507 ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10); 4515 ga_init2(&ectx.ec_trystack, sizeof(trycmd_T), 10);
5504 char_u *buf; 5512 char_u *buf;
5505 size_t len = produce_cmdmods( 5513 size_t len = produce_cmdmods(
5506 NULL, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE); 5514 NULL, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);
5507 5515
5508 buf = alloc(len + 1); 5516 buf = alloc(len + 1);
5509 if (buf != NULL) 5517 if (likely(buf != NULL))
5510 { 5518 {
5511 (void)produce_cmdmods( 5519 (void)produce_cmdmods(
5512 buf, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE); 5520 buf, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);
5513 smsg("%s%4d CMDMOD %s", pfx, current, buf); 5521 smsg("%s%4d CMDMOD %s", pfx, current, buf);
5514 vim_free(buf); 5522 vim_free(buf);