From ffdbce2b9992c26a9c107d3ec0f3cb614d491703 Mon Sep 17 00:00:00 2001 From: N5N3 <2642243996@qq.com> Date: Sat, 9 Mar 2024 16:25:30 +0800 Subject: [PATCH] make GC happy. --- src/subtype.c | 68 ++++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/src/subtype.c b/src/subtype.c index b6515c979dfa2..2f535504026aa 100644 --- a/src/subtype.c +++ b/src/subtype.c @@ -2818,9 +2818,9 @@ static jl_value_t *omit_bad_union(jl_value_t *u, jl_tvar_t *t) // Caller might not have rooted `res` static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbinding_t *vb, jl_unionall_t *u, jl_stenv_t *e) { - jl_value_t *varval = NULL, *nivar = NULL; - jl_tvar_t *newvar = vb->var; - JL_GC_PUSH3(&res, &newvar, &nivar); + jl_value_t *varval = NULL, *ilb = NULL, *iub = NULL, *nivar = NULL; + jl_tvar_t *newvar = vb->var, *ivar = NULL; + JL_GC_PUSH6(&res, &newvar, &ivar, &nivar, &ilb, &iub); // try to reduce var to a single value if (jl_is_long(vb->ub) && jl_is_typevar(vb->lb)) { varval = vb->ub; @@ -2914,42 +2914,45 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind jl_ivarbinding_t *pwrap = NULL; for (jl_ivarbinding_t *btemp = allvars, *pbtemp = NULL; btemp != NULL; btemp = btemp->next) { int bdepth0 = btemp->root->depth0; - if (jl_has_typevar(*btemp->lb, vb->var)) { - assert(btemp->root->var == *btemp->var || bdepth0 == vb->depth0); - if (vb->lb == (jl_value_t*)*btemp->var) { + ivar = *btemp->var; + ilb = *btemp->lb; + iub = *btemp->ub; + if (jl_has_typevar(ilb, vb->var)) { + assert(btemp->root->var == ivar || bdepth0 == vb->depth0); + if (vb->lb == (jl_value_t*)ivar) { JL_GC_POP(); JL_GC_POP(); return jl_bottom_type; } if (varval) { JL_TRY { - *btemp->lb = jl_substitute_var(*btemp->lb, vb->var, varval); + *btemp->lb = jl_substitute_var(ilb, vb->var, varval); } JL_CATCH { res = jl_bottom_type; } } - else if (*btemp->lb == (jl_value_t*)vb->var) { + else if (ilb == (jl_value_t*)vb->var) { *btemp->lb = vb->lb; } - else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, *btemp->var) && !jl_has_typevar(vb->ub, *btemp->var)) { + else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, ivar) && !jl_has_typevar(vb->ub, ivar)) { // if our variable is T, and some outer variable has constraint S = Ref{T}, // move the `where T` outside `where S` instead of putting it here. issue #21243. if (newvar != vb->var) - *btemp->lb = jl_substitute_var(*btemp->lb, vb->var, (jl_value_t*)newvar); + *btemp->lb = jl_substitute_var(ilb, vb->var, (jl_value_t*)newvar); if (!wrapped) pwrap = pbtemp; wrapped = 1; } else { - *btemp->lb = jl_new_struct(jl_unionall_type, vb->var, *btemp->lb); + *btemp->lb = jl_new_struct(jl_unionall_type, vb->var, ilb); } - assert((jl_value_t*)*btemp->var != *btemp->lb); + assert((jl_value_t*)ivar != *btemp->lb); } - if (jl_has_typevar(*btemp->ub, vb->var)) { - assert(btemp->root->var == *btemp->var || bdepth0 == vb->depth0); - if (vb->ub == (jl_value_t*)*btemp->var) { - *btemp->ub = omit_bad_union(*btemp->ub, vb->var); - if (*btemp->ub == jl_bottom_type && btemp->ub != btemp->lb) { + if (jl_has_typevar(iub, vb->var)) { + assert(btemp->root->var == ivar || bdepth0 == vb->depth0); + if (vb->ub == (jl_value_t*)ivar) { + *btemp->ub = omit_bad_union(iub, vb->var); + if (*btemp->ub == jl_bottom_type && *btemp->ub != *btemp->lb) { JL_GC_POP(); JL_GC_POP(); return jl_bottom_type; @@ -2957,28 +2960,28 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind } if (varval) { JL_TRY { - *btemp->ub = jl_substitute_var(*btemp->ub, vb->var, varval); + *btemp->ub = jl_substitute_var(iub, vb->var, varval); } JL_CATCH { res = jl_bottom_type; } } - else if (*btemp->ub == (jl_value_t*)vb->var) { + else if (iub == (jl_value_t*)vb->var) { // TODO: this loses some constraints, such as in this test, where we replace T4<:S3 (e.g. T4==S3 since T4 only appears covariantly once) with T4<:Any // a = Tuple{Float64,T3,T4} where T4 where T3 // b = Tuple{S2,Tuple{S3},S3} where S2 where S3 // Tuple{Float64, T3, T4} where {S3, T3<:Tuple{S3}, T4<:S3} *btemp->ub = vb->ub; } - else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, *btemp->var) && !jl_has_typevar(vb->ub, *btemp->var)) { + else if (bdepth0 == vb->depth0 && !jl_has_typevar(vb->lb, ivar) && !jl_has_typevar(vb->ub, ivar)) { if (newvar != vb->var) - *btemp->ub = jl_substitute_var(*btemp->ub, vb->var, (jl_value_t*)newvar); + *btemp->ub = jl_substitute_var(iub, vb->var, (jl_value_t*)newvar); if (!wrapped) pwrap = pbtemp; wrapped = 1; } else - *btemp->ub = jl_new_struct(jl_unionall_type, vb->var, *btemp->ub); - assert((jl_value_t*)*btemp->var != *btemp->ub); + *btemp->ub = jl_new_struct(jl_unionall_type, vb->var, iub); + assert((jl_value_t*)ivar != *btemp->ub); } pbtemp = btemp; } @@ -3033,18 +3036,21 @@ static jl_value_t *finish_unionall(jl_value_t *res JL_MAYBE_UNROOTED, jl_varbind // Freeze the innervars' lb/ub and perform substitution if needed. for (jl_ivarbinding_t *btemp1 = allvars; btemp1 != NULL; btemp1 = btemp1->next) { - jl_tvar_t *ivar = *btemp1->var; + ivar = *btemp1->var; + ilb = *btemp1->lb; + iub = *btemp1->ub; int isinnervar = btemp1->root->var != ivar; - if (isinnervar && ((ivar->lb != *btemp1->lb) || - (ivar->ub != *btemp1->ub))) { - nivar = (jl_value_t *)jl_new_typevar(ivar->name, *btemp1->lb, *btemp1->ub); + if (isinnervar && (ivar->lb != ilb || ivar->ub != iub)) { + nivar = (jl_value_t *)jl_new_typevar(ivar->name, ilb, iub); if (jl_has_typevar(res, ivar)) res = jl_substitute_var(res, ivar, nivar); for (jl_ivarbinding_t *btemp2 = btemp1->next; btemp2 != NULL; btemp2 = btemp2->next) { - if (jl_has_typevar(*btemp2->lb, ivar)) - *btemp2->lb = jl_substitute_var(*btemp2->lb, ivar, nivar); - if (jl_has_typevar(*btemp2->ub, ivar)) - *btemp2->ub = jl_substitute_var(*btemp2->ub, ivar, nivar); + ilb = *btemp2->lb; + iub = *btemp2->ub; + if (jl_has_typevar(ilb, ivar)) + *btemp2->lb = jl_substitute_var(ilb, ivar, nivar); + if (jl_has_typevar(iub, ivar)) + *btemp2->ub = jl_substitute_var(iub, ivar, nivar); } *btemp1->var = (jl_tvar_t *)nivar; }