From 33bab281e27cf866e77fb3bba6e37f5a5edfef03 Mon Sep 17 00:00:00 2001 From: Robin Haberkorn Date: Sun, 23 Aug 2026 22:08:16 +0200 Subject: Revert "optimize main state machine transitions with tail calls" For yet unknown reasons this does not improve performance on GCC 16 even though it also supports `__attribute__((musttail))`. As long as I do not understand why, I don't want to risk any unnecessary problems. I have reason to believe that the tail-call optimized version still has subtle bugs. See also the "tail-calls" branch. This reverts commit 2e097cec409182c3cb39b74489387480bf8a278f. --- src/core-commands.c | 64 ++++++++++++++++++++++++----------------------------- 1 file changed, 29 insertions(+), 35 deletions(-) (limited to 'src/core-commands.c') diff --git a/src/core-commands.c b/src/core-commands.c index d01cbb9..612d980 100644 --- a/src/core-commands.c +++ b/src/core-commands.c @@ -763,7 +763,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) teco_error_modifier_set(error, cmd); return NULL; } - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; } switch (chr) { @@ -792,7 +792,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) } if (ctx->flags.mode == TECO_MODE_NORMAL) teco_expressions_add_digit(chr, ctx->qreg_table_locals->radix); - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; case '*': /* @@ -804,7 +804,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) */ if (teco_cmdline_ssm(SCI_GETCURRENTPOS, 0, 0) == 1 && teco_cmdline_ssm(SCI_GETCHARAT, 0, 0) == '*') - TECO_RETURN(ctx, &teco_state_save_cmdline, error); + return &teco_state_save_cmdline; /* treat as an operator */ break; @@ -819,7 +819,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) if (ctx->parent.must_undo) teco_undo_gint(ctx->nest_level); ctx->nest_level++; - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; case '>': if (ctx->flags.modifier_at) { @@ -838,7 +838,7 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) teco_undo_gint(ctx->nest_level); ctx->nest_level--; } - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; /* * Control Structures (conditionals) @@ -856,9 +856,9 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) else if (ctx->flags.mode == TECO_MODE_NORMAL) /* skip to end of conditional; skip ELSE-part */ ctx->flags.mode = TECO_MODE_PARSE_ONLY_COND; - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; - case '\'': TECO_RETURN(ctx, teco_state_endcond(ctx, "'", error), error); + case '\'': return teco_state_endcond(ctx, "'", error); /* * Word movement and deletion commands. @@ -871,13 +871,13 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) * but should accept only one colon modifier. */ case 'w': - case 'W': TECO_RETURN(ctx, teco_state_start_words(ctx, "W", 1, error), error); + case 'W': return teco_state_start_words(ctx, "W", 1, error); case 'p': - case 'P': TECO_RETURN(ctx, teco_state_start_words(ctx, "P", -1, error), error); + case 'P': return teco_state_start_words(ctx, "P", -1, error); case 'v': - case 'V': TECO_RETURN(ctx, teco_state_start_delete_words(ctx, "V", 1, error), error); + case 'V': return teco_state_start_delete_words(ctx, "V", 1, error); case 'y': - case 'Y': TECO_RETURN(ctx, teco_state_start_delete_words(ctx, "Y", -1, error), error); + case 'Y': return teco_state_start_delete_words(ctx, "Y", -1, error); /* * Modifiers @@ -896,11 +896,11 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) if (ctx->parent.must_undo) teco_undo_flags(ctx->flags); ctx->flags.modifier_at = TRUE; - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; case ':': if (ctx->flags.mode > TECO_MODE_NORMAL) - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; if (ctx->flags.modifier_colon >= 2) { teco_error_modifier_set(error, ":"); return NULL; @@ -908,21 +908,18 @@ teco_state_start_input(teco_machine_main_t *ctx, gunichar chr, GError **error) if (ctx->parent.must_undo) teco_undo_flags(ctx->flags); ctx->flags.modifier_colon++; - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; default: /* * commands implemented in teco_state_control */ - if (TECO_IS_CTL(chr)) { - teco_state_t *next = teco_state_control_input(ctx, TECO_CTL_ECHO(chr), error); - TECO_RETURN(ctx, next, error); - } + if (TECO_IS_CTL(chr)) + return teco_state_control_input(ctx, TECO_CTL_ECHO(chr), error); } - teco_state_t *next = teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), - teco_ascii_toupper(chr), error); - TECO_RETURN(ctx, next, error); + return teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), + teco_ascii_toupper(chr), error); } TECO_DEFINE_STATE_START(teco_state_start, @@ -1091,12 +1088,11 @@ teco_state_fcommand_input(teco_machine_main_t *ctx, gunichar chr, GError **error }; switch (chr) { - case '"': TECO_RETURN(ctx, teco_state_endcond(ctx, "F\"", error), error); + case '"': return teco_state_endcond(ctx, "F\"", error); } - teco_state_t *next = teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), - teco_ascii_toupper(chr), error); - TECO_RETURN(ctx, next, error); + return teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), + teco_ascii_toupper(chr), error); } TECO_DEFINE_STATE_COMMAND(teco_state_fcommand, @@ -1305,7 +1301,7 @@ teco_state_condcommand_input(teco_machine_main_t *ctx, gunichar chr, GError **er ctx->flags.mode = TECO_MODE_PARSE_ONLY_COND; } - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; } TECO_DEFINE_STATE_COMMAND(teco_state_condcommand, @@ -1741,9 +1737,8 @@ teco_state_control_input(teco_machine_main_t *ctx, gunichar chr, GError **error) * Currently you get error messages like 'Syntax error "F"' for ^F. * The easiest way around would be g_prefix_error(error, "Control command"); */ - teco_state_t *next = teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), - teco_ascii_toupper(chr), error); - TECO_RETURN(ctx, next, error); + return teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), + teco_ascii_toupper(chr), error); } TECO_DEFINE_STATE_COMMAND(teco_state_control, @@ -1756,7 +1751,7 @@ teco_state_ascii_input(teco_machine_main_t *ctx, gunichar chr, GError **error) if (ctx->flags.mode == TECO_MODE_NORMAL) teco_expressions_push(chr); - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; } /*$ ^^ ^^c @@ -1941,7 +1936,7 @@ teco_state_ctlc_input(teco_machine_main_t *ctx, gunichar chr, GError **error) { switch (chr) { case TECO_CTL_KEY('C'): return teco_state_ctlc_control_input(ctx, 'C', error); - case '^': TECO_RETURN(ctx, &teco_state_ctlc_control, error); + case '^': return &teco_state_ctlc_control; } return ctx->flags.mode > TECO_MODE_NORMAL @@ -1994,7 +1989,7 @@ teco_state_ctlc_control_input(teco_machine_main_t *ctx, gunichar chr, GError **e */ if (chr == 'c' || chr == 'C') { if (ctx->flags.mode > TECO_MODE_NORMAL) - TECO_RETURN(ctx, &teco_state_start, error); + return &teco_state_start; if (teco_undo_enabled) { g_set_error_literal(error, TECO_ERROR, TECO_ERROR_FAILED, @@ -2958,9 +2953,8 @@ teco_state_ecommand_input(teco_machine_main_t *ctx, gunichar chr, GError **error /* * FIXME: Should we return a special syntax error in case of failure? */ - teco_state_t *next = teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), - teco_ascii_toupper(chr), error); - TECO_RETURN(ctx, next, error); + return teco_machine_main_transition_input(ctx, transitions, G_N_ELEMENTS(transitions), + teco_ascii_toupper(chr), error); } TECO_DEFINE_STATE_COMMAND(teco_state_ecommand, -- cgit v1.2.3