fix(gi): 模块级空数组字面量 = [] 改走 zeroinitializer - 修大数组被逐元素展开(元素过多+池耗尽)

This commit is contained in:
TermiNexus committed 2026-10-16 13:02:38 +08:00
1 parent 7e9ed22dff
commit e796314a24
1 file changed
+15 -5
+15 -5
View File
@@ -762,12 +762,22 @@ novirtual class TranslatorGenMixin:
viperlib.snprintf(init_buf, 48, "%lld", init_val) viperlib.snprintf(init_buf, 48, "%lld", init_val)
gv.Initializer = init_buf gv.Initializer = init_buf
elif init_kind == 2: elif init_kind == 2:
# List literal -> array initializer [N x elem_ty] [elem_ty val0, ...] # 空字面量 `= []`:整块清零 ⇒ 直接 zeroinitializer。
arr_init: str = self._build_array_initializer_text(pool, var_ty, init_list_node) # 若走下面的"逐元素展开",`[N]uint8` 这类大数组会生成**百万级**元素文本
if arr_init is not None: gv.Initializer = arr_init # (`[i8 0, i8 0, …]`)——既撞上 MLIR 侧上限(too many global array elements),
# 又让每个元素 ~5KB 的渲染开销把编译池吃光
# (现场:n=1048576、src_head=[i8 0, i8 0, …]、[MEM] 池耗尽)。
ln_c: ast.List* = ast.List*(init_list_node)
elts_c: list[ast.AST*]* = None
if ln_c is not None: elts_c = ln_c.elts
if init_list_node is None or elts_c is None or len(elts_c) == 0:
gv.Initializer = "zeroinitializer"
else: else:
# Initializer build failed: error out (fail-fast) instead of falling back to zeroinitializer arr_init: str = self._build_array_initializer_text(pool, var_ty, init_list_node)
self.Gen.TypeGenErr.fatal_error(node, f"failed to build the initializer of module-level variable '{var_name}'", "TypeError") if arr_init is not None: gv.Initializer = arr_init
else:
# Initializer build failed: error out (fail-fast) instead of falling back
self.Gen.TypeGenErr.fatal_error(node, f"failed to build the initializer of module-level variable '{var_name}'", "TypeError")
elif init_kind == 3: elif init_kind == 3:
# String literal initializer: for array types (t.CArray[char, N]) use a byte-array # String literal initializer: for array types (t.CArray[char, N]) use a byte-array
# initializer (content + zero padding); a string-pointer GEP initializer would mismatch. # initializer (content + zero padding); a string-pointer GEP initializer would mismatch.