From 7da9d7cb0dc1b8cf4081dea9b6c6c04defa528e2 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Wed, 14 Oct 2026 19:54:29 +0800 Subject: [PATCH] =?UTF-8?q?fix(viperc):=20=E4=BD=8D=E5=AE=BD=E6=8E=A2?= =?UTF-8?q?=E6=B5=8B=E5=BE=AA=E7=8E=AF=E6=94=B9=E4=B8=BA=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=2064=20=E6=AC=A1=E4=B8=8A=E7=95=8C=EF=BC=8C=E4=BF=AE=E4=B8=BB?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=99=A8=E6=AD=BB=E5=BE=AA=E7=8E=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 现象:Phase1 编译到 viperlib.vp 时卡死,栈顶停在 ExprGenOps.vp:1362(我新加的位宽探测 while) - 原因:`while t != 0 { t = t >> 1 }`(t 为 int64)在生成代码里不收敛(疑似 i64 移位/比较被按窄宽度处理)→ 死循环;改为 `while i < 64 and t > 0` 的固定上界写法,两处(ExprGenOps 运行期常量折叠 / AssignGenMixin 静态求值)一起改 - 遗留待查:该 while 为何不收敛(i64 >> / != 0 的代码生成),属同类“最小宽度”问题面 --- App/lib/core/Gen/AssignGenMixin.vp | 6 +++++- App/lib/core/Gen/Expr/ExprGenOps.vp | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/App/lib/core/Gen/AssignGenMixin.vp b/App/lib/core/Gen/AssignGenMixin.vp index 819af60..8379e88 100644 --- a/App/lib/core/Gen/AssignGenMixin.vp +++ b/App/lib/core/Gen/AssignGenMixin.vp @@ -121,9 +121,13 @@ novirtual class AssignGenMixin: t: int64 = res if res < 0: t = res ^ int64(-1) vw: int = 1 # 符号位 - while t != 0: + # 固定 64 次上界(i64 最多 64 位):不用 `while t != 0` —— 某些代码生成下 + # i64 的移位/比较不收敛,会死循环。 + bi: int = 0 + while bi < 64 and t > 0: vw += 1 t = t >> 1 + bi += 1 if vw > w: w = vw if w > 0: if w <= 8: bits_out[0] = 8 diff --git a/App/lib/core/Gen/Expr/ExprGenOps.vp b/App/lib/core/Gen/Expr/ExprGenOps.vp index d019bc7..a786e41 100644 --- a/App/lib/core/Gen/Expr/ExprGenOps.vp +++ b/App/lib/core/Gen/Expr/ExprGenOps.vp @@ -1358,9 +1358,13 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase): t_cf: int64 = cf_v if cf_v < 0: t_cf = cf_v ^ int64(-1) vw_cf: int = 1 # 符号位 - while t_cf != 0: + # 固定 64 次上界(i64 最多 64 位):不用 `while t != 0` —— 某些代码生成下 + # i64 的移位/比较不收敛,会死循环(现场:主编译器卡死在 ExprGenOps 死循环里)。 + bi_cf: int = 0 + while bi_cf < 64 and t_cf > 0: vw_cf += 1 t_cf = t_cf >> 1 + bi_cf += 1 if vw_cf > cf_w: cf_w = vw_cf if cf_w <= 8: cf_w = 8 elif cf_w <= 16: cf_w = 16