#include "vim9.h"
+#if defined(__GNUC__) || defined(__clang__)
+# define likely(x) __builtin_expect((x), 1)
+# define unlikely(x) __builtin_expect((x), 0)
+#else
+# define unlikely(x) (x)
+# define likely(x) (x)
+#endif
+
// Structure put on ec_trystack when ISN_TRY is encountered.
typedef struct {
int tcd_frame_idx; // ec_frame_idx at ISN_TRY
if (count > 0)
ectx->ec_stack.ga_len -= count - 1;
- else if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ else if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
return FAIL;
else
++ectx->ec_stack.ga_len;
#ifdef FEAT_PROFILE
if (do_profiling == PROF_YES)
{
- if (ga_grow(&profile_info_ga, 1) == OK)
+ if (likely(ga_grow(&profile_info_ga, 1) == OK))
{
profinfo_T *info = ((profinfo_T *)profile_info_ga.ga_data)
+ profile_info_ga.ga_len;
// - if needed: a counter for number of closures created in
// ectx->ec_funcrefs.
varcount = dfunc->df_varcount + dfunc->df_has_closure;
- if (ga_grow(&ectx->ec_stack, arg_to_add + STACK_FRAME_SIZE + varcount)
- == FAIL)
+ if (unlikely(ga_grow(&ectx->ec_stack, arg_to_add + STACK_FRAME_SIZE
+ + varcount) == FAIL))
return FAIL;
// If depth of calling is getting too high, don't execute the function.
else
{
ref->or_outer = ALLOC_CLEAR_ONE(outer_T);
- if (ref->or_outer == NULL)
+ if (unlikely(ref->or_outer == NULL))
{
vim_free(ref);
return FAIL;
// Result replaces the arguments on the stack.
if (argcount > 0)
ectx->ec_stack.ga_len -= argcount - 1;
- else if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ else if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
return FAIL;
else
++ectx->ec_stack.ga_len;
{
// Make space for arguments from the partial, shift the "argcount"
// arguments up.
- if (ga_grow(&ectx->ec_stack, pt->pt_argc) == FAIL)
+ if (unlikely(ga_grow(&ectx->ec_stack, pt->pt_argc) == FAIL))
return FAIL;
for (i = 1; i <= argcount; ++i)
*STACK_TV_BOT(-i + pt->pt_argc) = *STACK_TV_BOT(-i);
// If this function returns and the closure is still being used, we
// need to make a copy of the context (arguments and local variables).
// Store a reference to the partial so we can handle that.
- if (ga_grow(&ectx->ec_funcrefs, 1) == FAIL)
+ if (unlikely(ga_grow(&ectx->ec_funcrefs, 1) == FAIL))
{
vim_free(pt);
return FAIL;
p = skipwhite(p);
if (*p == '#')
break;
- if (ga_grow(&ga, 1) == OK)
+ if (likely(ga_grow(&ga, 1) == OK))
((char_u **)(ga.ga_data))[ga.ga_len++] = p;
if (STRNCMP(p, "def ", 4) == 0)
break;
isn_T *iptr;
typval_T *tv;
- if (++breakcheck_count >= 100)
+ if (unlikely(++breakcheck_count >= 100))
{
line_breakcheck();
breakcheck_count = 0;
}
- if (got_int)
+ if (unlikely(got_int))
{
// Turn CTRL-C into an exception.
got_int = FALSE;
did_throw = TRUE;
}
- if (did_emsg && msg_list != NULL && *msg_list != NULL)
+ if (unlikely(did_emsg && msg_list != NULL && *msg_list != NULL))
{
// Turn an error message into an exception.
did_emsg = FALSE;
*msg_list = NULL;
}
- if (did_throw)
+ if (unlikely(did_throw))
{
garray_T *trystack = &ectx->ec_trystack;
trycmd_T *trycmd = NULL;
{
// Not inside try or need to return from current functions.
// Push a dummy return value.
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
tv->v_type = VAR_NUMBER;
int res;
int save_flags = cmdmod.cmod_flags;
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
init_tv(tv);
// push typeval VAR_INSTR with instructions to be executed
case ISN_INSTR:
{
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
tv->vval.v_instr = ALLOC_ONE(instr_T);
clear_redir_lval();
redir_vname = 0;
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
{
vim_free(res);
goto theend;
if (pass == 1)
{
cmd = alloc(len + 1);
- if (cmd == NULL)
+ if (unlikely(cmd == NULL))
goto theend;
len = 0;
}
p = tv_stringify(tv, buf);
len = (int)STRLEN(p);
- if (ga_grow(&ga, len + 2) == FAIL)
+ if (unlikely(ga_grow(&ga, len + 2) == FAIL))
failed = TRUE;
else
{
// load local variable or argument
case ISN_LOAD:
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
copy_tv(STACK_TV_VAR(iptr->isn_arg.number), STACK_TV_BOT(0));
++ectx->ec_stack.ga_len;
// load v: variable
case ISN_LOADV:
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
copy_tv(get_vim_var_tv(iptr->isn_arg.number), STACK_TV_BOT(0));
++ectx->ec_stack.ga_len;
if (sv == NULL)
goto theend;
allocate_if_null(sv->sv_tv);
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
copy_tv(sv->sv_tv, STACK_TV_BOT(0));
++ectx->ec_stack.ga_len;
}
else
{
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
copy_tv(&di->di_tv, STACK_TV_BOT(0));
++ectx->ec_stack.ga_len;
}
else
{
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
copy_tv(&di->di_tv, STACK_TV_BOT(0));
++ectx->ec_stack.ga_len;
{
char_u *name = iptr->isn_arg.string;
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
SOURCING_LNUM = iptr->isn_lnum;
if (eval_variable(name, (int)STRLEN(name),
default: // Cannot reach here
goto theend;
}
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
tv->v_type = VAR_DICT;
// This is not expected to fail, name is checked during
// compilation: don't set SOURCING_LNUM.
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
if (eval_option(&name, &optval, TRUE) == FAIL)
goto theend;
typval_T optval;
char_u *name = iptr->isn_arg.string;
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
// name is always valid, checked when compiling
(void)eval_env_var(&name, &optval, TRUE);
// load @register
case ISN_LOADREG:
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
tv->v_type = VAR_STRING;
+ iptr->isn_arg.outer.outer_idx;
if (iptr->isn_type == ISN_LOADOUTER)
{
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
copy_tv(tv, STACK_TV_BOT(0));
++ectx->ec_stack.ga_len;
case ISN_PUSHFUNC:
case ISN_PUSHCHANNEL:
case ISN_PUSHJOB:
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
tv->v_lock = 0;
char_u *key;
int idx;
- if (dict == NULL)
+ if (unlikely(dict == NULL))
goto theend;
for (idx = 0; idx < count; ++idx)
{
}
item = dictitem_alloc(key);
clear_tv(tv);
- if (item == NULL)
+ if (unlikely(item == NULL))
{
dict_unref(dict);
goto theend;
if (count > 0)
ectx->ec_stack.ga_len -= 2 * count - 1;
- else if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ else if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
else
++ectx->ec_stack.ga_len;
// return from a :def function call without a value
case ISN_RETURN_VOID:
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
++ectx->ec_stack.ga_len;
if (pt == NULL)
goto theend;
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
{
vim_free(pt);
goto theend;
typval_T *idxtv =
STACK_TV_VAR(iptr->isn_arg.forloop.for_idx);
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
if (ltv->v_type == VAR_LIST)
{
{
trycmd_T *trycmd = NULL;
- if (GA_GROW(&ectx->ec_trystack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_trystack, 1) == FAIL))
goto theend;
trycmd = ((trycmd_T *)ectx->ec_trystack.ga_data)
+ ectx->ec_trystack.ga_len;
iemsg("Evaluating catch while current_exception is NULL");
goto theend;
}
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
tv = STACK_TV_BOT(0);
++ectx->ec_stack.ga_len;
tv = STACK_TV_BOT(-1 - gi->gi_with_op);
li = list_find(tv->vval.v_list, gi->gi_index);
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
++ectx->ec_stack.ga_len;
copy_tv(&li->li_tv, STACK_TV_BOT(-1));
if (parse_cmd_address(&ea, &errormsg, FALSE) == FAIL)
goto on_error;
- if (GA_GROW(&ectx->ec_stack, 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, 1) == FAIL))
goto theend;
++ectx->ec_stack.ga_len;
tv = STACK_TV_BOT(-1);
}
CHECK_LIST_MATERIALIZE(l);
- if (GA_GROW(&ectx->ec_stack, count - 1) == FAIL)
+ if (unlikely(GA_GROW(&ectx->ec_stack, count - 1) == FAIL))
goto theend;
ectx->ec_stack.ga_len += count - 1;
CLEAR_FIELD(ectx);
ectx.ec_dfunc_idx = ufunc->uf_dfunc_idx;
ga_init2(&ectx.ec_stack, sizeof(typval_T), 500);
- if (ga_grow(&ectx.ec_stack, 20) == FAIL)
+ if (unlikely(ga_grow(&ectx.ec_stack, 20) == FAIL))
{
funcdepth_decrement();
return FAIL;
NULL, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);
buf = alloc(len + 1);
- if (buf != NULL)
+ if (likely(buf != NULL))
{
(void)produce_cmdmods(
buf, iptr->isn_arg.cmdmod.cf_cmdmod, FALSE);