summaryrefslogtreecommitdiffstats
path: root/src/eval.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2022-09-28 16:16:15 +0100
committerBram Moolenaar <Bram@vim.org>2022-09-28 16:16:15 +0100
commit82418263fa91792e851cb0de879d1595327d5531 (patch)
treee14f38d9dba9dce01e0c3b6c6612ca577bf27b49 /src/eval.c
parent1936c765364d6a771cea5df9971318060db82730 (diff)
patch 9.0.0618: calling function for reduce() has too much overheadv9.0.0618
Problem: Calling function for reduce() has too much overhead. Solution: Do not create a funccall_T every time.
Diffstat (limited to 'src/eval.c')
-rw-r--r--src/eval.c37
1 files changed, 33 insertions, 4 deletions
diff --git a/src/eval.c b/src/eval.c
index 0102bd70b5..2330bd6a10 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -216,12 +216,39 @@ eval_expr_valid_arg(typval_T *tv)
}
/*
+ * When calling eval_expr_typval() many times we only need one funccall_T.
+ * Returns NULL when no funccall_T is to be used.
+ * When returning non-NULL remove_funccal() must be called later.
+ */
+ funccall_T *
+eval_expr_get_funccal(typval_T *expr, typval_T *rettv)
+{
+ if (expr->v_type != VAR_PARTIAL)
+ return NULL;
+
+ partial_T *partial = expr->vval.v_partial;
+ if (partial == NULL)
+ return NULL;
+ if (partial->pt_func == NULL
+ || partial->pt_func->uf_def_status == UF_NOT_COMPILED)
+ return NULL;
+
+ return create_funccal(partial->pt_func, rettv);
+}
+
+/*
* Evaluate an expression, which can be a function, partial or string.
* Pass arguments "argv[argc]".
+ * "fc_arg" is from eval_expr_get_funccal() or NULL;
* Return the result in "rettv" and OK or FAIL.
*/
int
-eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
+eval_expr_typval(
+ typval_T *expr,
+ typval_T *argv,
+ int argc,
+ funccall_T *fc_arg,
+ typval_T *rettv)
{
char_u *s;
char_u buf[NUMBUFLEN];
@@ -247,7 +274,8 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
if (partial->pt_func != NULL
&& partial->pt_func->uf_def_status != UF_NOT_COMPILED)
{
- funccall_T *fc = create_funccal(partial->pt_func, rettv);
+ funccall_T *fc = fc_arg != NULL ? fc_arg
+ : create_funccal(partial->pt_func, rettv);
int r;
if (fc == NULL)
@@ -256,7 +284,8 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
// Shortcut to call a compiled function with minimal overhead.
r = call_def_function(partial->pt_func, argc, argv,
DEF_USE_PT_ARGV, partial, fc, rettv);
- remove_funccal();
+ if (fc_arg == NULL)
+ remove_funccal();
if (r == FAIL)
return FAIL;
}
@@ -304,7 +333,7 @@ eval_expr_to_bool(typval_T *expr, int *error)
typval_T rettv;
int res;
- if (eval_expr_typval(expr, NULL, 0, &rettv) == FAIL)
+ if (eval_expr_typval(expr, NULL, 0, NULL, &rettv) == FAIL)
{
*error = TRUE;
return FALSE;