chore(messages): includes 运行时中文字符串英文化
把 includes 下 11 个文件(memhub 94、mlirlite/__function 71、ast/parser 54、mlirlite/__module 41、mlirlite/__types 28、ast/lexer 8、ast/tokens 4、sys 2、traceback 1、mlirlite/__builder 1、requests/https 1)的运行时诊断/报错字符串(OOM/MEM/FREEFRAME/MLIR 报错/AST 报错/栈转储横幅等)由中文改为英文。 口径:只改字符串字面量内部文字,行数零变化(+307/-307);printf 格式符与转义序列的多重集合逐一校验不变(_strcheck 异常 0)。验证:三重重编 SUCCESS(184.28s)+ 全量 77/77 顺序回归通过 + VET 编译 SUCCESS / --search-paths 7 条 exit 0。
This commit is contained in:
1 parent
c0d56b127d
commit
587d989dec
11 files changed
+307
-307
No files matched your search
+8
-8
@@ -74,12 +74,12 @@ def _lex_record_overflow(text: str, lineno: int, col: int):
|
||||
msg_buf: str = stdlib.malloc(512)
|
||||
if msg_buf is not None:
|
||||
stdio.snprintf(msg_buf, 512,
|
||||
"[TPV] 整数字面量溢出: 字面量 '%s' 超出 64 位可表示范围"
|
||||
"(按位模式解释的上限为 18446744073709551615 = 2^64-1,"
|
||||
"该字面量需要的位宽至少 65 位)。"
|
||||
"禁止静默回绕/截断,已终止编译。"
|
||||
"修法: 把该字面量改到 0..18446744073709551615 的 64 位位模式范围内;"
|
||||
"本语言不存在更宽的整数类型,如需更大数值请拆分为多个 64 位字表达。", text)
|
||||
"[TPV] integer literal overflow: literal '%s' exceeds the 64-bit representable range"
|
||||
" (the bit-pattern interpretation upper bound is 18446744073709551615 = 2^64-1,"
|
||||
" the literal needs a width of at least 65 bits)."
|
||||
" Silent wrap-around/truncation is forbidden; compilation aborted."
|
||||
" Fix: change the literal into the 64-bit bit-pattern range 0..18446744073709551615;"
|
||||
" this language has no wider integer type, for larger values split into multiple 64-bit words.", text)
|
||||
_g_lex_err_msg = msg_buf
|
||||
else:
|
||||
_g_lex_err_msg = text
|
||||
@@ -320,7 +320,7 @@ class Lexer:
|
||||
ptr: Lexer* = pool.alloc(Lexer.__sizeof__())
|
||||
if ptr == None:
|
||||
# Pool exhausted: fail-fast instead of returning NULL (downstream would treat NULL as a valid Lexer)
|
||||
stdio.printf("[AST] Lexer 分配失败:内存池已耗尽(need=%zu 字节)\n",
|
||||
stdio.printf("[AST] Lexer allocation failed: memory pool exhausted (need=%zu bytes)\n",
|
||||
sizet(Lexer.__sizeof__()))
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -345,7 +345,7 @@ def _lexer_init(lx: Lexer*, src: str, pool: memhub.MemManager*):
|
||||
# Allocate indentation stack
|
||||
lx.indent_stack = pool.alloc(LEXER_MAX_INDENT * 8)
|
||||
if lx.indent_stack == None:
|
||||
stdio.printf("[AST] Lexer.indent_stack 分配失败:内存池已耗尽(need=%zu 字节)\n",
|
||||
stdio.printf("[AST] Lexer.indent_stack allocation failed: memory pool exhausted (need=%zu bytes)\n",
|
||||
sizet(LEXER_MAX_INDENT * 8))
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
|
||||
+56
-56
@@ -278,7 +278,7 @@ def _record_parse_err(ps: Parser*):
|
||||
# Copy the message text via stdlib (token.str_val lives in the pool; stored independently to be safe)
|
||||
buf_m: str = stdlib.malloc(128)
|
||||
if buf_m is not None:
|
||||
stdio.snprintf(buf_m, 128, "意外的 token '%s'", err_s)
|
||||
stdio.snprintf(buf_m, 128, "unexpected token '%s'", err_s)
|
||||
_g_parse_err_msg = buf_m
|
||||
else:
|
||||
_g_parse_err_msg = err_s
|
||||
@@ -305,7 +305,7 @@ def _record_parse_err_ctx(ps: Parser*, tok_type: int,
|
||||
_g_parse_err_msg = err_s
|
||||
return
|
||||
stdio.snprintf(buf_m, 512,
|
||||
"意外的 token '%s'(type=%d) | 附注: prev='%s' (line %d col %d) | next='%s' (line %d col %d)",
|
||||
"unexpected token '%s' (type=%d) | note: prev='%s' (line %d col %d) | next='%s' (line %d col %d)",
|
||||
err_s, tok_type, pv_str, pv_line, pv_col, nx_str, nx_line, nx_col);
|
||||
_g_parse_err_msg = buf_m
|
||||
|
||||
@@ -324,12 +324,12 @@ def _record_neg_literal_overflow(lit_text: str, lineno: int, col: int):
|
||||
buf: str = stdlib.malloc(512)
|
||||
if buf is not None:
|
||||
stdio.snprintf(buf, 512,
|
||||
"[TPV] 负数整数字面量越界: 一元减作用于整数字面量后的结果超出 64 位"
|
||||
"有符号可表示范围(允许范围 -9223372036854775808..18446744073709551615"
|
||||
" = [-2^63, 2^64-1];负数结果必须 >= -2^63)。字面量原文: '-%s'。"
|
||||
"禁止静默回绕/截断,已终止编译。"
|
||||
"修法: 把该负数改到 -9223372036854775808..-1 的范围内(本语言不存在"
|
||||
"更宽的整数类型,如需更大数值请拆分为多个 64 位字表达)。", lit_text)
|
||||
"[TPV] negative integer literal out of range: unary minus applied to an integer literal exceeds the"
|
||||
" signed 64-bit representable range (allowed range -9223372036854775808..18446744073709551615"
|
||||
" = [-2^63, 2^64-1]; a negative result must be >= -2^63). Literal text: '-%s'."
|
||||
" Silent wrap-around/truncation is forbidden; compilation aborted."
|
||||
" Fix: change the negative number into -9223372036854775808..-1 (this language has no"
|
||||
" wider integer type, for larger values split into multiple 64-bit words).", lit_text)
|
||||
_g_parse_err_msg = buf
|
||||
else:
|
||||
_g_parse_err_msg = lit_text
|
||||
@@ -435,12 +435,12 @@ def _RecordDescriptorErr(detail: str, lineno: int, col: int):
|
||||
buf: str = stdlib.malloc(1024)
|
||||
if buf is not None:
|
||||
stdio.snprintf(buf, 1024,
|
||||
"类型描述符非法(%s)。const/volatile 是只在类型位置生效的软关键字,"
|
||||
"必须写成 `名字: const 类型` / `名字: volatile 类型`"
|
||||
"(可组合 `名字: const volatile 类型`)。正确示例:a: const int / "
|
||||
"invalid type descriptor (%s). const/volatile are soft keywords valid only in type position;"
|
||||
" they must be written as `name: const type` / `name: volatile type`"
|
||||
" (combinable as `name: const volatile type`). Correct examples: a: const int / "
|
||||
"a: volatile int / a: const volatile t.CInt32T / "
|
||||
"def f(p: const rawptr[Foo]) -> const int。"
|
||||
"(描述符不会被静默忽略:缺类型 / 后随非类型 / 裸用一律终止编译)", detail)
|
||||
"def f(p: const rawptr[Foo]) -> const int."
|
||||
" (descriptors are never silently ignored: missing type / non-type follower / bare use all abort compilation)", detail)
|
||||
_g_parse_err_msg = buf
|
||||
else:
|
||||
_g_parse_err_msg = detail
|
||||
@@ -491,14 +491,14 @@ def _RecordVirtualErr(detail: str, lineno: int, col: int, extra: str):
|
||||
buf: str = stdlib.malloc(1536)
|
||||
if buf is not None:
|
||||
stdio.snprintf(buf, 1536,
|
||||
"[TPV] virtual/novirtual 修饰符非法(%s)。可写位置:类级 "
|
||||
"`virtual class C:` / `novirtual class C:`;方法级 "
|
||||
"[TPV] invalid virtual/novirtual modifier (%s). Valid positions: class level "
|
||||
"`virtual class C:` / `novirtual class C:`; method level "
|
||||
"`virtual def m(self): ...` / `novirtual def m(self): ...`"
|
||||
"(只能直接写在类体内:virtual class / class / novirtual class 的类体)。"
|
||||
"正确示例:virtual class Shape: / novirtual class Node: / "
|
||||
" (only directly inside a class body: the body of virtual class / class / novirtual class)."
|
||||
" Correct examples: virtual class Shape: / novirtual class Node: / "
|
||||
"class A: virtual def run(self) -> int: ... / "
|
||||
"novirtual class B: novirtual def helper(self) -> int: ...。%s"
|
||||
"(修饰符不会被静默忽略:非法形态一律终止编译)", detail, extra)
|
||||
"novirtual class B: novirtual def helper(self) -> int: ....%s"
|
||||
" (modifiers are never silently ignored: illegal forms all abort compilation)", detail, extra)
|
||||
_g_parse_err_msg = buf
|
||||
else:
|
||||
_g_parse_err_msg = detail
|
||||
@@ -534,24 +534,24 @@ def _ParseVirtualModified(ps: Parser*, parent: AST*):
|
||||
if kw2 == Keyword.Struct:
|
||||
# struct is a pure data type: no virtual / novirtual modifier allowed. A dedicated message
|
||||
# (not the generic "follower not class/def") points at the fix: struct already implies @t.NoVTable.
|
||||
_RecordStructErr(f"`{mod_name} struct` 非法:struct 禁止 virtual/novirtual 修饰",
|
||||
_RecordStructErr(f"`{mod_name} struct` is invalid: struct forbids the virtual/novirtual modifier",
|
||||
mod_lineno, mod_col,
|
||||
"struct 天然无虚表(解析期已合成 @t.NoVTable),"
|
||||
"请直接写 `struct X:`;需要虚表语义请改用 class。")
|
||||
"struct has no vtable by nature (a @t.NoVTable is synthesized at parse time);"
|
||||
" write `struct X:` directly; if vtable semantics are needed, use class instead.")
|
||||
else:
|
||||
_RecordVirtualErr(f"`{mod_name}` 后随 '{nxt_s}'(非 class/def)",
|
||||
_RecordVirtualErr(f"`{mod_name}` is followed by '{nxt_s}' (not class/def)",
|
||||
mod_lineno, mod_col,
|
||||
f"`{mod_name}` 只在 class/def 前生效;"
|
||||
f"若此处本意是普通标识符名,请改名"
|
||||
f"(该词在语句起始会被判为修饰符)。")
|
||||
f"`{mod_name}` takes effect only before class/def;"
|
||||
f" if a plain identifier name was intended here, rename it"
|
||||
f" (this word is treated as a modifier at statement start).")
|
||||
ps.error_count += 1
|
||||
# Dispatch the remaining tokens to the generic statement path (no infinite loop, no error overwrite).
|
||||
_parse_simple_stmt_into(ps, parent)
|
||||
return
|
||||
if is_def != 0 and ps.in_class_body == 0:
|
||||
_RecordVirtualErr(f"{mod_name} def 出现在类体之外", mod_lineno, mod_col,
|
||||
f"{mod_name} def 描述的是「类体内方法的虚/非虚」,"
|
||||
f"模块级 / 函数体 / 分支体内没有可归属的类。")
|
||||
_RecordVirtualErr(f"{mod_name} def appears outside a class body", mod_lineno, mod_col,
|
||||
f"{mod_name} def describes the 'virtual/non-virtual' of a method inside a class body;"
|
||||
f" at module level / function body / branch body there is no class to attach to.")
|
||||
ps.error_count += 1
|
||||
# Merge existing decorators (@deco + virtual class/def) then hand off to the existing class/def parser
|
||||
merged: list[AST*]* = list[AST*](ps.pool, 8)
|
||||
@@ -2461,8 +2461,8 @@ def _parse_type_ann(ps: Parser*) -> AST*:
|
||||
if _IsStaticDescriptorKeyword(ps) != 0:
|
||||
# Annotation-position `static` (`name: static T`) is no longer supported: storage-class markers
|
||||
# are always prefixed. Fail loudly here (otherwise `static` becomes an opaque "static" class).
|
||||
_RecordDescriptorErr("注解位置的 static 已不再支持:请写成前置形式"
|
||||
" `static 名字: 类型 = 值`(等价 `名字: t.CStatic | 类型`)",
|
||||
_RecordDescriptorErr("static in annotation position is no longer supported: use the prefix form"
|
||||
" `static name: type = value` (equivalent to `name: t.CStatic | type`)",
|
||||
_cur_lineno(ps), _cur_col(ps))
|
||||
_advance(ps)
|
||||
continue
|
||||
@@ -2511,7 +2511,7 @@ def _parse_type_ann(ps: Parser*) -> AST*:
|
||||
if mod_count > 0 and _cur_type(ps) != TokenType.Name:
|
||||
# Missing type after a descriptor (`a: const` / `a: const = 1` / `def f(a: const)`):
|
||||
# fail loudly -- never silently drop the descriptor.
|
||||
_RecordDescriptorErr("描述符后缺少类型", mod_lineno, mod_col)
|
||||
_RecordDescriptorErr("missing type after descriptor", mod_lineno, mod_col)
|
||||
ps.error_count += 1
|
||||
return None
|
||||
before_ec: int = ps.error_count
|
||||
@@ -2519,13 +2519,13 @@ def _parse_type_ann(ps: Parser*) -> AST*:
|
||||
if base is None:
|
||||
if mod_count > 0:
|
||||
# Descriptor consumed but type parsing failed (e.g. `a: const = 1`): fail loudly keeping the descriptor error.
|
||||
_RecordDescriptorErr("描述符后缺少类型(类型解析失败)", mod_lineno, mod_col)
|
||||
_RecordDescriptorErr("missing type after descriptor (type parse failed)", mod_lineno, mod_col)
|
||||
_record_parse_err(ps) # annotation parse failed: record position (error_count already bumped in _parse_test)
|
||||
return None
|
||||
if mod_count > 0 and base.kind() == ASTKind.Constant:
|
||||
# Non-type follower (`a: const 1` / `a: const "x"` / `a: const True`): fail loudly, since
|
||||
# descriptors modify types only and constants are not types -- never silently degrade or drop.
|
||||
_RecordDescriptorErr("描述符后随非类型(描述符只修饰类型)", mod_lineno, mod_col)
|
||||
_RecordDescriptorErr("descriptor followed by a non-type (descriptors modify types only)", mod_lineno, mod_col)
|
||||
ps.error_count += 1
|
||||
return None
|
||||
ptr_level: int = 0
|
||||
@@ -2678,7 +2678,7 @@ def _parse_statement_into(ps: Parser*, parent: AST*):
|
||||
# Matches only when followed by newline/EOF/semicolon (soft-keyword boundary), so `const = 5` /
|
||||
# `t.attr.const()` do not match. After recording, continue the generic simple_stmt dispatch.
|
||||
if _IsBareDescriptor(ps) != 0:
|
||||
_RecordDescriptorErr("裸用描述符(整条语句只有描述符,缺类型)",
|
||||
_RecordDescriptorErr("bare descriptor use (the whole statement is only a descriptor, missing type)",
|
||||
_cur_lineno(ps), _cur_col(ps))
|
||||
ps.error_count += 1
|
||||
if kw == Keyword.If or kw == Keyword.While or kw == Keyword.For or kw == Keyword.Try:
|
||||
@@ -3722,7 +3722,7 @@ def _parse_export_extern_var(ps: Parser*) -> AST*:
|
||||
if _match_op(ps, TokOp.Equal):
|
||||
if is_extern != 0:
|
||||
# An extern variable is externally defined: no initializer allowed in this module.
|
||||
_RecordDescriptorErr("extern 变量声明不能带初始值(符号定义在外部)",
|
||||
_RecordDescriptorErr("extern variable declaration cannot have an initializer (the symbol is defined externally)",
|
||||
lineno, col)
|
||||
ps.error_count += 1
|
||||
return None
|
||||
@@ -3846,12 +3846,12 @@ def _RecordStructErr(detail: str, lineno: int, col: int, extra: str):
|
||||
buf: str = stdlib.malloc(1536)
|
||||
if buf is not None:
|
||||
stdio.snprintf(buf, 1536,
|
||||
"[TPV] struct 定义非法(%s)。struct 与 class 同形,但**只能表示数据类型**:"
|
||||
"① 禁止 virtual / novirtual 修饰(struct 天然无虚表,已内置 @t.NoVTable);"
|
||||
"② 禁止在 struct 内定义 def(需要方法请改用 class);"
|
||||
"③ 允许在 REnum 内作为变体、也允许 struct 内再写 struct。"
|
||||
"正确示例:struct Point: x: int / struct Point: x: int 换行 4 空格 y: int。%s"
|
||||
"(struct 的约束不会被静默忽略:非法形态一律终止编译)", detail, extra)
|
||||
"[TPV] invalid struct definition (%s). A struct has the same shape as a class but **can only represent a data type**:"
|
||||
"(1) the virtual / novirtual modifier is forbidden (a struct has no vtable by nature, @t.NoVTable is built in);"
|
||||
"(2) defining a def inside a struct is forbidden (use class if methods are needed);"
|
||||
"(3) it may appear as a variant inside REnum, and a struct may contain another struct."
|
||||
" Correct example: struct Point: x: int / struct Point: x: int, then a newline with 4-space indented y: int.%s"
|
||||
" (struct constraints are never silently ignored: illegal forms all abort compilation)", detail, extra)
|
||||
_g_parse_err_msg = buf
|
||||
else:
|
||||
_g_parse_err_msg = detail
|
||||
@@ -3869,8 +3869,8 @@ def _parse_structdef(ps: Parser*) -> AST*:
|
||||
col: int = _cur_col(ps)
|
||||
_advance(ps) # struct
|
||||
if _cur_type(ps) != TokenType.Name:
|
||||
_RecordStructErr("`struct` 后缺少类型名", lineno, col,
|
||||
"正确写法:struct Point:(类型名紧跟 struct)。")
|
||||
_RecordStructErr("missing type name after `struct`", lineno, col,
|
||||
"Correct form: struct Point: (the type name follows struct immediately).")
|
||||
ps.error_count += 1
|
||||
return None
|
||||
name: str = _cur_str(ps)
|
||||
@@ -3942,10 +3942,10 @@ def _parse_structdef(ps: Parser*) -> AST*:
|
||||
fname_s: str = "(anonymous)"
|
||||
if fd_s is not None and fd_s.name is not None:
|
||||
fname_s = fd_s.name
|
||||
_RecordStructErr(f"struct '{name}' 内定义 def '{fname_s}'",
|
||||
_RecordStructErr(f"def '{fname_s}' defined inside struct '{name}'",
|
||||
it_s.lineno, it_s.col_offset,
|
||||
"struct 只表示数据类型(与 C 的 struct 同口径);"
|
||||
"若确实需要方法与虚表,请把该类型写成 class。")
|
||||
"a struct represents a data type only (same as C's struct);"
|
||||
" if methods and a vtable are really needed, write the type as a class.")
|
||||
ps.error_count += 1
|
||||
break
|
||||
_set_pos(node, lineno, col, 0, 0)
|
||||
@@ -4016,12 +4016,12 @@ def _RecordSwitchCaseErr(detail: str, lineno: int, col: int):
|
||||
buf: str = stdlib.malloc(512)
|
||||
if buf is not None:
|
||||
stdio.snprintf(buf, 512,
|
||||
"switch 的 case 标签非法(%s)。switch 只支持常量字面量或枚举变体标签"
|
||||
"(可多值 `case 1 | 2:`),不接受序列/映射/捕获等结构化模式。"
|
||||
"正确示例:case 1: / case \"a\": / case Color.Red: / case Opt.Some():", detail)
|
||||
"invalid switch case label (%s). switch supports only constant literals or enum variant labels"
|
||||
" (multi-value `case 1 | 2:` allowed); it does not accept structural patterns such as sequences/mappings/captures."
|
||||
" Correct examples: case 1: / case \"a\": / case Color.Red: / case Opt.Some():", detail)
|
||||
_g_parse_err_msg = buf
|
||||
else:
|
||||
_g_parse_err_msg = "switch 的 case 标签非法"
|
||||
_g_parse_err_msg = "invalid switch case label"
|
||||
|
||||
|
||||
def _CheckSwitchCasePattern(ps: Parser*, pat: AST*) -> int:
|
||||
@@ -4077,7 +4077,7 @@ def _parse_switch_case(ps: Parser*) -> AST*:
|
||||
_set_pos(mv, pattern.lineno, pattern.col_offset, 0, 0)
|
||||
pattern = mv
|
||||
if _CheckSwitchCasePattern(ps, pattern) == 0:
|
||||
_RecordSwitchCaseErr("case 标签不是常量/枚举变体", lineno, col)
|
||||
_RecordSwitchCaseErr("case label is not a constant/enum variant", lineno, col)
|
||||
ps.error_count += 1
|
||||
# guard: `case <value> if <cond> ':'` (same form as _parse_match_case)
|
||||
guard: AST* = None
|
||||
@@ -4617,7 +4617,7 @@ def parse_tokens(pool: memhub.MemManager*,
|
||||
if tok_count > PARSER_MAX_TOKENS:
|
||||
_g_parse_err_line = _cur_lineno(ps)
|
||||
_g_parse_err_col = _cur_col(ps)
|
||||
_g_parse_err_msg = "token 链表成环:lexer 输出的 token 链表无终止(_emit 重复追加同一 Token 或分配别名),已终止解析"
|
||||
_g_parse_err_msg = "token list is cyclic: the token list emitted by the lexer has no terminator (_emit appended the same Token twice or aliased it); parsing aborted"
|
||||
return None
|
||||
# Budget: the watchdog counts "query current token" calls (well below 256 per token in valid parses,
|
||||
# so it cannot trip falsely) while catching cycles/spins; it also bounds _advance and statement loops.
|
||||
@@ -4640,11 +4640,11 @@ def parse_tokens(pool: memhub.MemManager*,
|
||||
buf_e: str = stdlib.malloc(256)
|
||||
if buf_e is not None:
|
||||
stdio.snprintf(buf_e, 256,
|
||||
"语法错误:解析器已记录 %d 处错误但未记录具体原因;"
|
||||
"出错位置附近的 token='%s'(type=%d)",
|
||||
"syntax error: the parser recorded %d error(s) but no specific reason;"
|
||||
" token near the error position='%s' (type=%d)",
|
||||
ps.error_count, err_s_e, _cur_type(ps));
|
||||
_g_parse_err_msg = buf_e
|
||||
else:
|
||||
_g_parse_err_msg = "语法错误:解析器未记录具体原因"
|
||||
_g_parse_err_msg = "syntax error: the parser recorded no specific reason"
|
||||
return None
|
||||
return module_node
|
||||
+4
-4
@@ -10,8 +10,8 @@ def _ast_pool_fatal(what: str, need: sizet):
|
||||
"""Unified fail-fast when a pool alloc fails (returns NULL).
|
||||
Reports the real cause (pool exhausted) and terminates instead of leaving NULL str_val / dummy tokens.
|
||||
"""
|
||||
stdio.printf("[AST] %s 分配失败:内存池已耗尽(alloc 返回 NULL,need=%zu 字节)"
|
||||
"——上游有块被写穿/丢失,见 [MEM] 报告\n", what, need)
|
||||
stdio.printf("[AST] %s allocation failed: memory pool exhausted (alloc returned NULL, need=%zu bytes)"
|
||||
" -- an upstream block was overrun/lost, see [MEM] report\n", what, need)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
|
||||
@@ -296,7 +296,7 @@ def _kw_lookup(name: str) -> int:
|
||||
"""
|
||||
if name == None:
|
||||
# Defensive: a NULL str_val would crash _kw_hash_str and mask the real cause (pool exhausted).
|
||||
stdio.printf("[AST] _kw_lookup 收到 NULL 名称:token.str_val 未分配成功(内存池耗尽 / 未 set)\n")
|
||||
stdio.printf("[AST] _kw_lookup got a NULL name: token.str_val not allocated (memory pool exhausted / not set)\n")
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
if _kw_index != None:
|
||||
@@ -534,6 +534,6 @@ def token_set_str_literal(pool: memhub.MemManager*, tok: Token*,
|
||||
slen: sizet = string.strlen(text)
|
||||
buf: str = pool.alloc(slen + 1)
|
||||
if buf == None:
|
||||
_ast_pool_fatal("token.str_val(字面量)", slen + 1)
|
||||
_ast_pool_fatal("token.str_val(literal)", slen + 1)
|
||||
string.memcpy(buf, text, slen + 1)
|
||||
tok.str_val = buf
|
||||
@@ -393,12 +393,12 @@ class MemPool(MemManager):
|
||||
if size == 0: return None
|
||||
aligned: sizet = _align_up(size, MEMHUB_ALIGN)
|
||||
if self.offset + aligned > self.size:
|
||||
stdio.printf("\n[OOM] 内存不足 (Out of Memory)\n")
|
||||
stdio.printf("[OOM] 尝试分配: %zu 字节,失败\n", size)
|
||||
stdio.printf("[OOM] MemPool: total=%zu used=%zu (bump allocator, 无释放)\n",
|
||||
stdio.printf("\n[OOM] Out of Memory\n")
|
||||
stdio.printf("[OOM] attempted alloc: %zu bytes, failed\n", size)
|
||||
stdio.printf("[OOM] MemPool: total=%zu used=%zu (bump allocator, no free)\n",
|
||||
self.size, self.offset)
|
||||
stdio.printf("[OOM] 说明: 内存池已耗尽。可能原因: (1) 池大小不足,需增大 POOL_SIZE; (2) 存在内存泄漏。\n")
|
||||
stdio.printf("[OOM] 提示: 需要可控失败而非终止的调用方,请先用 MemPool.AllocOk(size) 预检。\n")
|
||||
stdio.printf("[OOM] note: pool exhausted. Likely causes: (1) pool too small, increase POOL_SIZE; (2) memory leak.\n")
|
||||
stdio.printf("[OOM] hint: callers needing controllable failure instead of termination should pre-check with MemPool.AllocOk(size).\n")
|
||||
stdlib.exit(1)
|
||||
ptr: rawptr = self.base + self.offset
|
||||
self.offset += aligned
|
||||
@@ -519,16 +519,16 @@ class MemSlab(MemManager):
|
||||
def alloc(self, size: sizet) -> rawptr:
|
||||
# Slab mode: allocate one block only if requested size <= block_size
|
||||
if self.free_list is None:
|
||||
stdio.printf("\n[OOM] 内存不足 (Out of Memory)\n")
|
||||
stdio.printf("[OOM] 尝试分配: %zu 字节,失败(free_list 已空)\n", size)
|
||||
stdio.printf("\n[OOM] Out of Memory\n")
|
||||
stdio.printf("[OOM] attempted alloc: %zu bytes, failed (free_list empty)\n", size)
|
||||
stdio.printf("[OOM] MemSlab: block_size=%zu block_count=%zu used=%zu\n",
|
||||
self.block_size, self.block_count, self.used_count)
|
||||
stdio.printf("[OOM] 说明: 内存池已耗尽。可能原因: (1) 池大小不足,需增大 POOL_SIZE; (2) 存在内存泄漏。\n")
|
||||
stdio.printf("[OOM] note: pool exhausted. Likely causes: (1) pool too small, increase POOL_SIZE; (2) memory leak.\n")
|
||||
stdlib.exit(1)
|
||||
if size > self.block_size:
|
||||
# Request larger than a block = caller error: fail gracefully with NULL (malloc-like,
|
||||
# caller decides), distinct from free-list exhaustion (real OOM, prints then exit(1)).
|
||||
stdio.printf("[WARN] MemSlab: 请求 %zu 字节超过 block_size=%zu,分配失败返回 NULL;应改用 MemBuddy/MemPool。\n",
|
||||
stdio.printf("[WARN] MemSlab: request %zu bytes exceeds block_size=%zu, alloc failed returning NULL; use MemBuddy/MemPool instead.\n",
|
||||
size, self.block_size)
|
||||
return None
|
||||
block: rawptr = self.free_list
|
||||
@@ -743,7 +743,7 @@ class MemBuddy(MemManager):
|
||||
# instance), which makes reset a no-op and leaks every later allocation (1 GB OOM).
|
||||
# fail-fast.
|
||||
stdio.printf(
|
||||
"[MEM] reset_to mark=%zu > chk_depth=%zu(mark 异常,reset 失效,终止)\n",
|
||||
"[MEM] reset_to mark=%zu > chk_depth=%zu (bad mark, reset disabled, terminating)\n",
|
||||
mark, self.chk_depth)
|
||||
return
|
||||
if mark >= self.chk_depth:
|
||||
@@ -859,7 +859,7 @@ class MemBuddy(MemManager):
|
||||
w3: uint64 = self._ff_word(block, 3)
|
||||
exp1: uint64 = self._ff_stamp(order)
|
||||
exp2: uint64 = uint64(MEMBUDDY_FREEFRAME_TAG2)
|
||||
stdio.printf("[FREEFRAME] 空闲块四字: block=%llu order=%d w0(next)=%llu w1=%llu(期望=0x%llx) w2=%llu(期望=0x%llx) w3(next镜像)=%llu\n",
|
||||
stdio.printf("[FREEFRAME] free-block four words: block=%llu order=%d w0(next)=%llu w1=%llu(expected=0x%llx) w2=%llu(expected=0x%llx) w3(next mirror)=%llu\n",
|
||||
uint64(block), order, w0, w1, exp1, w2, exp2, w3)
|
||||
dev_n: int = 0
|
||||
if w3 != w0:
|
||||
@@ -875,24 +875,24 @@ class MemBuddy(MemManager):
|
||||
# 0/8/16/24, so a run reaching offset 0 covers word0.
|
||||
lo_f: sizet = sizet(dev_n) * 8
|
||||
hi_f: sizet = (sizet(dev_n) + 1) * 8 - 1
|
||||
stdio.printf("[FREEFRAME] 跨度推断: 不符字数=%d/3 ⇒ 本空闲块内写入跨度 ∈ [%zu, %zu] 字节(通用式 [8n, 8n+7],n=不符字数;n=1⇒8..15, n=2⇒16..23, n=3⇒>=24);含左邻 canary 则 ∈ [%zu, %zu]\n",
|
||||
stdio.printf("[FREEFRAME] span inference: mismatched words=%d/3 => write span within this free block in [%zu, %zu] bytes (general form [8n, 8n+7], n=mismatched words; n=1=>8..15, n=2=>16..23, n=3=>>=24); with left-neighbour canary then in [%zu, %zu]\n",
|
||||
dev_n, lo_f, hi_f, lo_f + 8, hi_f + 8)
|
||||
# w1 / w3 cause: _fl_push is the only link-in site and always stamps w1 (non-zero), so
|
||||
# w2 == TAG2 proves the stamp was applied and w1 == 0 must be an off-list write; if
|
||||
# w2 != TAG2 the whole stamp is untrustworthy and w1 == 0 is not attributed on its own.
|
||||
if w2 == exp2:
|
||||
stdio.printf("[FREEFRAME] w1 成因: w2==TAG2 ⇒ 本块确经 _fl_push 打过印记(_ff_push_mark 三字同写)⇒ w1=0 是链外写入者清零,非入链漏打印记\n")
|
||||
stdio.printf("[FREEFRAME] w1 cause: w2==TAG2 => this block was indeed stamped by _fl_push (_ff_push_mark writes three words) => w1=0 was zeroed by an off-list writer, not a missing link-in stamp\n")
|
||||
else:
|
||||
stdio.printf("[FREEFRAME] w1 成因: w2!=TAG2 ⇒ 印记整体不可信(入链未打或三字俱被覆盖),w1=0 不单独归因\n")
|
||||
stdio.printf("[FREEFRAME] w1 cause: w2!=TAG2 => the whole stamp is untrustworthy (link-in not stamped or all three words overwritten); w1=0 is not attributed alone\n")
|
||||
if w3 == 0:
|
||||
stdio.printf("[FREEFRAME] w3 成因: 若写入范围未达偏移 24 ⇒ w3 保持入链原值 = 入链时的 old_head ⇒ =0 表示入链时 free_lists[order]==0(本块是链尾,next=NULL)\n")
|
||||
stdio.printf("[FREEFRAME] w3 cause: if the write did not reach offset 24 => w3 keeps its link-in value = old_head at link-in time => =0 means free_lists[order]==0 at link-in (this block is the tail, next=NULL)\n")
|
||||
else:
|
||||
stdio.printf("[FREEFRAME] w3 成因: w3!=0 但 !=w0 ⇒ 或 w0 被改(镜像失配)或 w3 本身被改,需结合跨度区间判读\n")
|
||||
stdio.printf("[FREEFRAME] w3 cause: w3!=0 but !=w0 => either w0 was changed (mirror mismatch) or w3 itself was changed; read together with the span range\n")
|
||||
# Left-neighbour probe: clamp max_order if it was written through, to avoid spinning.
|
||||
mo: int = self.max_order
|
||||
if mo < 0 or mo > MEMBUDDY_MAX_ORDERS:
|
||||
mo = MEMBUDDY_MAX_ORDERS
|
||||
stdio.printf("[FREEFRAME] 左邻探测(块尾正好落在 A 的分配块 = 越界写来源): max_order=%d usable=%llu\n",
|
||||
stdio.printf("[FREEFRAME] left-neighbour probe (block tail lands exactly in A's allocated block = overflow source): max_order=%d usable=%llu\n",
|
||||
mo, uint64(self.usable))
|
||||
o: int = 0
|
||||
found_l: int = 0
|
||||
@@ -906,7 +906,7 @@ class MemBuddy(MemManager):
|
||||
lcan: uint64 = *((uint64*)(block - MEMBUDDY_CANARY))
|
||||
found_l += 1
|
||||
if lcan != uint64(MEMBUDDY_CANARY_PATTERN):
|
||||
stdio.printf("[FREEFRAME] 阶 o=%d L=%llu hdr=0x%llX 用户ptr=%llu canary=0x%llx ⇒ canary 损坏(本块可能是写入者,也可能是被同一写者波及的受害者)——归属见下方「左邻归属判据/判定」两行\n",
|
||||
stdio.printf("[FREEFRAME] order o=%d L=%llu hdr=0x%llX user ptr=%llu canary=0x%llx => canary damaged (this block may be the writer, or a victim hit by the same writer) -- see the two lines 'left-neighbour attribution criteria/verdict' below\n",
|
||||
o, l_addr, lhdr, l_addr + MEMBUDDY_HEADER_SIZE,
|
||||
lcan)
|
||||
# Look up the writer's allocation: the record key is the block's returned
|
||||
@@ -930,11 +930,11 @@ class MemBuddy(MemManager):
|
||||
# file:line via a stable constant; no tag -> "?", never faked.
|
||||
w_site_r: str = _det_site_name(
|
||||
_det_site_get(lr_i, l_usr))
|
||||
stdio.printf("[FREEFRAME] 写入者分配记录: [%zu] ptr=%llu sz=%llu freemark=%d 原始字=%llu site=%s(sz 即写入者 alloc 请求尺寸;freemark=1 表该 ptr 已 free、0 表存活;site=该记录的调用点 tag 映射,无 tag 打 ?)\n",
|
||||
stdio.printf("[FREEFRAME] writer alloc record: [%zu] ptr=%llu sz=%llu freemark=%d raw word=%llu site=%s (sz is the writer's alloc request size; freemark=1 means that ptr was freed, 0 means alive; site=the call-site tag mapping of this record, ? if no tag)\n",
|
||||
lr_i, l_usr, w_sz_r, w_fr_r, w_raw_r, w_site_r)
|
||||
lr_hit += 1
|
||||
if lr_hit == 0:
|
||||
stdio.printf("[FREEFRAME] 写入者分配记录: 无(该用户指针无记录 ⇒ 记录表曾扩容/截断,或该块非经 alloc 得)\n")
|
||||
stdio.printf("[FREEFRAME] writer alloc record: none (no record for that user pointer => the record table was reallocated/truncated, or the block did not come from alloc)\n")
|
||||
# [FREEFRAME] Dump the writer's payload head/tail to separate an object
|
||||
# overflow from a wild pointer landing on this block's tail (see
|
||||
# _ff_owner_dump).
|
||||
@@ -943,15 +943,15 @@ class MemBuddy(MemManager):
|
||||
# canary alone cannot attribute; criteria in _ff_left_classify).
|
||||
self._ff_left_classify(l_addr, bs_o, lcan, w0)
|
||||
else:
|
||||
stdio.printf("[FREEFRAME] 阶 o=%d L=%llu hdr=0x%llX 用户ptr=%llu canary=0x%llx(完好:不是它的连续越界写)\n",
|
||||
stdio.printf("[FREEFRAME] order o=%d L=%llu hdr=0x%llX user ptr=%llu canary=0x%llx (intact: not a contiguous overflow write from it)\n",
|
||||
o, l_addr, lhdr, l_addr + MEMBUDDY_HEADER_SIZE,
|
||||
lcan)
|
||||
o += 1
|
||||
if found_l == 0:
|
||||
stdio.printf("[FREEFRAME] 无候选:左邻不存在「块头奇数且阶与几何一致」的分配块 ⇒ **不能**用左邻几何归因(写入者可能是野指针落点,或来自更远处,需另证)\n")
|
||||
stdio.printf("[FREEFRAME] no candidate: no allocated left neighbour with 'odd block header and matching order/geometry' => left-neighbour geometry CANNOT be used for attribution (the writer may be a wild-pointer landing, or from farther away; needs separate proof)\n")
|
||||
# Nearby records: which objects were allocated in this area (detection: ptr = user + 2).
|
||||
if self._det_records is not None:
|
||||
stdio.printf("[FREEFRAME] 记录表近邻(|ptr-A| <= 256): ")
|
||||
stdio.printf("[FREEFRAME] nearby records (|ptr-A| <= 256): ")
|
||||
printed: int = 0
|
||||
ri2: sizet = 0
|
||||
while ri2 < self._det_count and printed < 8:
|
||||
@@ -1001,11 +1001,11 @@ class MemBuddy(MemManager):
|
||||
head_addr: uint64 = uint64(block) + MEMBUDDY_HEADER_SIZE
|
||||
# Payload tail 16B (16 bytes before the canary).
|
||||
tail_addr: uint64 = uint64(block) + big - MEMBUDDY_CANARY - 16
|
||||
stdio.printf("[FREEFRAME] 写入者 payload 头16B(=%llu): ", head_addr)
|
||||
stdio.printf("[FREEFRAME] writer payload head16B(=%llu): ", head_addr)
|
||||
for bi_h in range(16):
|
||||
bv_h: uint8 = *((uint8*)(head_addr + uint64(bi_h)))
|
||||
stdio.printf("%02X ", uint32(bv_h))
|
||||
stdio.printf("| 尾16B(=%llu): ", tail_addr)
|
||||
stdio.printf("| tail16B(=%llu): ", tail_addr)
|
||||
for bi_t in range(16):
|
||||
bv_t: uint8 = *((uint8*)(tail_addr + uint64(bi_t)))
|
||||
stdio.printf("%02X ", uint32(bv_t))
|
||||
@@ -1022,14 +1022,14 @@ class MemBuddy(MemManager):
|
||||
d_fr: int = 0
|
||||
if (w_d & (uint64(1) << 63)) != 0:
|
||||
d_fr = 1
|
||||
stdio.printf("[FREEFRAME] 写入者请求尺寸: [%zu] sz=%llu freemark=%d 原始字=%llu;本块可写=%zu 字节(bs=%zu − 头%zu − canary%zu)\n",
|
||||
stdio.printf("[FREEFRAME] writer request size: [%zu] sz=%llu freemark=%d raw word=%llu; this block writable=%zu bytes (bs=%zu - header%zu - canary%zu)\n",
|
||||
ri_d, d_sz, d_fr, w_d,
|
||||
big - MEMBUDDY_HEADER_SIZE - MEMBUDDY_CANARY,
|
||||
big, sizet(MEMBUDDY_HEADER_SIZE),
|
||||
sizet(MEMBUDDY_CANARY))
|
||||
hit_d += 1
|
||||
if hit_d == 0:
|
||||
stdio.printf("[FREEFRAME] 写入者请求尺寸: 无记录(记录表曾扩容/截断,或该块非经 alloc 得)\n")
|
||||
stdio.printf("[FREEFRAME] writer request size: no record (the record table was reallocated/truncated, or the block did not come from alloc)\n")
|
||||
stdio.fflush(None)
|
||||
|
||||
def _ff_addr_in_pool(self, a: uint64) -> int:
|
||||
@@ -1085,7 +1085,7 @@ class MemBuddy(MemManager):
|
||||
can_eq_w0: int = 0
|
||||
if lcan == w0:
|
||||
can_eq_w0 = 1
|
||||
stdio.printf("[FREEFRAME] 左邻归属判据(实测): canary==A.word0=%d;L payload 尾16B全零=%d;写入值(=canary)在 L payload 出现=%zu 字;L payload 非零字 池内=%zu 池外=%zu(payload 共 %zu 字,起点 L+%zu)\n",
|
||||
stdio.printf("[FREEFRAME] left-neighbour criteria (measured): canary==A.word0=%d; L payload tail16B all zero=%d; written value (=canary) appears in L payload=%zu words; L payload non-zero words in-pool=%zu out-of-pool=%zu (payload total %zu words, starts at L+%zu)\n",
|
||||
can_eq_w0, tail_zero, hit_v, in_pool, out_pool, nw,
|
||||
sizet(MEMBUDDY_HEADER_SIZE))
|
||||
case_n: int = 0
|
||||
@@ -1094,12 +1094,12 @@ class MemBuddy(MemManager):
|
||||
if out_pool != 0:
|
||||
case_n = case_n + 2
|
||||
if case_n == 1 or case_n == 3:
|
||||
stdio.printf("[FREEFRAME] ⇒ 结论A:写入按 8 字节字推进(canary 与 A.word0 同值)且起点 ≤ L+%zu、**跳过**偏移 32..47 ⇒ 该次写**不是**「从 L 的 payload 尾部连续溢出」;若 L 的所有者确实越界,其写入宽度必然 > 申请尺寸 sz(对照上方「写入者请求尺寸」行)\n",
|
||||
stdio.printf("[FREEFRAME] => verdict A: the write advanced in 8-byte words (canary equals A.word0) and the start is <= L+%zu, SKIPPING offsets 32..47 => this write is NOT 'a contiguous overflow from the tail of L payload'; if L's owner did overflow, its write width must be > the request size sz (compare the 'writer request size' line above)\n",
|
||||
l_bs - MEMBUDDY_CANARY)
|
||||
if case_n == 2 or case_n == 3:
|
||||
stdio.printf("[FREEFRAME] ⇒ 结论B:L 的 payload 含**池外非零字**(本池 alloc 只产生池内地址或 0)⇒ 该 payload 不是「按 8 字节槽写元素指针」的结果 ⇒ 记录项的 sz 只是**申请**尺寸、不是写入范围:写入按更宽的结构体宽度跨字进行(或 payload 被第三方覆盖)⇒ 归属不能只看几何\n")
|
||||
stdio.printf("[FREEFRAME] => verdict B: L payload contains out-of-pool non-zero words (this pool's alloc only produces in-pool addresses or 0) => that payload is not the result of 'storing an element pointer per 8-byte slot' => the record's sz is only the REQUESTED size, not the written range: the write proceeds across words with a wider struct width (or the payload was overwritten by a third party) => attribution cannot rely on geometry alone\n")
|
||||
if case_n == 0:
|
||||
stdio.printf("[FREEFRAME] ⇒ 结论C:可区分特征均未命中 ⇒ 不据「几何 + canary 损坏」断言归属(需结合记录表现场与 payload 全量转储另证)\n")
|
||||
stdio.printf("[FREEFRAME] => verdict C: no distinguishing feature matched => do not assert attribution from 'geometry + damaged canary' (needs the record-table scene and a full payload dump as separate proof)\n")
|
||||
|
||||
def _ff_verify(self, order: int, block: rawptr):
|
||||
"""[FREEFRAME] Verify the free-block stamps before popping (detection only, caller-checked).
|
||||
@@ -1121,7 +1121,7 @@ class MemBuddy(MemManager):
|
||||
w3: uint64 = self._ff_word(block, 3)
|
||||
if w1 == self._ff_stamp(order) and w2 == uint64(MEMBUDDY_FREEFRAME_TAG2) and w3 == w0:
|
||||
return
|
||||
stdio.printf("[FREEFRAME] 空闲块元数据被写穿: order=%d block=%llu w0(next)=%llu w1=%llu(期望=0x%llx) w2=%llu(期望=0x%llx) w3(next镜像)=%llu(入链后被链外写入,立即转储)\n",
|
||||
stdio.printf("[FREEFRAME] free-block metadata written through: order=%d block=%llu w0(next)=%llu w1=%llu(expected=0x%llx) w2=%llu(expected=0x%llx) w3(next mirror)=%llu (written off-list after linking, dumping immediately)\n",
|
||||
order, uint64(block), w0, w1, self._ff_stamp(order), w2,
|
||||
uint64(MEMBUDDY_FREEFRAME_TAG2), w3)
|
||||
self._ff_report(order, block)
|
||||
@@ -1154,7 +1154,7 @@ class MemBuddy(MemManager):
|
||||
can_val: uint64 = cp[0]
|
||||
if can_val == uint64(MEMBUDDY_CANARY_PATTERN):
|
||||
return
|
||||
stdio.printf("[FREEFRAME] 释放前 canary 损坏(本块所有者**越过了本块可用区**;写入宽度见下方 payload 转储,`sz` 是申请尺寸、不是写入范围): block=%llu order=%d 用户ptr=%llu 合法写长=%zu canary=0x%llx 期望=0x%llx\n",
|
||||
stdio.printf("[FREEFRAME] pre-free canary damaged (this block's owner went PAST this block's usable area; see the payload dump below for the write width; `sz` is the requested size, not the written range): block=%llu order=%d user ptr=%llu legal write len=%zu canary=0x%llx expected=0x%llx\n",
|
||||
uint64(block), order, uint64(block) + MEMBUDDY_HEADER_SIZE,
|
||||
bs - MEMBUDDY_HEADER_SIZE - MEMBUDDY_CANARY, can_val,
|
||||
uint64(MEMBUDDY_CANARY_PATTERN))
|
||||
@@ -1163,7 +1163,7 @@ class MemBuddy(MemManager):
|
||||
dump_n: int = 8
|
||||
if uint64(block) + bs + 16 <= uint64(self.usable) + self.usable_size:
|
||||
dump_n = 24
|
||||
stdio.printf("[FREEFRAME] canary 起 %d 字节: ", dump_n)
|
||||
stdio.printf("[FREEFRAME] %d bytes from canary: ", dump_n)
|
||||
for bi in range(dump_n):
|
||||
bv: uint8 = *((uint8*)(can_addr + uint64(bi)))
|
||||
stdio.printf("%02X ", uint32(bv))
|
||||
@@ -1187,7 +1187,7 @@ class MemBuddy(MemManager):
|
||||
"alloc failed" and shift the failure point along the call chain.
|
||||
"""
|
||||
if order < 0 or order > MEMBUDDY_MAX_ORDERS:
|
||||
stdio.printf("[MEM] _fl_pop 调用者=_split_to_order order 越界: order=%d 容量=%d MAX_ORDERS=%d max_order=%d\n",
|
||||
stdio.printf("[MEM] _fl_pop caller=_split_to_order order out of range: order=%d capacity=%d MAX_ORDERS=%d max_order=%d\n",
|
||||
order, MEMBUDDY_MAX_ORDERS + 1, MEMBUDDY_MAX_ORDERS, self.max_order)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1197,7 +1197,7 @@ class MemBuddy(MemManager):
|
||||
# itself wild (e.g. free_lists=-1, order=0 => the first access is 0xffffffffffffffff). Must
|
||||
# be rejected before ANY free_lists[...] access, or even the guard is too late.
|
||||
if self.usable is not None and uint64(self.free_lists) != uint64(self.usable) - (MEMBUDDY_MAX_ORDERS + 1) * 8:
|
||||
stdio.printf("[MEM] _fl_pop 调用者=_split_to_order free_lists 基址非法(MemBuddy 对象被写穿): free_lists=%llu usable=%llu max_order=%d\n",
|
||||
stdio.printf("[MEM] _fl_pop caller=_split_to_order free_lists base invalid (MemBuddy object written through): free_lists=%llu usable=%llu max_order=%d\n",
|
||||
uint64(self.free_lists), uint64(self.usable), self.max_order)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1205,7 +1205,7 @@ class MemBuddy(MemManager):
|
||||
if head_val == 0:
|
||||
return None
|
||||
if self._fl_block_ok(rawptr(head_val)) == 0:
|
||||
stdio.printf("[MEM] _fl_pop 调用者=_split_to_order 链表头非法: order=%d head=%llu max_order=%d usable_size=%zu(free_lists[order] 被写穿:非池内对齐块地址)\n",
|
||||
stdio.printf("[MEM] _fl_pop caller=_split_to_order list head invalid: order=%d head=%llu max_order=%d usable_size=%zu (free_lists[order] written through: not an in-pool aligned block address)\n",
|
||||
order, head_val, self.max_order, self.usable_size)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1219,7 +1219,7 @@ class MemBuddy(MemManager):
|
||||
next_ptr: rawptr = rawptr(*((uint64*)(block)))
|
||||
next_val: uint64 = uint64(next_ptr)
|
||||
if next_val != 0 and self._fl_block_ok(rawptr(next_val)) == 0:
|
||||
stdio.printf("[MEM] _fl_pop 调用者=_split_to_order next 指针非法: order=%d block=%llu next=%llu max_order=%d usable_size=%zu(空闲块首字被写穿:next 非池内对齐块地址)\n",
|
||||
stdio.printf("[MEM] _fl_pop caller=_split_to_order next pointer invalid: order=%d block=%llu next=%llu max_order=%d usable_size=%zu (free block first word written through: next is not an in-pool aligned block address)\n",
|
||||
order, head_val, next_val, self.max_order, self.usable_size)
|
||||
stdio.fflush(None)
|
||||
# [FREEFRAME] In detection mode add a forensic dump (left-neighbour probe + nearby
|
||||
@@ -1257,7 +1257,7 @@ class MemBuddy(MemManager):
|
||||
while uint64(cur) != 0:
|
||||
steps += 1
|
||||
if steps > max_steps:
|
||||
stdio.printf("[MEM] free_lists[%d] 链成环或节点数超上限(next 指针被破坏): head=%llu target=%llu;停止遍历避免自旋,堆已损坏\n",
|
||||
stdio.printf("[MEM] free_lists[%d] chain cyclic or node count over limit (next pointer damaged): head=%llu target=%llu; stop walking to avoid spinning, heap corrupted\n",
|
||||
order, head_val, uint64(target))
|
||||
return 0
|
||||
# [FREEFRAME] Stamp check of the visited node (detection): the next hop comes from
|
||||
@@ -1309,7 +1309,7 @@ class MemBuddy(MemManager):
|
||||
# max_order must be in range before it indexes free_lists (a corrupt field would
|
||||
# otherwise read out of bounds and feed garbage to _fl_pop). fail-fast.
|
||||
if self.max_order < 0 or self.max_order > MEMBUDDY_MAX_ORDERS:
|
||||
stdio.printf("[MEM] _split_to_order max_order 非法(字段被写穿): to_order=%d max_order=%d 容量=%d MAX_ORDERS=%d usable_size=%zu\n",
|
||||
stdio.printf("[MEM] _split_to_order max_order invalid (field written through): to_order=%d max_order=%d capacity=%d MAX_ORDERS=%d usable_size=%zu\n",
|
||||
to_order, self.max_order, MEMBUDDY_MAX_ORDERS + 1, MEMBUDDY_MAX_ORDERS,
|
||||
self.usable_size)
|
||||
stdio.fflush(None)
|
||||
@@ -1338,7 +1338,7 @@ class MemBuddy(MemManager):
|
||||
# explicit bound) already guarantee order in [0, max_order], so behaviour changes only on
|
||||
# corruption.
|
||||
if order < 0 or order > MEMBUDDY_MAX_ORDERS:
|
||||
stdio.printf("[MEM] _coalesce order 非法(块头被写穿): order=%d 容量=%d MAX_ORDERS=%d max_order=%d block=%llu\n",
|
||||
stdio.printf("[MEM] _coalesce order invalid (block header written through): order=%d capacity=%d MAX_ORDERS=%d max_order=%d block=%llu\n",
|
||||
order, MEMBUDDY_MAX_ORDERS + 1, MEMBUDDY_MAX_ORDERS,
|
||||
self.max_order, uint64(block))
|
||||
stdio.fflush(None)
|
||||
@@ -1422,7 +1422,7 @@ class MemBuddy(MemManager):
|
||||
# and leave the existing "too big -> None" contract (the `order <= self.max_order`
|
||||
# branch below) untouched.
|
||||
if needed < size:
|
||||
stdio.printf("[MEM] alloc 调用者=上层 size 溢出: size=%zu needed=%zu(size+HEADER+CANARY 回绕,拒绝分配)\n",
|
||||
stdio.printf("[MEM] alloc caller=upper layer size overflow: size=%zu needed=%zu (size+HEADER+CANARY wrapped, alloc refused)\n",
|
||||
size, needed)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1461,7 +1461,7 @@ class MemBuddy(MemManager):
|
||||
# reclaim it -> a gradual leak ending in 1 GB main-pool OOM.
|
||||
# fail-fast instead of silent.
|
||||
stdio.printf(
|
||||
"[MEM] 记录栈 realloc 失败 cap=%zu depth=%zu(reset 将失效,终止)\n",
|
||||
"[MEM] record stack realloc failed cap=%zu depth=%zu (reset will be disabled, terminating)\n",
|
||||
self.chk_cap, self.chk_depth)
|
||||
if self.chk_depth < self.chk_cap:
|
||||
self.chk_stack[self.chk_depth] = uint64(block)
|
||||
@@ -1492,7 +1492,7 @@ class MemBuddy(MemManager):
|
||||
drp: uint64 = self._det_records[dup_i * 2]
|
||||
drs: uint64 = self._det_records[dup_i * 2 + 1]
|
||||
if drp == rec_ptr_d and (drs & ff_d) == 0:
|
||||
stdio.printf("[DET] 分配重叠: 新alloc(size=%llu)与记录[%zu](sz=%llu)同地址 ptr=%llu(同一块重复分配,free list 损坏)\n",
|
||||
stdio.printf("[DET] alloc overlap: new alloc(size=%llu) and record[%zu](sz=%llu) share address ptr=%llu (same block allocated twice, free list corrupted)\n",
|
||||
uint64(size), dup_i, drs & (ff_d - 1), rec_ptr_d)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1506,7 +1506,7 @@ class MemBuddy(MemManager):
|
||||
# (the very case this branch hunts), indexing free_lists[dbg_order]
|
||||
# would read out of bounds and feed garbage to a deref. fail-fast.
|
||||
if dbg_order < 0 or dbg_order > MEMBUDDY_MAX_ORDERS:
|
||||
stdio.printf("[MEMDBG] alloc dbg_order 非法(块头被写穿): hdr=0x%llX dbg_order=%d 容量=%d block=%llu(终止)\n",
|
||||
stdio.printf("[MEMDBG] alloc dbg_order invalid (block header written through): hdr=0x%llX dbg_order=%d capacity=%d block=%llu (terminating)\n",
|
||||
uint64(dbg_hdr), dbg_order, MEMBUDDY_MAX_ORDERS + 1,
|
||||
uint64(dbg_block))
|
||||
stdio.fflush(None)
|
||||
@@ -1515,13 +1515,13 @@ class MemBuddy(MemManager):
|
||||
dbg_n: sizet = 0
|
||||
while uint64(dbg_cur) != 0:
|
||||
if uint64(dbg_cur) == uint64(dbg_block):
|
||||
stdio.printf("[MEMDBG] alloc 重复出块: size=%llu block=%llu 仍残留 free list order=%d(重复 put 实锤,终止)\n",
|
||||
stdio.printf("[MEMDBG] alloc duplicate block: size=%llu block=%llu still remains on free list order=%d (duplicate put proven, terminating)\n",
|
||||
uint64(size), uint64(dbg_block), dbg_order)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
dbg_n += 1
|
||||
if dbg_n > self.usable_size / MEMBUDDY_MIN_BLOCK + 2:
|
||||
stdio.printf("[MEMDBG] alloc 扫描 free list order=%d 成环/超长(自检异常,终止)\n", dbg_order)
|
||||
stdio.printf("[MEMDBG] alloc scan free list order=%d cyclic/over-long (self-check abnormal, terminating)\n", dbg_order)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
dbg_cur = rawptr(*((uint64*)(dbg_cur)))
|
||||
@@ -1550,9 +1550,9 @@ class MemBuddy(MemManager):
|
||||
# (unresolved or shadowed constant). Never exit here: alloc failures return None
|
||||
# for the caller to handle (tests rely on free-and-retry after OOM).
|
||||
if size == 0:
|
||||
stdio.printf("[MEM] alloc 请求尺寸为 0:返回 NULL(非池耗尽!)——"
|
||||
"请检查调用处尺寸表达式是否被静默求值为 0"
|
||||
"(常量未解析/被同名符号遮蔽/被算成 0)\n")
|
||||
stdio.printf("[MEM] alloc request size is 0: returning NULL (NOT pool exhaustion!) --"
|
||||
"check whether the caller's size expression was silently evaluated to 0"
|
||||
"(constant unresolved/shadowed by a same-named symbol/evaluated to 0)\n")
|
||||
# Fields below are read from existing state only (this branch runs only on
|
||||
# failure): site tag, pool alloc sequence, zero-size hit count, pool state,
|
||||
# and the stage/detail context set by TPV.
|
||||
@@ -1563,8 +1563,8 @@ class MemBuddy(MemManager):
|
||||
if self.chk_stack is not None:
|
||||
marked = 1
|
||||
zero_hits: sizet = _zero_alloc_note()
|
||||
stdio.printf("[MEM] site=%s ctx=%s/%s marked=%d 本池分配序号=%zu 0尺寸累计=%zu "
|
||||
"池基址=%llu 池容量=%zu 已用=%zu 空闲=%zu "
|
||||
stdio.printf("[MEM] site=%s ctx=%s/%s marked=%d pool alloc seq=%zu zero-size total=%zu "
|
||||
"pool base=%llu pool capacity=%zu used=%zu free=%zu "
|
||||
"max_order=%d detection=%d deep=%d\n",
|
||||
_det_site_name(_alloc_site_current()),
|
||||
_alloc_ctx_stage_str(), _alloc_ctx_detail_str(), marked,
|
||||
@@ -1576,12 +1576,12 @@ class MemBuddy(MemManager):
|
||||
elif self.usable is not None:
|
||||
needed2: sizet = size + MEMBUDDY_HEADER_SIZE + MEMBUDDY_CANARY
|
||||
order2: int = self._order_for_size(needed2)
|
||||
stdio.printf("[MEM] alloc 失败 size=%zu needed=%zu order=%d max_order=%d used=%zu pool_base=%llu\n",
|
||||
stdio.printf("[MEM] alloc failed size=%zu needed=%zu order=%d max_order=%d used=%zu pool_base=%llu\n",
|
||||
size, needed2, order2, self.max_order, self.used_bytes(),
|
||||
uint64(self.usable))
|
||||
# Attribution (always-on, no --detection needed): site comes from the alloc_tagged site
|
||||
# tag, ctx=stage/current file from TPV's SetAllocCtx (? if unset). Failure path only.
|
||||
stdio.printf("[MEM] 归属 site=%s ctx=%s/%s 池容量=%zu\n",
|
||||
stdio.printf("[MEM] attribution site=%s ctx=%s/%s pool capacity=%zu\n",
|
||||
_det_site_name(_alloc_site_current()),
|
||||
_alloc_ctx_stage_str(), _alloc_ctx_detail_str(),
|
||||
self.usable_size)
|
||||
@@ -1592,22 +1592,22 @@ class MemBuddy(MemManager):
|
||||
win_net: sizet = 0
|
||||
if win_start_free > win_now_free:
|
||||
win_net = win_start_free - win_now_free
|
||||
stdio.printf("[MEM] 本窗口起点空闲=%zu 当前空闲=%zu(窗口内净分配=%zu)\n",
|
||||
stdio.printf("[MEM] window start free=%zu current free=%zu (net alloc in window=%zu)\n",
|
||||
win_start_free, win_now_free, win_net)
|
||||
# Size profile: see which orders of live blocks filled the pool (read-only, no --detection).
|
||||
self.dump_alive_orders()
|
||||
# self_check != 0 means the free list structure is damaged (a block header or
|
||||
# next pointer was written through), so alloc finds no block despite free space.
|
||||
sc: int = self.self_check()
|
||||
stdio.printf("[MEM] alloc 失败 self_check=%d free_bytes=%zu free_count=%zu chk_depth=%zu big=%zu\n",
|
||||
stdio.printf("[MEM] alloc failed self_check=%d free_bytes=%zu free_count=%zu chk_depth=%zu big=%zu\n",
|
||||
sc, self.free_bytes(), self.free_count(), self.chk_depth, self.big_alloc_count)
|
||||
# Huge chk_depth => allocation storm (per-statement/per-call); small chk_depth
|
||||
# with huge used => repeated single large allocations (buffers/table growth).
|
||||
if order2 > self.max_order:
|
||||
stdio.printf("[MEM] 原因:请求 size 超 pool 最大块(order %d > max %d)\n",
|
||||
stdio.printf("[MEM] cause: requested size exceeds pool max block (order %d > max %d)\n",
|
||||
order2, self.max_order)
|
||||
else:
|
||||
stdio.printf("[MEM] 原因:pool 耗尽(空闲 %zu 字节不足)\n", self.free_bytes())
|
||||
stdio.printf("[MEM] cause: pool exhausted (free %zu bytes insufficient)\n", self.free_bytes())
|
||||
# Failure (alloc(0) or exhausted): unlock and return None; the caller decides.
|
||||
# Must not exit -- tests free a block and retry after an OOM.
|
||||
self._unlock()
|
||||
@@ -1669,7 +1669,7 @@ class MemBuddy(MemManager):
|
||||
# off (never coalesce again, to avoid a duplicate free-list put); with
|
||||
# debug on, terminate and expose the stale/duplicate free call site.
|
||||
if _memdbg_enable != 0:
|
||||
stdio.printf("[MEMDBG] 悬空/重复 free: ptr=%llu block=%llu header=0x%llX(偶数=已释放/未初始化,终止)\n",
|
||||
stdio.printf("[MEMDBG] dangling/duplicate free: ptr=%llu block=%llu header=0x%llX (even=already freed/uninitialized, terminating)\n",
|
||||
uint64(ptr), uint64(block), stored_val)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1687,13 +1687,13 @@ class MemBuddy(MemManager):
|
||||
dbg_fn: sizet = 0
|
||||
while uint64(dbg_f) != 0:
|
||||
if uint64(dbg_f) == uint64(block):
|
||||
stdio.printf("[MEMDBG] 重复归还: free(ptr=%llu) block=%llu 已在 free list order=%d(double-put 实锤,终止)\n",
|
||||
stdio.printf("[MEMDBG] duplicate return: free(ptr=%llu) block=%llu already on free list order=%d (double-put proven, terminating)\n",
|
||||
uint64(ptr), uint64(block), order)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
dbg_fn += 1
|
||||
if dbg_fn > self.usable_size / MEMBUDDY_MIN_BLOCK + 2:
|
||||
stdio.printf("[MEMDBG] free 扫描 free list order=%d 成环/超长(自检异常,终止)\n", order)
|
||||
stdio.printf("[MEMDBG] free scan free list order=%d cyclic/over-long (self-check abnormal, terminating)\n", order)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
dbg_f = rawptr(*((uint64*)(dbg_f)))
|
||||
@@ -1709,7 +1709,7 @@ class MemBuddy(MemManager):
|
||||
and dbg_blk < uint64(self.usable) + self.usable_size):
|
||||
dbg_hv: uint64 = *((uint64*)(dbg_blk))
|
||||
if (dbg_hv & 1) == 0:
|
||||
stdio.printf("[MEMDBG] 悬空/重复 free: ptr=%llu block=%llu header=0x%llX(偶数=已释放/未初始化,终止)\n",
|
||||
stdio.printf("[MEMDBG] dangling/duplicate free: ptr=%llu block=%llu header=0x%llX (even=already freed/uninitialized, terminating)\n",
|
||||
uint64(ptr), dbg_blk, dbg_hv)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -1744,9 +1744,9 @@ class MemBuddy(MemManager):
|
||||
e_ci += 1
|
||||
else:
|
||||
e_in_win = -1 # record stack full (chk_depth==chk_cap) -> check skipped
|
||||
stdio.printf("[MEM] free 被拒绝: ptr=%llu block=%llu 在池内=%d 对齐=%d "
|
||||
"块头=0x%llX 块头奇数=%d 在记录窗口=%d chk_depth=%zu "
|
||||
"本池 base=%llu usable=%llu usable_size=%zu\n",
|
||||
stdio.printf("[MEM] free rejected: ptr=%llu block=%llu in_pool=%d aligned=%d "
|
||||
"header=0x%llX header_odd=%d in_record_window=%d chk_depth=%zu "
|
||||
"this pool base=%llu usable=%llu usable_size=%zu\n",
|
||||
e_eff, e_blk, e_in_pool, e_aligned, e_hdr, e_hdr_odd,
|
||||
e_in_win, self.chk_depth,
|
||||
uint64(self.base), uint64(self.usable), self.usable_size)
|
||||
@@ -1877,26 +1877,26 @@ class MemBuddy(MemManager):
|
||||
m_fa: uint16* = (uint16*)(p - 2)
|
||||
mfv_a: uint16 = m_fa[0]
|
||||
if mfv_a != uint16(MEMBUDDY_DET_MARKER):
|
||||
stdio.printf("[DET] 下溢写: ptr=%llu size=%llu 前标记=0x%04X(期望 0xCDCD)\n",
|
||||
stdio.printf("[DET] underflow write: ptr=%llu size=%llu front marker=0x%04X (expected 0xCDCD)\n",
|
||||
p, s, uint32(mfv_a))
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
m16: uint16* = (uint16*)(p + s)
|
||||
mv: uint16 = m16[0]
|
||||
if mv != uint16(MEMBUDDY_DET_MARKER):
|
||||
stdio.printf("[DET] 越界写: ptr=%llu size=%llu 后标记=0x%04X(期望 0xCDCD)块内容前16B: ",
|
||||
stdio.printf("[DET] out-of-bounds write: ptr=%llu size=%llu tail marker=0x%04X (expected 0xCDCD) block content first16B: ",
|
||||
p, s, uint32(mv))
|
||||
for bi3 in range(16):
|
||||
bv3: uint8 = *((uint8*)(p + uint64(bi3)))
|
||||
stdio.printf("%02X ", uint32(bv3))
|
||||
# Overflow region (24 bytes from ptr+size): 0x00 = written through, 0xCD = not
|
||||
# written, other = written value; shows how far/direction the writer went.
|
||||
stdio.printf("越界区: ")
|
||||
stdio.printf("overflow region: ")
|
||||
for bj3 in range(24):
|
||||
bvj: uint8 = *((uint8*)(p + s + uint64(bj3)))
|
||||
stdio.printf("%02X ", uint32(bvj))
|
||||
# Record-table context: the 3 records before/after, to infer the phase.
|
||||
stdio.printf("\n记录上下文: ")
|
||||
stdio.printf("\nrecord context: ")
|
||||
ci2: int = -3
|
||||
while ci2 <= 3:
|
||||
idx2: sizet = sizet(int(i) + ci2)
|
||||
@@ -1907,7 +1907,7 @@ class MemBuddy(MemManager):
|
||||
ci2 += 1
|
||||
# Overlap check: a ptr with several records means alloc handed the same block to
|
||||
# different size requests (they overwrite each other).
|
||||
stdio.printf("\n同ptr记录: ")
|
||||
stdio.printf("\nsame-ptr records: ")
|
||||
for ci3 in range(self._det_count):
|
||||
cp3: uint64 = self._det_records[ci3 * 2]
|
||||
cs3: uint64 = self._det_records[ci3 * 2 + 1]
|
||||
@@ -1942,7 +1942,7 @@ class MemBuddy(MemManager):
|
||||
cur: rawptr = rawptr(head_val)
|
||||
if uint64(cur) != 0 and self._fl_block_ok(cur) == 0:
|
||||
# Free-list head itself invalid (e.g. uninitialized 0xBE...): dereferencing would AV; report and stop this order.
|
||||
stdio.printf("[MEM] free_lists[%d] 头非法(非池内对齐块地址,疑元数据未初始化/被写穿): "
|
||||
stdio.printf("[MEM] free_lists[%d] head invalid (not an in-pool aligned block address; metadata possibly uninitialized/written through): "
|
||||
"head=%llu chk_depth=%zu usable=%llu usable_size=%zu\n",
|
||||
i, head_val, self.chk_depth, uint64(self.usable), self.usable_size)
|
||||
stdio.fflush(None)
|
||||
@@ -1951,7 +1951,7 @@ class MemBuddy(MemManager):
|
||||
while uint64(cur) != 0:
|
||||
steps += 1
|
||||
if steps > max_steps:
|
||||
stdio.printf("[MEM] free_lists[%d] 链成环或节点数超上限(next 指针被破坏): head=%llu;停止计数避免自旋,堆已损坏\n",
|
||||
stdio.printf("[MEM] free_lists[%d] chain cyclic or node count over limit (next pointer damaged): head=%llu; stop counting to avoid spinning, heap corrupted\n",
|
||||
i, head_val)
|
||||
break
|
||||
count += 1
|
||||
@@ -1959,7 +1959,7 @@ class MemBuddy(MemManager):
|
||||
if uint64(next_p) != 0 and self._fl_block_ok(next_p) == 0:
|
||||
# Head/node invalid (uninitialized 0xBE... or non-pool-aligned): further dereference
|
||||
# would AV, so just report and stop counting this order (metadata corruption proof).
|
||||
stdio.printf("[MEM] free_lists[%d] 节点非法(非池内对齐块地址,疑元数据未初始化/被写穿): "
|
||||
stdio.printf("[MEM] free_lists[%d] node invalid (not an in-pool aligned block address; metadata possibly uninitialized/written through): "
|
||||
"head=%llu cur=%llu next=%llu chk_depth=%zu usable=%llu usable_size=%zu\n",
|
||||
i, head_val, uint64(cur), uint64(next_p), self.chk_depth,
|
||||
uint64(self.usable), self.usable_size)
|
||||
@@ -1979,7 +1979,7 @@ class MemBuddy(MemManager):
|
||||
cur: rawptr = rawptr(head_val)
|
||||
if uint64(cur) != 0 and self._fl_block_ok(cur) == 0:
|
||||
# Free-list head itself invalid (e.g. uninitialized 0xBE...): dereferencing would AV; report and stop this order.
|
||||
stdio.printf("[MEM] free_lists[%d] 头非法(非池内对齐块地址,疑元数据未初始化/被写穿): "
|
||||
stdio.printf("[MEM] free_lists[%d] head invalid (not an in-pool aligned block address; metadata possibly uninitialized/written through): "
|
||||
"head=%llu chk_depth=%zu usable=%llu usable_size=%zu\n",
|
||||
i, head_val, self.chk_depth, uint64(self.usable), self.usable_size)
|
||||
stdio.fflush(None)
|
||||
@@ -1988,13 +1988,13 @@ class MemBuddy(MemManager):
|
||||
while uint64(cur) != 0:
|
||||
steps += 1
|
||||
if steps > max_steps:
|
||||
stdio.printf("[MEM] free_lists[%d] 链成环或节点数超上限(next 指针被破坏): head=%llu;停止统计避免自旋,堆已损坏\n",
|
||||
stdio.printf("[MEM] free_lists[%d] chain cyclic or node count over limit (next pointer damaged): head=%llu; stop counting to avoid spinning, heap corrupted\n",
|
||||
i, head_val)
|
||||
break
|
||||
total += _block_size_at_order(i)
|
||||
next_b: rawptr = rawptr(*((uint64*)(cur)))
|
||||
if uint64(next_b) != 0 and self._fl_block_ok(next_b) == 0:
|
||||
stdio.printf("[MEM] free_lists[%d] 节点非法(非池内对齐块地址,疑元数据未初始化/被写穿): "
|
||||
stdio.printf("[MEM] free_lists[%d] node invalid (not an in-pool aligned block address; metadata possibly uninitialized/written through): "
|
||||
"head=%llu cur=%llu next=%llu chk_depth=%zu usable=%llu usable_size=%zu\n",
|
||||
i, head_val, uint64(cur), uint64(next_b), self.chk_depth,
|
||||
uint64(self.usable), self.usable_size)
|
||||
@@ -2079,28 +2079,28 @@ class MemBuddy(MemManager):
|
||||
lost: sizet = 0
|
||||
if self.usable_size > alive_bytes + fb:
|
||||
lost = self.usable_size - alive_bytes - fb
|
||||
stdio.printf("[MEM] 整池账目:镜像存活=%zu 块/%zu 字节 空闲链表=%zu 字节 "
|
||||
"丢失=%zu 字节(丢失=既不在链表也不被持有 ⇒ 空闲链被写穿后截断)\n",
|
||||
stdio.printf("[MEM] whole-pool accounting: mirror live=%zu blocks/%zu bytes free lists=%zu bytes "
|
||||
"lost=%zu bytes (lost=neither on the lists nor held => free chain truncated after being written through)\n",
|
||||
live, alive_bytes, fb, lost)
|
||||
# Segmentation: only the part allocated after mark() is "this window"; the total would also
|
||||
# include the historical prefix (mark1 runs once in Phase1 1b => prefix=1a, window=1b).
|
||||
stdio.printf("[MEM] 分段(mark_depth=%zu chk_depth=%zu):前缀[0,mark)=%zu 块/%zu 字节 "
|
||||
"本窗口[mark,end)=%zu 块/%zu 字节\n",
|
||||
stdio.printf("[MEM] segments (mark_depth=%zu chk_depth=%zu): prefix[0,mark)=%zu blocks/%zu bytes "
|
||||
"this window[mark,end)=%zu blocks/%zu bytes\n",
|
||||
self.mark_depth, self.chk_depth, pfx_live, pfx_bytes_a,
|
||||
win_live, win_bytes_a)
|
||||
stdio.printf("[MEM] 存活块 order 分布(记录在案共 %zu 块;单块=%llu<<order 字节):\n",
|
||||
stdio.printf("[MEM] live-block order distribution (%zu blocks recorded total; single block=%llu<<order bytes):\n",
|
||||
live, uint64(MEMBUDDY_MIN_BLOCK))
|
||||
for oi in range(max_o + 1):
|
||||
cnt: uint64 = counts[oi]
|
||||
if cnt != 0:
|
||||
blk: uint64 = uint64(MEMBUDDY_MIN_BLOCK) << oi
|
||||
stdio.printf("[MEM] order=%d 块=%llu 单块=%llu 合计=%llu\n",
|
||||
stdio.printf("[MEM] order=%d blocks=%llu single=%llu total=%llu\n",
|
||||
oi, cnt, blk, cnt * blk)
|
||||
if bad != 0:
|
||||
stdio.printf("[MEM] 记录项异常(NULL/越界/块头 order 非法)共 %zu 条;"
|
||||
"抽样 4 条(addr / 块头):\n", bad)
|
||||
stdio.printf("[MEM] abnormal record entries (NULL/out-of-range/block header order invalid) total %zu;"
|
||||
"sampling 4 entries (addr / block header):\n", bad)
|
||||
else:
|
||||
stdio.printf("[MEM] 记录项抽样 4 条(addr / 块头):\n")
|
||||
stdio.printf("[MEM] sampling 4 record entries (addr / block header):\n")
|
||||
si: sizet = 0
|
||||
dstep: sizet = self.chk_depth / 4
|
||||
if dstep == 0:
|
||||
@@ -2145,7 +2145,7 @@ class MemBuddy(MemManager):
|
||||
cur: rawptr = rawptr(head_val)
|
||||
if uint64(cur) != 0 and self._fl_block_ok(cur) == 0:
|
||||
# Free-list head itself invalid (e.g. uninitialized 0xBE...): dereferencing would AV; report and stop this order.
|
||||
stdio.printf("[MEM] free_lists[%d] 头非法(非池内对齐块地址,疑元数据未初始化/被写穿): "
|
||||
stdio.printf("[MEM] free_lists[%d] head invalid (not an in-pool aligned block address; metadata possibly uninitialized/written through): "
|
||||
"head=%llu chk_depth=%zu usable=%llu usable_size=%zu\n",
|
||||
i, head_val, self.chk_depth, uint64(self.usable), self.usable_size)
|
||||
stdio.fflush(None)
|
||||
@@ -2179,7 +2179,7 @@ class MemBuddy(MemManager):
|
||||
# from_mark > chk_depth: the caller's mark is bogus (wrong field / cross-instance),
|
||||
# which would make the check a no-op and miss overflows. fail-fast.
|
||||
stdio.printf(
|
||||
"[MEM] check_alive_blocks from_mark=%zu > chk_depth=%zu(mark 异常)\n",
|
||||
"[MEM] check_alive_blocks from_mark=%zu > chk_depth=%zu (bad mark)\n",
|
||||
from_mark, self.chk_depth)
|
||||
return 0
|
||||
if from_mark >= self.chk_depth:
|
||||
@@ -2192,12 +2192,12 @@ class MemBuddy(MemManager):
|
||||
if block is not None:
|
||||
if uint64(block) < uint64(self.usable):
|
||||
# Block address below the pool start.
|
||||
stdio.printf("[MEM] 存活块损坏 rc=1(块地址低于 usable): block=%llu usable=%llu ci=%zu from_mark=%zu\n",
|
||||
stdio.printf("[MEM] live block corrupted rc=1 (block address below usable): block=%llu usable=%llu ci=%zu from_mark=%zu\n",
|
||||
uint64(block), uint64(self.usable), ci, from_mark)
|
||||
return 1
|
||||
if uint64(block) >= uint64(self.usable) + self.usable_size:
|
||||
# Block address past the pool end.
|
||||
stdio.printf("[MEM] 存活块损坏 rc=2(块地址超出池末尾): block=%llu usable=%llu ci=%zu from_mark=%zu\n",
|
||||
stdio.printf("[MEM] live block corrupted rc=2 (block address past pool end): block=%llu usable=%llu ci=%zu from_mark=%zu\n",
|
||||
uint64(block), uint64(self.usable), ci, from_mark)
|
||||
return 2
|
||||
stored: rawptr = rawptr(*((uint64*)(block)))
|
||||
@@ -2207,19 +2207,19 @@ class MemBuddy(MemManager):
|
||||
order: int = int(stored_val >> 1)
|
||||
if order < 0:
|
||||
# Negative order (header written through).
|
||||
stdio.printf("[MEM] 存活块损坏 rc=3(order 为负): block=%llu order=%d ci=%zu from_mark=%zu\n",
|
||||
stdio.printf("[MEM] live block corrupted rc=3 (order negative): block=%llu order=%d ci=%zu from_mark=%zu\n",
|
||||
uint64(block), order, ci, from_mark)
|
||||
return 3
|
||||
if order > self.max_order:
|
||||
# order beyond max_order.
|
||||
stdio.printf("[MEM] 存活块损坏 rc=4(order 超 max_order): block=%llu order=%d max_order=%d ci=%zu from_mark=%zu\n",
|
||||
stdio.printf("[MEM] live block corrupted rc=4 (order over max_order): block=%llu order=%d max_order=%d ci=%zu from_mark=%zu\n",
|
||||
uint64(block), order, self.max_order, ci, from_mark)
|
||||
return 4
|
||||
offset: sizet = uint64(block) - uint64(self.usable)
|
||||
bs: sizet = _block_size_at_order(order)
|
||||
if offset % bs != 0:
|
||||
# Block not aligned to its order's block size.
|
||||
stdio.printf("[MEM] 存活块损坏 rc=5(块未对齐 order 大小): block=%llu order=%d bs=%zu offset=%zu ci=%zu from_mark=%zu\n",
|
||||
stdio.printf("[MEM] live block corrupted rc=5 (block not aligned to order size): block=%llu order=%d bs=%zu offset=%zu ci=%zu from_mark=%zu\n",
|
||||
uint64(block), order, bs, offset, ci, from_mark)
|
||||
return 5
|
||||
# Block-tail canary check: the key sentinel for overflow damage. The canary is
|
||||
@@ -2231,7 +2231,7 @@ class MemBuddy(MemManager):
|
||||
# Overflow scene: the block-tail canary was overwritten (rc=6). Report the
|
||||
# block/order/bs plus the index and window start for location.
|
||||
stdio.printf(
|
||||
"[MEM] canary 损坏: block=%llu order=%d bs=%zu ci=%zu from_mark=%zu canary=0x%llx 期望=0x%llx\n",
|
||||
"[MEM] canary corrupted: block=%llu order=%d bs=%zu ci=%zu from_mark=%zu canary=0x%llx expected=0x%llx\n",
|
||||
uint64(block), order, bs, ci, from_mark,
|
||||
uint64(can_stored), uint64(MEMBUDDY_CANARY_PATTERN))
|
||||
# Width diagnostic: print the high/low 32-bit halves of the read value and
|
||||
@@ -2244,7 +2244,7 @@ class MemBuddy(MemManager):
|
||||
exp_hi: uint64 = exp_d >> 32
|
||||
exp_lo: uint64 = exp_d - (exp_hi << 32)
|
||||
stdio.printf(
|
||||
"[MEM] canary 位宽诊断: canary_lo=0x%llx canary_hi=0x%llx 期望_lo=0x%llx 期望_hi=0x%llx\n",
|
||||
"[MEM] canary width diagnostic: canary_lo=0x%llx canary_hi=0x%llx expected_lo=0x%llx expected_hi=0x%llx\n",
|
||||
can_lo, can_hi, exp_lo, exp_hi)
|
||||
# Flush so the scene survives a redirected stdout (the caller prints then exits).
|
||||
stdio.fflush(None)
|
||||
|
||||
@@ -80,7 +80,7 @@ novirtual class IRBuilder:
|
||||
c0: int = buf[0]
|
||||
if c0 == 0 or (c0 != 'i' and c0 != 'f' and c0 != '!' and c0 != 'n' and
|
||||
c0 != '[' and c0 != '{' and c0 != '%' and c0 != '"'):
|
||||
stdio.printf("[IR-FAIL] _type_str: LLVMType 对象已损坏 ty=0x%llx 首字符=%d 输出='%s'\n",
|
||||
stdio.printf("[IR-FAIL] _type_str: corrupted LLVMType object ty=0x%llx first char=%d output='%s'\n",
|
||||
uint64(ty), c0, buf)
|
||||
stdlib.exit(1)
|
||||
return None
|
||||
|
||||
+71
-71
@@ -392,7 +392,7 @@ def _ll_name_needs_quote(name: str) -> int:
|
||||
# ============================================================
|
||||
def _MlirSymRefAppend(out: str, outsz: sizet, name: str):
|
||||
if name is None or name[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 空符号名")
|
||||
MlirFail("MLIR render: empty symbol name")
|
||||
if name[0] == '"':
|
||||
_append_cstr(out, outsz, "@")
|
||||
_append_cstr(out, outsz, name)
|
||||
@@ -505,7 +505,7 @@ def _find_max_ssa_number(func: Function*) -> int:
|
||||
while blk is not None:
|
||||
blk_steps += 1
|
||||
if blk_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: func blocks(函数名=%s,ssa 扫描终止)\n", func.Name)
|
||||
stdio.printf("[IR-DUMP] cyclic list: func blocks (func name=%s, ssa scan aborted)\n", func.Name)
|
||||
stdlib.exit(1)
|
||||
if blk.Lines is not None:
|
||||
lines: GSList[Line]* = blk.Lines
|
||||
@@ -514,7 +514,7 @@ def _find_max_ssa_number(func: Function*) -> int:
|
||||
while line is not None:
|
||||
line_steps += 1
|
||||
if line_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: block lines(函数名=%s,块=%s,ssa 扫描终止)\n",
|
||||
stdio.printf("[IR-DUMP] cyclic list: block lines (func name=%s, block=%s, ssa scan aborted)\n",
|
||||
func.Name, blk.Name)
|
||||
stdlib.exit(1)
|
||||
if line.Buf is not None:
|
||||
@@ -641,7 +641,7 @@ def RenumberSSA(func: Function*, pool: memhub.MemBuddy*):
|
||||
while blk is not None:
|
||||
blk_steps += 1
|
||||
if blk_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: func blocks(函数名=%s,ssa 重编号终止)\n", func.Name)
|
||||
stdio.printf("[IR-DUMP] cyclic list: func blocks (func name=%s, ssa renumber aborted)\n", func.Name)
|
||||
stdlib.exit(1)
|
||||
if blk.Lines is not None:
|
||||
lines: GSList[Line]* = blk.Lines
|
||||
@@ -650,7 +650,7 @@ def RenumberSSA(func: Function*, pool: memhub.MemBuddy*):
|
||||
while line is not None:
|
||||
line_steps += 1
|
||||
if line_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: block lines(函数名=%s,块=%s,ssa 重编号终止)\n",
|
||||
stdio.printf("[IR-DUMP] cyclic list: block lines (func name=%s, block=%s, ssa renumber aborted)\n",
|
||||
func.Name, blk.Name)
|
||||
stdlib.exit(1)
|
||||
if line.Buf is not None:
|
||||
@@ -676,7 +676,7 @@ def RenumberSSA(func: Function*, pool: memhub.MemBuddy*):
|
||||
while blk is not None:
|
||||
blk_steps += 1
|
||||
if blk_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: func blocks(函数名=%s,ssa 替换终止)\n", func.Name)
|
||||
stdio.printf("[IR-DUMP] cyclic list: func blocks (func name=%s, ssa replace aborted)\n", func.Name)
|
||||
stdlib.exit(1)
|
||||
if blk.Lines is not None:
|
||||
lines: GSList[Line]* = blk.Lines
|
||||
@@ -685,7 +685,7 @@ def RenumberSSA(func: Function*, pool: memhub.MemBuddy*):
|
||||
while line is not None:
|
||||
line_steps += 1
|
||||
if line_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: block lines(函数名=%s,块=%s,ssa 替换终止)\n",
|
||||
stdio.printf("[IR-DUMP] cyclic list: block lines (func name=%s, block=%s, ssa replace aborted)\n",
|
||||
func.Name, blk.Name)
|
||||
stdlib.exit(1)
|
||||
if line.Buf is not None:
|
||||
@@ -1205,7 +1205,7 @@ def _mlir_dup(s: str) -> str:
|
||||
n: sizet = string.strlen(s)
|
||||
b: str = _MLIR_Pool.alloc(n + 1)
|
||||
if b is None:
|
||||
MlirFail("MLIR 渲染: 文本 dup 分配失败")
|
||||
MlirFail("MLIR render: text dup allocation failed")
|
||||
string.strncpy(b, s, n)
|
||||
b[n] = '\0'
|
||||
return b
|
||||
@@ -1215,7 +1215,7 @@ def _MlirTablesInit(pool: memhub.MemBuddy*):
|
||||
"""Initialize the two tables and the parse scratch buffers"""
|
||||
global _MLIR_Pool, _MLIR_Pass, _MLIR_ConstTy, _MLIR_ConstVal, _MLIR_ConstName, _MLIR_ConstCount, _MLIR_AliasFrom, _MLIR_AliasTo, _MLIR_AliasCount, _SC_Op, _SC_Tb, _SC_Ty, _SC_Ty2, _SC_V1, _SC_V2, _SC_V3, _SC_Callee, _SC_Args, _SC_ArgTs, _SC_IdxV, _SC_IdxT, _SC_Mt, _SC_Tmp, _SC_Tmp2, _SC_P1, _SC_P2, _SC_B1, _SC_B2, _SC_Buf
|
||||
if pool is None:
|
||||
MlirFail("MLIR 渲染: 内存池为空")
|
||||
MlirFail("MLIR render: memory pool is null")
|
||||
_MLIR_Pool = pool
|
||||
_MLIR_Pass = 0
|
||||
_MLIR_ConstCount = 0
|
||||
@@ -1227,7 +1227,7 @@ def _MlirTablesInit(pool: memhub.MemBuddy*):
|
||||
_MLIR_AliasTo = pool.alloc(MLIR_ALIAS_CAP * 8)
|
||||
if _MLIR_ConstTy is None or _MLIR_ConstVal is None or _MLIR_ConstName is None \
|
||||
or _MLIR_AliasFrom is None or _MLIR_AliasTo is None:
|
||||
MlirFail("MLIR 渲染: 常量/别名表分配失败")
|
||||
MlirFail("MLIR render: constant/alias table allocation failed")
|
||||
string.memset(_MLIR_ConstTy, 0, MLIR_CONST_CAP * 8)
|
||||
string.memset(_MLIR_ConstVal, 0, MLIR_CONST_CAP * 8)
|
||||
string.memset(_MLIR_ConstName, 0, MLIR_CONST_CAP * 8)
|
||||
@@ -1254,7 +1254,7 @@ def _MlirTablesInit(pool: memhub.MemBuddy*):
|
||||
_SC_B2 = pool.alloc(4096)
|
||||
_SC_Buf = pool.alloc(4096)
|
||||
if _SC_Op is None or _SC_Ty is None or _SC_Mt is None or _SC_Tmp is None:
|
||||
MlirFail("MLIR 渲染: 解析 scratch 分配失败")
|
||||
MlirFail("MLIR render: parse scratch allocation failed")
|
||||
_SC_Op[0] = '\0'
|
||||
_SC_Ty[0] = '\0'
|
||||
_SC_Mt[0] = '\0'
|
||||
@@ -1282,7 +1282,7 @@ def _MlirAliasAdd(from_name: str, to_name: str):
|
||||
if from_name is None or to_name is None:
|
||||
return
|
||||
if _MLIR_AliasCount >= MLIR_ALIAS_CAP:
|
||||
MlirFail("MLIR 渲染: bitcast 别名表溢出")
|
||||
MlirFail("MLIR render: bitcast alias table overflow")
|
||||
sp: str* = _mlir_slotp(_MLIR_AliasFrom, _MLIR_AliasCount)
|
||||
st: str* = _mlir_slotp(_MLIR_AliasTo, _MLIR_AliasCount)
|
||||
sp[0] = _mlir_dup(from_name)
|
||||
@@ -1315,12 +1315,12 @@ def _MlirConstGet(tytext: str, valtext: str) -> str:
|
||||
return sn[0]
|
||||
if _MLIR_Pass == 2:
|
||||
# pass1 already scanned all instruction lines; no new constant should appear here
|
||||
MlirFail("MLIR 渲染: 发射阶段出现未物化常量(扫描遗漏)")
|
||||
MlirFail("MLIR render: unmaterialized constant in emit pass (scan missed it)")
|
||||
if _MLIR_ConstCount >= MLIR_CONST_CAP:
|
||||
MlirFail("MLIR 渲染: 常量表溢出")
|
||||
MlirFail("MLIR render: constant table overflow")
|
||||
nm: str = _MLIR_Pool.alloc(32)
|
||||
if nm is None:
|
||||
MlirFail("MLIR 渲染: 常量名分配失败")
|
||||
MlirFail("MLIR render: constant name allocation failed")
|
||||
viperlib.snprintf(nm, 32, "%%c%d", _MLIR_ConstCount)
|
||||
sp2: str* = _mlir_slotp(_MLIR_ConstTy, _MLIR_ConstCount)
|
||||
sv2: str* = _mlir_slotp(_MLIR_ConstVal, _MLIR_ConstCount)
|
||||
@@ -1344,7 +1344,7 @@ def _MlirCxResName(resname: str, suffix: str) -> str:
|
||||
"""
|
||||
nm: str = _MLIR_Pool.alloc(64)
|
||||
if nm is None:
|
||||
MlirFail("MLIR 渲染: cmpxchg 结果名分配失败")
|
||||
MlirFail("MLIR render: cmpxchg result name allocation failed")
|
||||
nm[0] = '\0'
|
||||
_append_cstr(nm, 4096, "%_")
|
||||
_append_cstr(nm, 4096, resname + 1)
|
||||
@@ -1376,7 +1376,7 @@ def _MlirFloatLiteral(val: str, mt: str) -> str:
|
||||
elif string.strcmp(mt, "f128") == 0:
|
||||
want = 32
|
||||
if want == 0:
|
||||
MlirFail("MLIR 渲染: 十六进制浮点字面量的类型既非 f16/f32/f64/f128")
|
||||
MlirFail("MLIR render: hex float literal type is none of f16/f32/f64/f128")
|
||||
nd: int = 0
|
||||
p: str = val + 2
|
||||
while (p[0] >= '0' and p[0] <= '9') \
|
||||
@@ -1385,7 +1385,7 @@ def _MlirFloatLiteral(val: str, mt: str) -> str:
|
||||
nd += 1
|
||||
p = p + 1
|
||||
if nd != want:
|
||||
MlirFail("MLIR 渲染: 浮点位模式位数与类型不符(f16/f32/f64/f128 依次需 4/8/16/32 位十六进制)")
|
||||
MlirFail("MLIR render: float bit-pattern width mismatches type (f16/f32/f64/f128 need 4/8/16/32 hex digits respectively)")
|
||||
return val
|
||||
# Already decimal text: use as-is
|
||||
return val
|
||||
@@ -1410,7 +1410,7 @@ def _MlirEmitOneConst(out: str, outsz: sizet, mt: str, val: str, nm: str):
|
||||
if mt[0] == 'f':
|
||||
lit = _MlirFloatLiteral(val, mt)
|
||||
elif mt[0] != 'i':
|
||||
MlirFail("MLIR 渲染: 不支持的常量操作数形态")
|
||||
MlirFail("MLIR render: unsupported constant operand form")
|
||||
_append_cstr(out, outsz, " = llvm.mlir.constant(")
|
||||
_append_cstr(out, outsz, lit)
|
||||
# i1's `true`/`false` are MLIR bare boolean keywords, no type suffix allowed:
|
||||
@@ -1621,7 +1621,7 @@ def _MlirFindBlock(func: Function*, name: str) -> BasicBlock*:
|
||||
while blk is not None:
|
||||
steps += 1
|
||||
if steps > IR_DUMP_CHAIN_LIMIT:
|
||||
MlirFail("MLIR 渲染: 块链疑似成环")
|
||||
MlirFail("MLIR render: block chain may be cyclic")
|
||||
if blk.Name is not None and string.strcmp(blk.Name, name) == 0:
|
||||
return blk
|
||||
blk = blk.Next
|
||||
@@ -1647,7 +1647,7 @@ def _MlirOperand(val: str, tyllvm: str, out: str, outsz: sizet) -> str:
|
||||
non-SSA (literal/symbol ref) -> materialized %cN (registered during the scan pass).
|
||||
"""
|
||||
if val is None or val[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 操作数为空")
|
||||
MlirFail("MLIR render: empty operand")
|
||||
if val[0] == '%':
|
||||
r: str = _MlirResolve(val)
|
||||
_append_cstr(out, outsz, r)
|
||||
@@ -1681,7 +1681,7 @@ def _MlirPhiScan(text: str):
|
||||
while p[0] != '\0':
|
||||
g += 1
|
||||
if g > 512:
|
||||
MlirFail("MLIR 渲染: phi 入边过多")
|
||||
MlirFail("MLIR render: too many phi incoming edges")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != '[':
|
||||
break
|
||||
@@ -1742,7 +1742,7 @@ def _MlirPhiFindIncoming(text: str, src: BasicBlock*) -> int:
|
||||
while p[0] != '\0':
|
||||
g += 1
|
||||
if g > 512:
|
||||
MlirFail("MLIR 渲染: phi 入边过多")
|
||||
MlirFail("MLIR render: too many phi incoming edges")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != '[':
|
||||
break
|
||||
@@ -1811,7 +1811,7 @@ def _MlirBlockOperands(out: str, outsz: sizet,
|
||||
if _MlirIsPhiLine(ln.Buf) == 0:
|
||||
break
|
||||
if _MlirPhiFindIncoming(ln.Buf, src) == 0:
|
||||
MlirFail("MLIR 渲染: 跳转目标块带 phi,但找不到与源块匹配的入边")
|
||||
MlirFail("MLIR render: target block has phi but no incoming edge matches the source block")
|
||||
if cnt > 0:
|
||||
_append_cstr(tmp, 8192, ", ")
|
||||
_MlirOperand(_SC_B1, _SC_B2, tmp, 4096)
|
||||
@@ -1823,7 +1823,7 @@ def _MlirBlockOperands(out: str, outsz: sizet,
|
||||
cnt += 1
|
||||
ln = ln.Next
|
||||
if cnt == 0:
|
||||
MlirFail("MLIR 渲染: 目标块带 phi 但未生成块实参")
|
||||
MlirFail("MLIR render: target block has phi but no block arguments were generated")
|
||||
_append_cstr(out, outsz, "(")
|
||||
_append_cstr(out, outsz, tmp)
|
||||
_append_cstr(out, outsz, ")")
|
||||
@@ -1858,7 +1858,7 @@ def _MlirEmitBlockHeader(out: str, outsz: sizet, blk: BasicBlock*):
|
||||
cnt += 1
|
||||
ln = ln.Next
|
||||
if cnt == 0:
|
||||
MlirFail("MLIR 渲染: 块首 phi 解析失败")
|
||||
MlirFail("MLIR render: failed to parse leading phi")
|
||||
_append_cstr(out, outsz, "(")
|
||||
_append_cstr(out, outsz, tmp)
|
||||
_append_cstr(out, outsz, ")")
|
||||
@@ -1876,7 +1876,7 @@ def _MlirEmitBlockLines(out: str, outsz: sizet, blk: BasicBlock*):
|
||||
while ln is not None:
|
||||
steps += 1
|
||||
if steps > IR_DUMP_CHAIN_LIMIT:
|
||||
MlirFail("MLIR 渲染: 块指令链疑似成环")
|
||||
MlirFail("MLIR render: block instruction chain may be cyclic")
|
||||
if ln.Buf is not None:
|
||||
if skipping != 0 and _MlirIsPhiLine(ln.Buf) != 0:
|
||||
ln = ln.Next
|
||||
@@ -1889,7 +1889,7 @@ def _MlirEmitBlockLines(out: str, outsz: sizet, blk: BasicBlock*):
|
||||
def _MlirCheckEntryNoPhi(blk: BasicBlock*):
|
||||
"""entry block must not have phis (no predecessor, cannot become block params)"""
|
||||
if _MlirBlockHasPhi(blk) != 0:
|
||||
MlirFail("MLIR 渲染: entry 块不允许 phi(MLIR entry 块不接受块参数)")
|
||||
MlirFail("MLIR render: entry block must not have phi (MLIR entry block takes no block arguments)")
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -2010,28 +2010,28 @@ def _MlirAlloca(p: str, resname: str, out: str, outsz: sizet):
|
||||
# ", align N" (the intermediate-text form from build_alloca_aligned)
|
||||
p = _mlir_ws(p + 1)
|
||||
if string.strncmp(p, "align", 5) != 0:
|
||||
MlirFail("MLIR 渲染: alloca 只支持 align 属性(未知属性)")
|
||||
MlirFail("MLIR render: alloca only supports the align attribute (unknown attribute)")
|
||||
p = _mlir_ws(p + 5)
|
||||
nd: int = 0
|
||||
while p[0] >= '0' and p[0] <= '9':
|
||||
if nd + 1 >= 512:
|
||||
MlirFail("MLIR 渲染: alloca 对齐值过长(超范围)")
|
||||
MlirFail("MLIR render: alloca alignment value too long (out of range)")
|
||||
aligntxt[nd] = p[0]
|
||||
nd += 1
|
||||
p = p + 1
|
||||
aligntxt[nd] = '\0'
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != '\0':
|
||||
MlirFail("MLIR 渲染: alloca 的 align 之后出现多余记号")
|
||||
MlirFail("MLIR render: extra token after alloca align")
|
||||
if nd == 0:
|
||||
MlirFail("MLIR 渲染: alloca 对齐值必须是常量(常量十进制,非 SSA)")
|
||||
MlirFail("MLIR render: alloca alignment must be a constant (decimal constant, not SSA)")
|
||||
if nd > 10:
|
||||
MlirFail("MLIR 渲染: alloca 对齐值超范围(须为 2 的幂且 <= 2^30)")
|
||||
MlirFail("MLIR render: alloca alignment out of range (must be a power of 2 and <= 2^30)")
|
||||
av: int = string.atoi(aligntxt)
|
||||
if av <= 0 or av > 1073741824:
|
||||
MlirFail("MLIR 渲染: alloca 对齐值超范围(须为 2 的幂且 <= 2^30)")
|
||||
MlirFail("MLIR render: alloca alignment out of range (must be a power of 2 and <= 2^30)")
|
||||
if (av & (av - 1)) != 0:
|
||||
MlirFail("MLIR 渲染: alloca 对齐值必须是 2 的幂")
|
||||
MlirFail("MLIR render: alloca alignment must be a power of 2")
|
||||
mt: str = _SC_Mt
|
||||
mt[0] = '\0'
|
||||
MlirTypeText(mt, 4096, tyb, _MLIR_Pool)
|
||||
@@ -2251,7 +2251,7 @@ def _MlirCall(p: str, resname: str, out: str, outsz: sizet):
|
||||
while p[0] != '\0':
|
||||
g0 += 1
|
||||
if g0 > 256:
|
||||
MlirFail("MLIR 渲染: 变参 call 的函数类型参数过多")
|
||||
MlirFail("MLIR render: too many function type params in variadic call")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == ')':
|
||||
p = p + 1
|
||||
@@ -2278,7 +2278,7 @@ def _MlirCall(p: str, resname: str, out: str, outsz: sizet):
|
||||
p = _mlir_read_value(p, calb, 512)
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != '(':
|
||||
MlirFail("MLIR 渲染: call 缺少实参列表")
|
||||
MlirFail("MLIR render: call missing argument list")
|
||||
p = p + 1
|
||||
args: str = _SC_Args
|
||||
argts: str = _SC_ArgTs
|
||||
@@ -2289,7 +2289,7 @@ def _MlirCall(p: str, resname: str, out: str, outsz: sizet):
|
||||
while p[0] != '\0':
|
||||
g += 1
|
||||
if g > 256:
|
||||
MlirFail("MLIR 渲染: call 实参过多")
|
||||
MlirFail("MLIR render: too many call arguments")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == ')':
|
||||
break
|
||||
@@ -2415,18 +2415,18 @@ def _MlirAsm(p: str, resname: str, rtyb: str, out: str, outsz: sizet):
|
||||
asmb: str = _SC_Tmp
|
||||
p = _mlir_read_value(p, asmb, 4096)
|
||||
if asmb[0] != '"':
|
||||
MlirFail("MLIR 渲染: inline_asm 缺少汇编文本(或含未知关键字)")
|
||||
MlirFail("MLIR render: inline_asm missing asm text (or contains an unknown keyword)")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != ',':
|
||||
MlirFail("MLIR 渲染: inline_asm 缺少约束串(形态须为 \"asm\", \"constraints\")")
|
||||
MlirFail("MLIR render: inline_asm missing constraint string (must be \"asm\", \"constraints\")")
|
||||
p = _mlir_ws(p + 1)
|
||||
conb: str = _SC_Args
|
||||
p = _mlir_read_value(p, conb, 2048)
|
||||
if conb[0] != '"':
|
||||
MlirFail("MLIR 渲染: inline_asm 约束串必须是字符串字面量")
|
||||
MlirFail("MLIR render: inline_asm constraint string must be a string literal")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != '(':
|
||||
MlirFail("MLIR 渲染: inline_asm 缺少实参列表 '(...)'")
|
||||
MlirFail("MLIR render: inline_asm missing argument list '(...)'")
|
||||
p = p + 1
|
||||
ops: str = _SC_ArgTs
|
||||
ops[0] = '\0'
|
||||
@@ -2437,7 +2437,7 @@ def _MlirAsm(p: str, resname: str, rtyb: str, out: str, outsz: sizet):
|
||||
while p[0] != '\0':
|
||||
g += 1
|
||||
if g > 256:
|
||||
MlirFail("MLIR 渲染: inline_asm 实参过多")
|
||||
MlirFail("MLIR render: too many inline_asm arguments")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == ')':
|
||||
break
|
||||
@@ -2462,7 +2462,7 @@ def _MlirAsm(p: str, resname: str, rtyb: str, out: str, outsz: sizet):
|
||||
p = p + 1
|
||||
p = _mlir_ws(p)
|
||||
if p[0] != '\0':
|
||||
MlirFail("MLIR 渲染: inline_asm 实参列表之后出现多余记号")
|
||||
MlirFail("MLIR render: extra token after inline_asm argument list")
|
||||
rmt: str = _SC_Buf
|
||||
rmt[0] = '\0'
|
||||
MlirTypeText(rmt, 1024, rtyb, _MLIR_Pool)
|
||||
@@ -2470,7 +2470,7 @@ def _MlirAsm(p: str, resname: str, rtyb: str, out: str, outsz: sizet):
|
||||
_MlirEmitRes(out, outsz, None)
|
||||
else:
|
||||
if resname is None:
|
||||
MlirFail("MLIR 渲染: inline_asm 有返回值但缺少结果名(%N = call …)")
|
||||
MlirFail("MLIR render: inline_asm has a return value but no result name (%N = call ...)")
|
||||
_MlirEmitRes(out, outsz, resname)
|
||||
_append_cstr(out, outsz, "llvm.inline_asm")
|
||||
if side != 0:
|
||||
@@ -2540,7 +2540,7 @@ def _MlirBitcast(p: str, resname: str, out: str, outsz: sizet):
|
||||
# With opaque pointers, a ptr->ptr bitcast is meaningless -> no-op:
|
||||
# register the result name as an alias of the source operand (later refs auto-rewritten), emit nothing
|
||||
if resname is None:
|
||||
MlirFail("MLIR 渲染: no-op bitcast 缺少结果名")
|
||||
MlirFail("MLIR render: no-op bitcast missing result name")
|
||||
opnd: str = _MlirOperand(vb, ftyb, None, 0)
|
||||
_MlirAliasAdd(resname, opnd)
|
||||
return
|
||||
@@ -2627,7 +2627,7 @@ def _MlirGep(p: str, resname: str, out: str, outsz: sizet):
|
||||
while p[0] == ',':
|
||||
g += 1
|
||||
if g > 32:
|
||||
MlirFail("MLIR 渲染: GEP 索引过多")
|
||||
MlirFail("MLIR render: too many GEP indices")
|
||||
p = _mlir_ws(p + 1)
|
||||
ityb: str = _SC_Ty
|
||||
p = _mlir_read_type(p, ityb, 512)
|
||||
@@ -2656,7 +2656,7 @@ def _MlirGep(p: str, resname: str, out: str, outsz: sizet):
|
||||
nidx += 1
|
||||
p = _mlir_ws(p)
|
||||
if nidx == 0:
|
||||
MlirFail("MLIR 渲染: GEP 缺少索引")
|
||||
MlirFail("MLIR render: GEP missing index")
|
||||
bmt: str = _SC_Tmp2
|
||||
bmt[0] = '\0'
|
||||
MlirTypeText(bmt, 4096, baseb, _MLIR_Pool)
|
||||
@@ -2727,7 +2727,7 @@ def _MlirSwitch(p: str, out: str, outsz: sizet):
|
||||
while p[0] != '\0':
|
||||
g += 1
|
||||
if g > 1024:
|
||||
MlirFail("MLIR 渲染: switch 分支过多")
|
||||
MlirFail("MLIR render: too many switch branches")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == ']' or p[0] == '\0':
|
||||
break
|
||||
@@ -2744,7 +2744,7 @@ def _MlirSwitch(p: str, out: str, outsz: sizet):
|
||||
cb: str = _SC_Ty2
|
||||
p = _mlir_read_value(p, cb, 512)
|
||||
if cvb[0] == '%':
|
||||
MlirFail("MLIR 渲染: switch case 值必须是常量(SSA 值不支持)")
|
||||
MlirFail("MLIR render: switch case value must be a constant (SSA value not supported)")
|
||||
cbr: str = _MlirBlkRef(cb)
|
||||
if ncase > 0:
|
||||
_append_cstr(cases, 4096, ", ")
|
||||
@@ -2861,7 +2861,7 @@ def _MlirCmpXchg(p: str, resname: str, resname2: str,
|
||||
fail: str = _SC_P2
|
||||
_mlir_read_value(p, fail, 512)
|
||||
if resname is None:
|
||||
MlirFail("MLIR 渲染: cmpxchg 缺少结果名")
|
||||
MlirFail("MLIR render: cmpxchg missing result name")
|
||||
# The two extractvalue result names derive deterministically from the struct name (identical across both passes)
|
||||
onm: str = _MlirCxResName(resname, "_v")
|
||||
snm: str = _MlirCxResName(resname, "_ok")
|
||||
@@ -2933,7 +2933,7 @@ def _MlirVaArg(p: str, resname: str, out: str, outsz: sizet):
|
||||
atyb: str = _SC_Ty2
|
||||
_mlir_read_type(p, atyb, 512)
|
||||
if resname is None:
|
||||
MlirFail("MLIR 渲染: va_arg 缺少结果名")
|
||||
MlirFail("MLIR render: va_arg missing result name")
|
||||
# Operand/result types (_MlirOperand only uses _SC_Mt, so take separate buffers here)
|
||||
omt: str = _SC_Tmp2
|
||||
omt[0] = '\0'
|
||||
@@ -2985,22 +2985,22 @@ def _MlirExtractValue(p: str, resname: str, out: str, outsz: sizet):
|
||||
break
|
||||
g += 1
|
||||
if g > 32:
|
||||
MlirFail("MLIR 渲染: extractvalue 索引过多")
|
||||
MlirFail("MLIR render: too many extractvalue indices")
|
||||
p = _mlir_ws(p + 1)
|
||||
ib: str = _SC_IdxT
|
||||
p = _mlir_read_value(p, ib, 512)
|
||||
if ib[0] == '\0':
|
||||
MlirFail("MLIR 渲染: extractvalue 缺少索引")
|
||||
MlirFail("MLIR render: extractvalue missing index")
|
||||
if ib[0] == '%':
|
||||
MlirFail("MLIR 渲染: extractvalue 索引必须是常量(SSA 索引不支持)")
|
||||
MlirFail("MLIR render: extractvalue index must be a constant (SSA index not supported)")
|
||||
if nidx > 0:
|
||||
_append_cstr(idxs, 1024, ", ")
|
||||
_append_cstr(idxs, 1024, ib)
|
||||
nidx += 1
|
||||
if nidx == 0:
|
||||
MlirFail("MLIR 渲染: extractvalue 缺少索引")
|
||||
MlirFail("MLIR render: extractvalue missing index")
|
||||
if p[0] != '\0':
|
||||
MlirFail("MLIR 渲染: extractvalue 索引之后出现多余记号")
|
||||
MlirFail("MLIR render: extra token after extractvalue index")
|
||||
# Aggregate type text goes into a separate buffer first (_MlirOperand only uses _SC_Mt)
|
||||
amt: str = _SC_Tmp2
|
||||
amt[0] = '\0'
|
||||
@@ -3048,15 +3048,15 @@ def _MlirRenderLine(text: str, out: str, outsz: sizet):
|
||||
q3 = _mlir_read_value(q3, tb2, 512)
|
||||
q4: str = _mlir_ws(q3)
|
||||
if q4[0] != '=':
|
||||
MlirFail("MLIR 渲染: 双结果前缀(%a, %b =)缺少 '='")
|
||||
MlirFail("MLIR render: double-result prefix (%a, %b =) missing '='")
|
||||
resname2 = _mlir_dup(tb2)
|
||||
p = _mlir_ws(q4 + 1)
|
||||
ob: str = _SC_Op
|
||||
p = _mlir_read_value(p, ob, 64)
|
||||
if ob[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 空指令")
|
||||
MlirFail("MLIR render: empty instruction")
|
||||
if resname2 is not None and string.strcmp(ob, "cmpxchg") != 0:
|
||||
MlirFail("MLIR 渲染: 双结果前缀(%a, %b =)只支持 cmpxchg")
|
||||
MlirFail("MLIR render: double-result prefix (%a, %b =) only supports cmpxchg")
|
||||
if _mlir_in_set(ob, "|add|sub|mul|sdiv|udiv|srem|urem|and|or|xor|shl|lshr|ashr|") != 0:
|
||||
_MlirBinop(p, resname, ob, out, outsz)
|
||||
return
|
||||
@@ -3099,7 +3099,7 @@ def _MlirRenderLine(text: str, out: str, outsz: sizet):
|
||||
if string.strcmp(ob, "phi") == 0:
|
||||
if out is not None:
|
||||
# Leading phis are skipped in _MlirEmitBlockLines; reaching here means phi is not at block head
|
||||
MlirFail("MLIR 渲染: phi 不在块首(v1 只支持块首连续 phi → 块参数)")
|
||||
MlirFail("MLIR render: phi is not at block head (v1 only supports leading consecutive phis -> block arguments)")
|
||||
_MlirPhiScan(text)
|
||||
return
|
||||
if string.strcmp(ob, "getelementptr") == 0:
|
||||
@@ -3131,7 +3131,7 @@ def _MlirRenderLine(text: str, out: str, outsz: sizet):
|
||||
return
|
||||
# Note: inline asm's opcode in intermediate text is "call" (call <ret> asm ...); _MlirCall
|
||||
# recognizes it and forwards to _MlirAsm (llvm.inline_asm).
|
||||
MlirFail("MLIR 渲染: 未知指令 opcode")
|
||||
MlirFail("MLIR render: unknown instruction opcode")
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -3158,7 +3158,7 @@ def _MlirFuncSig(buf: str, size: sizet,
|
||||
while cur is not None:
|
||||
cur_steps += 1
|
||||
if cur_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
MlirFail("MLIR 渲染: 参数链疑似成环")
|
||||
MlirFail("MLIR render: parameter chain may be cyclic")
|
||||
if first == 0:
|
||||
_append_cstr(buf, size, ", ")
|
||||
if cur.Name is not None:
|
||||
@@ -3256,7 +3256,7 @@ def FunctionPrint(buf: str, size: sizet,
|
||||
while blk is not None:
|
||||
blk_steps += 1
|
||||
if blk_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
MlirFail("MLIR 渲染: 函数块链疑似成环")
|
||||
MlirFail("MLIR render: function block chain may be cyclic")
|
||||
_MLIR_SrcBlk = blk
|
||||
if blk.Lines is not None:
|
||||
lines: GSList[Line]* = blk.Lines
|
||||
@@ -3265,7 +3265,7 @@ def FunctionPrint(buf: str, size: sizet,
|
||||
while ln is not None:
|
||||
ln_steps += 1
|
||||
if ln_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
MlirFail("MLIR 渲染: 块指令链疑似成环")
|
||||
MlirFail("MLIR render: block instruction chain may be cyclic")
|
||||
if ln.Buf is not None:
|
||||
_MlirRenderLine(ln.Buf, None, 0)
|
||||
ln = ln.Next
|
||||
@@ -3281,7 +3281,7 @@ def FunctionPrint(buf: str, size: sizet,
|
||||
while blk is not None:
|
||||
blk_steps += 1
|
||||
if blk_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
MlirFail("MLIR 渲染: 函数块链疑似成环")
|
||||
MlirFail("MLIR render: function block chain may be cyclic")
|
||||
_MLIR_SrcBlk = blk
|
||||
if first != 0:
|
||||
# entry block has no label; constant-materialization ops go at the entry block head
|
||||
@@ -3353,7 +3353,7 @@ def _MlirOutTruncFail():
|
||||
global _MlirOutTrunc
|
||||
if _MlirOutTrunc != 0:
|
||||
_MlirOutTrunc = 0
|
||||
MlirFail("MLIR 渲染: 输出文本超出缓冲被截断(需增大 dump_ir/FunctionPrint 的缓冲)")
|
||||
MlirFail("MLIR render: output text truncated by buffer overflow (increase the dump_ir/FunctionPrint buffer)")
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -3459,9 +3459,9 @@ def DebugNoteFunc(sym: str, file: str, line: int) -> int:
|
||||
if _g_dbg_on == 0:
|
||||
return 0
|
||||
if _g_dbg_depth >= DBGC_STACK_MAX:
|
||||
MlirFail("MLIR 调试记录: 函数嵌套深度超上限(DBGC_STACK_MAX)")
|
||||
MlirFail("MLIR debug record: function nesting depth exceeds limit (DBGC_STACK_MAX)")
|
||||
if _DbgEnsureStack() != 0:
|
||||
MlirFail("MLIR 调试记录: 上下文栈分配失败")
|
||||
MlirFail("MLIR debug record: context stack allocation failed")
|
||||
fs: str* = (str*)(uint64(_g_dbg_stk_func) + sizet(_g_dbg_depth) * 8)
|
||||
fs[0] = _g_dbg_func
|
||||
ff: str* = (str*)(uint64(_g_dbg_stk_file) + sizet(_g_dbg_depth) * 8)
|
||||
@@ -3479,7 +3479,7 @@ def DebugNoteFunc(sym: str, file: str, line: int) -> int:
|
||||
return 0
|
||||
need: sizet = string.strlen(sym) + string.strlen(file) + 64
|
||||
if _DbgReserve(need) != 0:
|
||||
MlirFail("MLIR 调试记录: F 记录缓冲分配失败")
|
||||
MlirFail("MLIR debug record: F record buffer allocation failed")
|
||||
viperlib.snprintf(_g_dbg_buf + _g_dbg_len, _g_dbg_cap - _g_dbg_len,
|
||||
"F\t%s\t%d\t%s\n", sym, line, file)
|
||||
_g_dbg_len = _g_dbg_len + string.strlen(_g_dbg_buf + _g_dbg_len)
|
||||
@@ -3546,7 +3546,7 @@ def _DebugNoteCall(callee: str) -> int:
|
||||
need: sizet = string.strlen(_g_dbg_func) + string.strlen(callee) \
|
||||
+ string.strlen(_g_dbg_file) + 64
|
||||
if _DbgReserve(need) != 0:
|
||||
MlirFail("MLIR 调试记录: C 记录缓冲分配失败")
|
||||
MlirFail("MLIR debug record: C record buffer allocation failed")
|
||||
viperlib.snprintf(_g_dbg_buf + _g_dbg_len, _g_dbg_cap - _g_dbg_len,
|
||||
"C\t%s\t%s\t%d\t%s\n",
|
||||
_g_dbg_func, callee, _g_dbg_line, _g_dbg_file)
|
||||
|
||||
+41
-41
@@ -160,7 +160,7 @@ class LLVMModule:
|
||||
while cur is not None:
|
||||
cur_steps += 1
|
||||
if cur_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module di named(DINamedCount=%zu,dump 终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: module di named (DINamedCount=%zu, dump aborted)\n",
|
||||
self.DINamedCount)
|
||||
stdlib.exit(1)
|
||||
if cur.Name is not None and string.strcmp(cur.Name, name) == 0:
|
||||
@@ -223,7 +223,7 @@ class LLVMModule:
|
||||
# list is corrupt → report and terminate immediately.
|
||||
cnt_dedup += 1
|
||||
if cnt_dedup > 100000:
|
||||
stdio.printf("[ANT-LOOP] NamedTypeHead 链表疑似成环, name=%s, 遍历节点=%d, 强制终止\n",
|
||||
stdio.printf("[ANT-LOOP] NamedTypeHead list suspected cycle, name=%s, visited nodes=%d, forced abort\n",
|
||||
name if name is not None else "(null)", cnt_dedup)
|
||||
stdlib.exit(1)
|
||||
if cur.Ty is not None:
|
||||
@@ -274,7 +274,7 @@ class LLVMModule:
|
||||
# Step guard: as above, prevent infinite traversal of a cyclic NamedTypeHead
|
||||
cnt_tdm += 1
|
||||
if cnt_tdm > 100000:
|
||||
stdio.printf("[TDM-LOOP] NamedTypeHead 链表疑似成环, name=%s, 强制终止\n",
|
||||
stdio.printf("[TDM-LOOP] NamedTypeHead list suspected cycle, name=%s, forced abort\n",
|
||||
name if name is not None else "(null)")
|
||||
stdlib.exit(1)
|
||||
if cur.Ty is not None:
|
||||
@@ -324,13 +324,13 @@ class LLVMModule:
|
||||
|
||||
# Mode comment (MLIR has no stub/text split)
|
||||
if mode == OUTPUT_STUB:
|
||||
_append_cstr(buf, size, " // MLIR-STUB: 仅全局声明与函数声明\n")
|
||||
_append_cstr(buf, size, " // MLIR-STUB: global and function declarations only\n")
|
||||
elif mode == OUTPUT_TEXT:
|
||||
_append_cstr(buf, size, " // MLIR-TEXT: 仅带体函数与含初值全局\n")
|
||||
_append_cstr(buf, size, " // MLIR-TEXT: body-bearing functions and initialized globals only\n")
|
||||
# target triple / datalayout: not carried by an MLIR module; supplied at mlir-translate/llc stage
|
||||
if self.TargetTriple is not None or self.DataLayout is not None:
|
||||
_append_cstr(buf, size,
|
||||
" // target triple / datalayout 由 mlir-translate / llc 阶段提供\n")
|
||||
" // target triple / datalayout are supplied by the mlir-translate / llc stage\n")
|
||||
|
||||
# Line-indent scratch buffer (module members indent 2 spaces). Its cap is bounded by the
|
||||
# module pool's buddy limit: a ~2 MiB sub-pool (max_order=15) allows max 1 MiB per block,
|
||||
@@ -339,7 +339,7 @@ class LLVMModule:
|
||||
tmp_cap: sizet = 1048560
|
||||
tmp: str = pool.alloc(tmp_cap)
|
||||
if tmp is None:
|
||||
MlirFail("MLIR 渲染: 模块缩进辅助缓冲分配失败(1048560 ≈ 1 MiB − 16 字节块头)")
|
||||
MlirFail("MLIR render: module indent scratch buffer allocation failed (1048560 ~= 1 MiB - 16-byte block header)")
|
||||
|
||||
# Globals (MLIR has no standalone type-definition line: named structs are inlined at the
|
||||
# use site, so NamedTypeHead definitions are not emitted here, only registered for lookup).
|
||||
@@ -348,7 +348,7 @@ class LLVMModule:
|
||||
while gv is not None:
|
||||
gv_steps += 1
|
||||
if gv_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module globals(GlobalCount=%zu,dump 终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: module globals (GlobalCount=%zu, dump aborted)\n",
|
||||
self.GlobalCount)
|
||||
stdlib.exit(1)
|
||||
if mode == OUTPUT_TEXT and gv.Initializer is None:
|
||||
@@ -370,7 +370,7 @@ class LLVMModule:
|
||||
while func is not None:
|
||||
func_steps += 1
|
||||
if func_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module funcs print(FuncCount=%zu,dump 终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: module funcs print (FuncCount=%zu, dump aborted)\n",
|
||||
self.FuncCount)
|
||||
stdlib.exit(1)
|
||||
emit: int = 0
|
||||
@@ -412,7 +412,7 @@ def _MlirPublishNamedTypes(mod: LLVMModule*, pool: memhub.MemBuddy*):
|
||||
while nt is not None:
|
||||
nt_steps += 1
|
||||
if nt_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module named types count(NamedTypeCount=%zu,计数终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: module named types count (NamedTypeCount=%zu, count aborted)\n",
|
||||
mod.NamedTypeCount)
|
||||
stdlib.exit(1)
|
||||
cnt += 1
|
||||
@@ -423,7 +423,7 @@ def _MlirPublishNamedTypes(mod: LLVMModule*, pool: memhub.MemBuddy*):
|
||||
while nt is not None:
|
||||
nt_steps += 1
|
||||
if nt_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: module named types publish(NamedTypeCount=%zu,发布终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: module named types publish (NamedTypeCount=%zu, publish aborted)\n",
|
||||
mod.NamedTypeCount)
|
||||
stdlib.exit(1)
|
||||
if nt.Ty is not None:
|
||||
@@ -631,7 +631,7 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy*,
|
||||
while fld is not None:
|
||||
fld_steps += 1
|
||||
if fld_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: struct fields(sname=%s,dump 终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: struct fields (sname=%s, dump aborted)\n",
|
||||
sname)
|
||||
stdlib.exit(1)
|
||||
if fld.Ty is not None:
|
||||
@@ -647,7 +647,7 @@ def _scan_type_for_cross_module_refs(pool: memhub.MemBuddy*,
|
||||
while fld2 is not None:
|
||||
fld2_steps += 1
|
||||
if fld2_steps > IR_DUMP_CHAIN_LIMIT:
|
||||
stdio.printf("[IR-DUMP] 链表成环: struct fields2(sname=%s,dump 终止)\n",
|
||||
stdio.printf("[IR-DUMP] list cycle: struct fields2 (sname=%s, dump aborted)\n",
|
||||
sname2)
|
||||
stdlib.exit(1)
|
||||
if fld2.Ty is not None:
|
||||
@@ -711,7 +711,7 @@ def LLVMModulePrint(buf: str, size: sizet,
|
||||
mod.PrintModule(buf, size, pool, mode)
|
||||
if _MlirModOutTrunc != 0:
|
||||
_MlirModOutTrunc = 0
|
||||
MlirFail("MLIR 渲染: 模块文本超出输出缓冲被截断(需增大 dump_ir 缓冲)")
|
||||
MlirFail("MLIR render: module text exceeds output buffer and was truncated (increase the dump_ir buffer)")
|
||||
|
||||
|
||||
# Global variable rendering (MLIR); linkage/constant/unnamed_addr/section map to keywords/attributes.
|
||||
@@ -845,7 +845,7 @@ def _MlirGlobalInit(buf: str, size: sizet,
|
||||
# Residual form not covered by the attribute path and not routed to region: fail loud, never
|
||||
# emit wrong MLIR (structs/vtables, symbol-referencing aggregates and pointer initializers are
|
||||
# already handled by _MlirGlobalInitRegion on the region path).
|
||||
MlirFail("MLIR 渲染: 全局初值形态 v1 不支持(属性路径与 initializer region 均未覆盖)")
|
||||
MlirFail("MLIR render: global initializer form unsupported in v1 (neither the attribute path nor the initializer region covers it)")
|
||||
|
||||
|
||||
def _MlirCStringToMlir(buf: str, size: sizet, src: str, pool: memhub.MemBuddy*):
|
||||
@@ -857,7 +857,7 @@ def _MlirCStringToMlir(buf: str, size: sizet, src: str, pool: memhub.MemBuddy*):
|
||||
"""
|
||||
p: str = src + 1 # Skip 'c', point at '"'
|
||||
if p[0] != '"':
|
||||
MlirFail("MLIR 渲染: 全局 c 字符串初值形态非法")
|
||||
MlirFail("MLIR render: illegal global c-string initializer form")
|
||||
_append_cstr(buf, size, p)
|
||||
|
||||
|
||||
@@ -865,7 +865,7 @@ def _MlirArrayDenseAt(buf: str, size: sizet, src: str,
|
||||
pool: memhub.MemBuddy*) -> str:
|
||||
"""LLVM array literal → MLIR dense content (nested recursive); returns the new cursor."""
|
||||
if src is None or src[0] != '[':
|
||||
MlirFail("MLIR 渲染: 全局数组初值形态 v1 不支持")
|
||||
MlirFail("MLIR render: global array initializer form unsupported in v1")
|
||||
p: str = src + 1
|
||||
_append_cstr(buf, size, "[")
|
||||
n: int = 0
|
||||
@@ -873,7 +873,7 @@ def _MlirArrayDenseAt(buf: str, size: sizet, src: str,
|
||||
while p[0] != '\0':
|
||||
g += 1
|
||||
if g > 4096:
|
||||
MlirFail("MLIR 渲染: 全局数组元素过多")
|
||||
MlirFail("MLIR render: too many global array elements")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == ']':
|
||||
p = p + 1
|
||||
@@ -887,12 +887,12 @@ def _MlirArrayDenseAt(buf: str, size: sizet, src: str,
|
||||
else:
|
||||
tb: str = pool.alloc(512)
|
||||
if tb is None:
|
||||
MlirFail("MLIR 渲染: 数组元素类型缓冲分配失败")
|
||||
MlirFail("MLIR render: array element type buffer allocation failed")
|
||||
p = _mlir_read_type(p, tb, 512)
|
||||
p = _mlir_ws(p)
|
||||
vb: str = pool.alloc(512)
|
||||
if vb is None:
|
||||
MlirFail("MLIR 渲染: 数组元素值缓冲分配失败")
|
||||
MlirFail("MLIR render: array element value buffer allocation failed")
|
||||
p = _mlir_read_value(p, vb, 512)
|
||||
_append_cstr(buf, size, vb)
|
||||
# Elements must carry a type annotation: MLIR array attributes default to i64, so
|
||||
@@ -901,7 +901,7 @@ def _MlirArrayDenseAt(buf: str, size: sizet, src: str,
|
||||
_append_cstr(buf, size, " : ")
|
||||
mtb: str = pool.alloc(4096)
|
||||
if mtb is None:
|
||||
MlirFail("MLIR 渲染: 数组元素 MLIR 类型缓冲分配失败")
|
||||
MlirFail("MLIR render: array element MLIR type buffer allocation failed")
|
||||
mtb[0] = '\0'
|
||||
MlirTypeText(mtb, 4096, tb, pool)
|
||||
_append_cstr(buf, size, mtb)
|
||||
@@ -979,7 +979,7 @@ def _MlirGvEnsureScratch(pool: memhub.MemBuddy*) -> int:
|
||||
if lb is None or ib is None or tb is None or la is None or pr is None \
|
||||
or r1 is None or r2 is None or nm is None or vl is None \
|
||||
or tyb is None or nb is None or ps is None:
|
||||
MlirFail("MLIR 渲染: 全局 region 缓冲分配失败")
|
||||
MlirFail("MLIR render: global region buffer allocation failed")
|
||||
lb[0] = '\0'; ib[0] = '\0'; tb[0] = '\0'; la[0] = '\0'; pr[0] = '\0'
|
||||
r1[0] = '\0'; r2[0] = '\0'; nm[0] = '\0'; vl[0] = '\0'
|
||||
tyb[0] = '\0'; nb[0] = '\0'; ps[0] = '\0'
|
||||
@@ -1123,12 +1123,12 @@ def _MlirGvWalk(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
insertvalue name; empty aggregate = %undef). path looks like "" / "0" / "0, 1".
|
||||
"""
|
||||
if depth > 64:
|
||||
MlirFail("MLIR 渲染: 全局初值嵌套过深(> 64 层)")
|
||||
MlirFail("MLIR render: global initializer nested too deeply (> 64 levels)")
|
||||
if ty is None:
|
||||
MlirFail("MLIR 渲染: 全局初值类型树缺失(无法确定元素 MLIR 类型)")
|
||||
MlirFail("MLIR render: global initializer type tree missing (cannot determine the element MLIR type)")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 全局初值文本意外结束")
|
||||
MlirFail("MLIR render: global initializer text ended unexpectedly")
|
||||
# Explicit array type prefix (e.g. "[3 x i8] [i8 1, i8 2]") is read off first
|
||||
if p[0] == '[' and _MlirGvIsArrayType(p) != 0:
|
||||
tb: str = _MlirGvSbRead1
|
||||
@@ -1221,7 +1221,7 @@ def _MlirGvPathChild(path: str, idx: int, depth: int) -> str:
|
||||
level writes slot depth, the child writes depth+1, so nothing overlaps; avoids per-node allocs.
|
||||
"""
|
||||
if depth < 0 or depth >= GV_PATH_MAX:
|
||||
MlirFail("MLIR 渲染: 下标路径深度越界")
|
||||
MlirFail("MLIR render: index path depth out of range")
|
||||
nb: str = _MlirGvPathStack + depth * GV_PATH_SLOT
|
||||
if path[0] == '\0':
|
||||
viperlib.snprintf(nb, GV_PATH_SLOT, "%d", idx)
|
||||
@@ -1237,7 +1237,7 @@ def _MlirGvWalkStruct(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
case LLVMType.Struct(sf, sfc, sn):
|
||||
fields = sf
|
||||
case _:
|
||||
MlirFail("MLIR 渲染: 初值为结构体,但全局类型不是结构体")
|
||||
MlirFail("MLIR render: initializer is a struct but the global type is not a struct")
|
||||
cur: ParamNode* = fields
|
||||
p = p + 1
|
||||
idx: int = 0
|
||||
@@ -1246,10 +1246,10 @@ def _MlirGvWalkStruct(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
while done == 0:
|
||||
guard += 1
|
||||
if guard > 4096:
|
||||
MlirFail("MLIR 渲染: 结构体初值元素过多")
|
||||
MlirFail("MLIR render: too many struct initializer elements")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 结构体初值缺少 '}'")
|
||||
MlirFail("MLIR render: struct initializer missing '}'")
|
||||
if p[0] == '}':
|
||||
p = p + 1
|
||||
done = 1
|
||||
@@ -1275,7 +1275,7 @@ def _MlirGvWalkArray(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
case LLVMType.Array(ae, ac):
|
||||
elem_ty = ae
|
||||
case _:
|
||||
MlirFail("MLIR 渲染: 初值为数组,但全局类型不是数组")
|
||||
MlirFail("MLIR render: initializer is an array but the global type is not an array")
|
||||
p = p + 1
|
||||
idx: int = 0
|
||||
done: int = 0
|
||||
@@ -1283,10 +1283,10 @@ def _MlirGvWalkArray(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
while done == 0:
|
||||
guard += 1
|
||||
if guard > 65536:
|
||||
MlirFail("MLIR 渲染: 数组初值元素过多")
|
||||
MlirFail("MLIR render: too many array initializer elements")
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 数组初值缺少 ']'")
|
||||
MlirFail("MLIR render: array initializer missing ']'")
|
||||
if p[0] == ']':
|
||||
p = p + 1
|
||||
done = 1
|
||||
@@ -1340,7 +1340,7 @@ def _MlirGvWalkLeaf(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
p = _mlir_read_type(p, tb, 512)
|
||||
p = _mlir_ws(p)
|
||||
if p[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 叶子初值只有类型、缺少值")
|
||||
MlirFail("MLIR render: leaf initializer has only a type and is missing a value")
|
||||
if p[0] == '@':
|
||||
# Bare symbol reference (strip LLVM quotes → re-add MLIR-style via _MlirSymRefAppend)
|
||||
nb: str = _MlirGvSbName
|
||||
@@ -1369,9 +1369,9 @@ def _MlirGvWalkLeaf(p: str, ty: LLVMType*, path: str, depth: int) -> str:
|
||||
emb: str = _MlirGvPool.alloc(string.strlen(p) + 128)
|
||||
if emb is not None:
|
||||
viperlib.snprintf(emb, string.strlen(p) + 128,
|
||||
"MLIR 渲染: 全局初值叶子形态 v1 不支持:'%s'", p)
|
||||
"MLIR render: global initializer leaf form unsupported in v1: '%s'", p)
|
||||
MlirFail(emb)
|
||||
MlirFail("MLIR 渲染: 全局初值叶子形态 v1 不支持")
|
||||
MlirFail("MLIR render: global initializer leaf form unsupported in v1")
|
||||
if depth > 0:
|
||||
_MlirGvInsertLeaf(path)
|
||||
return p
|
||||
@@ -1384,14 +1384,14 @@ def _MlirGvScanConstExprSym(p: str, out: str, outsz: sizet) -> str:
|
||||
while q[0] != '\0' and q[0] != '(':
|
||||
q = q + 1
|
||||
if q[0] != '(':
|
||||
MlirFail("MLIR 渲染: 常量表达式缺少 '('(bitcast/getelementptr)")
|
||||
MlirFail("MLIR render: constant expression missing '(' (bitcast/getelementptr)")
|
||||
dep: int = 0
|
||||
at: str = None
|
||||
guard: int = 0
|
||||
while q[0] != '\0':
|
||||
guard += 1
|
||||
if guard > 4096:
|
||||
MlirFail("MLIR 渲染: 常量表达式过长")
|
||||
MlirFail("MLIR render: constant expression too long")
|
||||
ch: int = q[0]
|
||||
if ch == '(':
|
||||
dep += 1
|
||||
@@ -1404,7 +1404,7 @@ def _MlirGvScanConstExprSym(p: str, out: str, outsz: sizet) -> str:
|
||||
at = q
|
||||
q = q + 1
|
||||
if at is None:
|
||||
MlirFail("MLIR 渲染: 常量表达式中未找到符号引用 '@'")
|
||||
MlirFail("MLIR render: symbol reference '@' not found in constant expression")
|
||||
_MlirGvReadSymName(at, out, outsz)
|
||||
return q
|
||||
|
||||
@@ -1412,7 +1412,7 @@ def _MlirGvScanConstExprSym(p: str, out: str, outsz: sizet) -> str:
|
||||
def _MlirGvReadSymName(at: str, out: str, outsz: sizet) -> str:
|
||||
"""Read a symbol name at '@', strip LLVM-style quotes ("…"); returns the cursor after the name."""
|
||||
if at is None or at[0] != '@':
|
||||
MlirFail("MLIR 渲染: 期望符号引用('@')")
|
||||
MlirFail("MLIR render: expected a symbol reference ('@')")
|
||||
q: str = at + 1
|
||||
n: sizet = 0
|
||||
if q[0] == '"':
|
||||
@@ -1432,7 +1432,7 @@ def _MlirGvReadSymName(at: str, out: str, outsz: sizet) -> str:
|
||||
q = q + 1
|
||||
out[n] = '\0'
|
||||
if n == 0:
|
||||
MlirFail("MLIR 渲染: 空符号名")
|
||||
MlirFail("MLIR render: empty symbol name")
|
||||
return q
|
||||
|
||||
|
||||
@@ -1485,7 +1485,7 @@ def _MlirGvEmitConst(val: str, ty: LLVMType*):
|
||||
mt[0] = '\0'
|
||||
TypePrint(mt, 4096, ty, _MlirGvPool)
|
||||
if mt[0] != 'i' and mt[0] != 'f':
|
||||
MlirFail("MLIR 渲染: 全局初值标量元素类型既非整数也非浮点")
|
||||
MlirFail("MLIR render: global initializer scalar element type is neither integer nor float")
|
||||
ln: str = _MlirGvNextLeafName()
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, " ")
|
||||
_append_cstr(_MlirGvLeafBuf, GV_REGION_BUF_SIZE, ln)
|
||||
|
||||
+28
-28
@@ -68,7 +68,7 @@ def _TypeSizeGuard() -> sizet:
|
||||
sz: sizet = LLVMType.__sizeof__()
|
||||
if sz == 0:
|
||||
stdio.printf("FATAL: mlirlite.LLVMType.__sizeof__() == 0"
|
||||
"(布局未注册或 opaque),拒绝 alloc(0)\n")
|
||||
" (layout unregistered or opaque), refusing alloc(0)\n")
|
||||
stdlib.exit(1)
|
||||
return sz
|
||||
|
||||
@@ -406,7 +406,7 @@ def MlirNamedTypesBegin(pool: memhub.MemBuddy*, capacity: sizet):
|
||||
return
|
||||
_MlirNamedTys = pool.alloc(capacity * 16)
|
||||
if _MlirNamedTys is None:
|
||||
MlirFail("MLIR 渲染: 命名结构体登记表分配失败")
|
||||
MlirFail("MLIR render: named-struct registry allocation failed")
|
||||
_MlirNamedCap = capacity
|
||||
|
||||
|
||||
@@ -495,23 +495,23 @@ def _MlirFailNamed(pool: memhub.MemBuddy*, reason: str, name: str):
|
||||
if buf is None:
|
||||
MlirFail(reason)
|
||||
if _MlirCtxLine is not None:
|
||||
viperlib.snprintf(buf, bsize, "%s(类型名 '%s') [行: %s]",
|
||||
viperlib.snprintf(buf, bsize, "%s (type name '%s') [line: %s]",
|
||||
reason, name, _MlirCtxLine)
|
||||
else:
|
||||
viperlib.snprintf(buf, bsize, "%s(类型名 '%s')", reason, name)
|
||||
viperlib.snprintf(buf, bsize, "%s (type name '%s')", reason, name)
|
||||
MlirFail(buf)
|
||||
|
||||
|
||||
def _MlirNamedCheckName(pool: memhub.MemBuddy*, name: str):
|
||||
"""Validate the name as MLIR string-literal content (quote / backslash / control chars fail loud)."""
|
||||
if name is None or name[0] == '\0':
|
||||
MlirFail("MLIR 渲染: 命名结构体名字为空")
|
||||
MlirFail("MLIR render: named-struct name is empty")
|
||||
i: sizet = 0
|
||||
while name[i] != '\0':
|
||||
ch: int = name[i]
|
||||
if ch == '"' or ch == 0x5C or (ch > 0 and ch < 32):
|
||||
_MlirFailNamed(pool,
|
||||
"MLIR 渲染: 命名结构体名字含 MLIR 字符串字面量非法字符(\" / \\ / 控制字符)",
|
||||
"MLIR render: named-struct name contains illegal MLIR string-literal characters (\" / \\ / control chars)",
|
||||
name)
|
||||
i += 1
|
||||
|
||||
@@ -530,11 +530,11 @@ def _MlirNamedStructAppend(dst: str, dstsz: sizet, name: str,
|
||||
_MlirNamedCheckName(pool, name)
|
||||
if fcount < 0:
|
||||
_MlirFailNamed(pool,
|
||||
"MLIR 渲染: 命名结构体在打印时仍为 opaque(无字段体)——MLIR 不允许无体前向声明",
|
||||
"MLIR render: named struct is still opaque at print time (no field body) -- MLIR forbids bodyless forward declarations",
|
||||
name)
|
||||
if fields is None and fcount != 0:
|
||||
_MlirFailNamed(pool,
|
||||
"MLIR 渲染: 命名结构体字段链缺失(FCount 非 0 但无字段)",
|
||||
"MLIR render: named-struct field chain missing (FCount non-zero but no fields)",
|
||||
name)
|
||||
_strappend(dst, dstsz, "!llvm.struct<\"")
|
||||
_strappend(dst, dstsz, name)
|
||||
@@ -551,7 +551,7 @@ def _MlirNamedStructAppend(dst: str, dstsz: sizet, name: str,
|
||||
# truncating (like the anonymous "..." path) would give a silently wrong layout.
|
||||
if fidx >= 4096:
|
||||
_MlirFailNamed(pool,
|
||||
"MLIR 渲染: 命名结构体字段过多或字段链成环(> 4096)",
|
||||
"MLIR render: too many named-struct fields or field chain cycles (> 4096)",
|
||||
name)
|
||||
if first == 0:
|
||||
_strappend(dst, dstsz, ", ")
|
||||
@@ -607,7 +607,7 @@ def TypePrint(buf: str, size: sizet,
|
||||
_MlirTypePrintDepth(buf, size, ty, pool, 0)
|
||||
if _MlirTypeTrunc != 0:
|
||||
_MlirTypeTrunc = 0
|
||||
MlirFail("MLIR 渲染: 类型文本超出输出缓冲被截断(该处缓冲过小,需按类型长度增大)")
|
||||
MlirFail("MLIR render: type text exceeds output buffer and was truncated (the buffer here is too small; increase it per type length)")
|
||||
|
||||
|
||||
# Type-text → MLIR type-text conversion. Accepts both sources: MLIR form (the norm, embedded by
|
||||
@@ -625,7 +625,7 @@ def MlirTypeText(dst: str, dstsz: sizet, src: str, pool: memhub.MemBuddy*):
|
||||
_MlirTypeAppend(dst, dstsz, src, pool, 0)
|
||||
if _MlirTypeTrunc != 0:
|
||||
_MlirTypeTrunc = 0
|
||||
MlirFail("MLIR 渲染: 类型文本转换结果超出输出缓冲被截断(该处缓冲过小,需按类型长度增大)")
|
||||
MlirFail("MLIR render: type-text conversion result exceeds output buffer and was truncated (the buffer here is too small; increase it per type length)")
|
||||
|
||||
|
||||
def MlirTypeTextIsPointer(src: str) -> int:
|
||||
@@ -707,11 +707,11 @@ def _MlirTypeAppend(dst: str, dstsz: sizet, src: str, pool: memhub.MemBuddy*,
|
||||
if dst is None or dstsz == 0 or src is None:
|
||||
return
|
||||
if depth > 64:
|
||||
MlirFail("类型文本嵌套过深(> 64 层)")
|
||||
MlirFail("type text nested too deeply (> 64 levels)")
|
||||
p: str = _MlirSkipWs(src)
|
||||
lt: sizet = _MlirTextLen(p)
|
||||
if lt == 0:
|
||||
MlirFail("空类型文本无法转换为 MLIR 类型")
|
||||
MlirFail("empty type text cannot be converted to an MLIR type")
|
||||
# ---- MLIR text passthrough (builders' embedded types are already rendered by TypePrint) ----
|
||||
if p[0] == '!':
|
||||
# Named-struct text (!llvm.struct<"name", …>): the body must match the module's
|
||||
@@ -797,13 +797,13 @@ def _MlirTypeAppend(dst: str, dstsz: sizet, src: str, pool: memhub.MemBuddy*,
|
||||
if emsg is not None:
|
||||
if _MlirCtxLine is not None:
|
||||
viperlib.snprintf(emsg, lt + clen + 128,
|
||||
"无法转换为 MLIR 类型文本(v1 未覆盖该形态):'%s' [行: %s]",
|
||||
"cannot convert to MLIR type text (v1 does not cover this form): '%s' [line: %s]",
|
||||
emb, _MlirCtxLine)
|
||||
else:
|
||||
viperlib.snprintf(emsg, lt + clen + 128,
|
||||
"无法转换为 MLIR 类型文本(v1 未覆盖该形态):'%s'", emb)
|
||||
"cannot convert to MLIR type text (v1 does not cover this form): '%s'", emb)
|
||||
MlirFail(emsg)
|
||||
MlirFail("无法转换为 MLIR 类型文本(v1 未覆盖该形态)")
|
||||
MlirFail("cannot convert to MLIR type text (v1 does not cover this form)")
|
||||
|
||||
|
||||
def _MlirArrayText(dst: str, dstsz: sizet, p: str, lt: sizet,
|
||||
@@ -827,11 +827,11 @@ def _MlirArrayText(dst: str, dstsz: sizet, p: str, lt: sizet,
|
||||
continue
|
||||
i += 1
|
||||
if xpos == 0:
|
||||
MlirFail("数组类型文本缺少 'N x elem' 形态")
|
||||
MlirFail("array type text is missing the 'N x elem' form")
|
||||
elem_len: sizet = innerlen - xpos - 3
|
||||
eb: str = pool.alloc(elem_len + 1)
|
||||
if eb is None:
|
||||
MlirFail("数组元素类型缓冲分配失败")
|
||||
MlirFail("array element type buffer allocation failed")
|
||||
string.strncpy(eb, inner + xpos + 3, elem_len)
|
||||
eb[elem_len] = '\0'
|
||||
_strappend(dst, dstsz, "!llvm.array<")
|
||||
@@ -863,7 +863,7 @@ def _MlirStructText(dst: str, dstsz: sizet, p: str, lt: sizet,
|
||||
flen -= 1
|
||||
fb: str = pool.alloc(flen + 1)
|
||||
if fb is None:
|
||||
MlirFail("结构体字段类型缓冲分配失败")
|
||||
MlirFail("struct field type buffer allocation failed")
|
||||
string.strncpy(fb, inner + start, flen)
|
||||
fb[flen] = '\0'
|
||||
if idx > 0:
|
||||
@@ -898,7 +898,7 @@ def _MlirNamedStructText(dst: str, dstsz: sizet, p: str, lt: sizet,
|
||||
return
|
||||
nm: str = pool.alloc(lt + 2)
|
||||
if nm is None:
|
||||
MlirFail("MLIR 渲染: 命名结构体名字缓冲分配失败")
|
||||
MlirFail("MLIR render: named-struct name buffer allocation failed")
|
||||
n: sizet = 0
|
||||
q: str = p + 1
|
||||
if q[0] == '"':
|
||||
@@ -916,7 +916,7 @@ def _MlirNamedStructText(dst: str, dstsz: sizet, p: str, lt: sizet,
|
||||
si: int = _MlirNamedFindSlot(nm)
|
||||
if si < 0:
|
||||
_MlirFailNamed(pool,
|
||||
"MLIR 渲染: 命名结构体类型文本未在模块中登记完整定义(MLIR 不允许无体前向声明,须以 !llvm.struct<\"name\", (…)> 内联形态使用)",
|
||||
"MLIR render: named-struct type text has no full definition registered in the module (MLIR forbids bodyless forward declarations; use the inline form !llvm.struct<\"name\", (...)>)",
|
||||
nm)
|
||||
slot: sizet* = _MlirNamedSlot(si)
|
||||
ty: LLVMType* = (LLVMType*)(slot[0])
|
||||
@@ -926,7 +926,7 @@ def _MlirNamedStructText(dst: str, dstsz: sizet, p: str, lt: sizet,
|
||||
_MlirNamedStructAppend(dst, dstsz, nm, fields, fcount, packed, pool, depth)
|
||||
case _:
|
||||
_MlirFailNamed(pool,
|
||||
"MLIR 渲染: 登记表中该名字不是结构体类型",
|
||||
"MLIR render: the name in the registry is not a struct type",
|
||||
nm)
|
||||
|
||||
|
||||
@@ -961,7 +961,7 @@ def _MlirFuncText(dst: str, dstsz: sizet, p: str, lt: sizet, fp: sizet,
|
||||
ret_len: sizet = fp
|
||||
rbuf: str = pool.alloc(ret_len + 1)
|
||||
if rbuf is None:
|
||||
MlirFail("函数返回类型缓冲分配失败")
|
||||
MlirFail("function return type buffer allocation failed")
|
||||
string.strncpy(rbuf, p, ret_len)
|
||||
rbuf[ret_len] = '\0'
|
||||
_strappend(dst, dstsz, "!llvm.func<")
|
||||
@@ -985,7 +985,7 @@ def _MlirFuncText(dst: str, dstsz: sizet, p: str, lt: sizet, fp: sizet,
|
||||
flen -= 1
|
||||
fb: str = pool.alloc(flen + 1)
|
||||
if fb is None:
|
||||
MlirFail("函数参数类型缓冲分配失败")
|
||||
MlirFail("function parameter type buffer allocation failed")
|
||||
string.strncpy(fb, inner + start, flen)
|
||||
fb[flen] = '\0'
|
||||
if idx > 0:
|
||||
@@ -1030,7 +1030,7 @@ def _MlirTypePrintDepth(buf: str, size: sizet,
|
||||
elif bits == 128:
|
||||
viperlib.snprintf(buf, size, "%s", "f128")
|
||||
else:
|
||||
MlirFail("TypePrint: 不支持的浮点位宽")
|
||||
MlirFail("TypePrint: unsupported float bit width")
|
||||
case LLVMType.Ptr(pointee):
|
||||
# MLIR uses opaque pointers: any pointee renders as !llvm.ptr. The pointee is kept
|
||||
# only in the internal model, for op rendering (e.g. a load's result type).
|
||||
@@ -1092,11 +1092,11 @@ def _MlirTypePrintDepth(buf: str, size: sizet,
|
||||
viperlib.snprintf(buf, size, "%s", "none")
|
||||
case LLVMType.Label():
|
||||
# MLIR has no label type (blocks use ^name references); unsupported in v1 → fail loud
|
||||
MlirFail("TypePrint(Label): MLIR 无 label 类型,v1 不支持")
|
||||
MlirFail("TypePrint(Label): MLIR has no label type, unsupported in v1")
|
||||
case LLVMType.Metadata():
|
||||
MlirFail("TypePrint(Metadata): MLIR llvm 方言 v1 不支持 metadata 类型")
|
||||
MlirFail("TypePrint(Metadata): the MLIR llvm dialect v1 does not support the metadata type")
|
||||
case _:
|
||||
MlirFail("TypePrint: 未知 LLVMType 变体")
|
||||
MlirFail("TypePrint: unknown LLVMType variant")
|
||||
|
||||
|
||||
def _MlirStructFields(buf: str, size: sizet,
|
||||
|
||||
+1
-1
@@ -872,7 +872,7 @@ def post_stream(url: str, data: str, content_type: str = "application/json",
|
||||
_st_state = 1
|
||||
else:
|
||||
_st_state = 2
|
||||
stdio.snprintf(_st_err, 512, "HTTP %d(请检查 Key/模型/地址或账号额度)", status_code)
|
||||
stdio.snprintf(_st_err, 512, "HTTP %d (check Key/model/address or account quota)", status_code)
|
||||
return status_code
|
||||
|
||||
|
||||
|
||||
@@ -69,11 +69,11 @@ def _init_argv_win32():
|
||||
global _argc, _argv
|
||||
cmdline: str = w32.win32base.GetCommandLineA()
|
||||
if cmdline == None:
|
||||
stdio.printf("ERROR: GetCommandLineA 返回 NULL,无法获取命令行,argv 将为空\n")
|
||||
stdio.printf("ERROR: GetCommandLineA returned NULL, cannot obtain command line, argv will be empty\n")
|
||||
return
|
||||
cmdlen: sizet = len(cmdline)
|
||||
if cmdlen == 0:
|
||||
stdio.printf("ERROR: 命令行字符串为空,无法获取参数,argv 将为空\n")
|
||||
stdio.printf("ERROR: command line string is empty, cannot obtain arguments, argv will be empty\n")
|
||||
return
|
||||
# Allocate buffer for parameter strings (worst case: entire command line + argc \0s)
|
||||
buf: bytes = _mbuddy.alloc(cmdlen + 1)
|
||||
|
||||
+1
-1
@@ -1528,7 +1528,7 @@ def WriteDumpHeaderFile(IsBreak: int):
|
||||
if IsBreak != 0:
|
||||
Trig = "Ctrl+Break"
|
||||
N: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
"\n===== 栈转储 %04u-%02u-%02u %02u:%02u:%02u.%03u pid=%u 触发=%s 主线程id=%u Seq=%d =====\n",
|
||||
"\n===== stack dump %04u-%02u-%02u %02u:%02u:%02u.%03u pid=%u trigger=%s main_thread_id=%u Seq=%d =====\n",
|
||||
uint32(St.wYear), uint32(St.wMonth), uint32(St.wDay),
|
||||
uint32(St.wHour), uint32(St.wMinute), uint32(St.wSecond),
|
||||
uint32(St.wMilliseconds), wp.GetCurrentProcessId(),
|
||||
|
||||
Reference in new issue
Block a user