From c2adbd4a3bf89400670cde96b5900c86073ebccc Mon Sep 17 00:00:00 2001 From: dzaima Date: Tue, 3 Sep 2024 03:36:39 +0300 Subject: [PATCH] move toConstant to builtins.h --- src/builtins.h | 10 ++++++++++ src/core/derv.c | 27 ++++++++++----------------- 2 files changed, 20 insertions(+), 17 deletions(-) diff --git a/src/builtins.h b/src/builtins.h index 093fbbde..b379e741 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -102,6 +102,16 @@ static bool isPervasiveDyExt(B x) { return false; } +static bool toConstant(B x, B* out) { // doesn't consume x; if possible, writes an owned reference to out, else leaves out unmodified + if (!isCallable(x)) { *out = inc(x); return true; } + if (TY(x) == t_md1D) { + Md1D* d = c(Md1D,x); + Md1* m1 = d->m1; + if (PTY(m1)==t_md1BI && m1->flags==n_const) { *out = inc(d->f); return true; } + } + return false; +} + extern GLOBAL B #define F(N,X) bi_##N, FOR_PFN(F,F,F) diff --git a/src/core/derv.c b/src/core/derv.c index 0db69141..46743378 100644 --- a/src/core/derv.c +++ b/src/core/derv.c @@ -100,29 +100,22 @@ static B md2D_uc1(B t, B o, B x) { return TIv(m,m2_uc1)(m, o, f, g, x); } -static B toConstant(B x) { // doesn't consume x - if (!isCallable(x)) return inc(x); - if (TY(x) == t_md1D) { - Md1D* d = c(Md1D,x); - Md1* m1 = d->m1; - if (PTY(m1)==t_md1BI && m1->flags==n_const) return inc(d->f); - } - return bi_N; -} STATIC_GLOBAL NFnDesc* ucwWrapDesc; STATIC_GLOBAL NFnDesc* uc1WrapDesc; static B fork_uc1(B t, B o, B x) { - B f = toConstant(c(Fork, t)->f); + B f; B g = c(Fork, t)->g; B h = c(Fork, t)->h; - if (RARE(q_N(f) | !isFun(g) | !isFun(h))) { dec(f); return def_fn_uc1(t, o, x); } - B args[] = {g, o, f}; - B tmp = m_nfn(ucwWrapDesc, tag(args, RAW_TAG)); - B r = TI(h,fn_uc1)(h,tmp,x); - // f is consumed by the eventual ucwWrap call. this hopes that everything is nice and calls o only once, and within the under call, so any user-facing Under interface must assert that that'll stay the case - decG(tmp); - return r; + if (LIKELY(isFun(g) && isFun(h) && toConstant(c(Fork, t)->f, &f))) { + B args[] = {g, o, f}; + B tmp = m_nfn(ucwWrapDesc, tag(args, RAW_TAG)); + B r = TI(h,fn_uc1)(h,tmp,x); + // f is consumed by the eventual ucwWrap call. this hopes that everything is nice and calls o only once, and within the under call, so any user-facing Under interface must assert that that'll stay the case + decG(tmp); + return r; + } + return def_fn_uc1(t, o, x); } static B ucwWrap_c1(B t, B x) { B* args = c(B, nfn_objU(t));