90 Commits
Author SHA1 Message Date
TermiNexus 65e03c823f feat(obs): reject nullable call arguments for non-nullable parameters
Compiled callees register a per-parameter nullable mask (self included for methods, specializations included); cross-module callees fall back to their vpi param annotations. A nullable binding/field argument now fails instead of silently narrowing.
2026-11-03 18:12:20 +08:00
TermiNexus 91e188c539 feat(vpc): vprofile instrumentation (--spend-file/--vpf) + verbatim --build-self forwarding
--spend-file <path> instruments every compiled function with
vpf_enter(id, name) / vpf_leave(id); main additionally calls
vpf_install(path, level). includes/vprofile.vp keeps the tables (no
allocation on the hot path), times with QPC and writes the report from
atexit, so normal return and exit() both produce it.

  --vpf 0 off | 1 call counts | 2 +per-function time (default) |
  3 +caller/callee edges

*A report path is resolved against the output exe directory, so
  ../prof.txt and absolute paths behave as documented regardless of the
  process cwd.
*Instrumented include objects use their own cache suffix
  (.binary.vpf<N>, stacked with the asan/traceback suffixes) and that
  cache is cleared once when profiling is enabled.
*StubMergerBuild force-adds the vprofile runtime to the reachable set;
  FuncGenBase emits a declare on demand because the instrumented module
  usually does not import vprofile.
*--repl is rejected: the fragment DLL is loaded at runtime and does not
  link the runtime.

--build-self no longer keeps a whitelist: SelfBuild.CollectForwardedArgs
drops only --build-self / --project / --build-dir and forwards every
other argument verbatim, so a self-build can enable the same modes as a
normal build.
2026-10-30 22:24:01 +08:00
TermiNexus eda8e4465f refactor(codegen): one body pipeline for module functions and class methods
Module-level functions and class methods each carried their own copy of "resolve the
return type", "create the parameter allocas" and "emit the implicit epilogue". The copies
drifted: an unannotated method was still typed i32 by the class-method body path while its
declaration said void, so the epilogue emitted `llvm.return 0 : i32` inside a void function
and the MLIR verifier rejected it ("'llvm.return' op expected no operands", Scheduler._yield).

- FuncGenBase.resolve_func_ret_ty: the single return-type policy (annotation -> storage
  marker -> __init__/__new__ hooks -> unannotated = procedure void -> fail-fast). Used by
  the forward-declare pass, the body pass, class methods and generic specializations
- FuncGenBase.param_llvm_ty: the single parameter mapping (CVoid skipped, bare class ->
  Ptr(struct), ArrayT -> element pointer), used by every signature and alloca site
- FuncGenBase.emit_func_epilogue: the single implicit-return implementation (procedure ->
  ret void, unreachable merge, fail-fast for an annotated fall-through), shared by module
  functions, methods and nested functions
- FuncGenBase.translate_func_body: the shared body pipeline (scope entry, self/parameter
  storage, *args va_list, try/except out-params, pre-scan, capture preparation, slife,
  statements, epilogue, state restore). ClassGenVTable._translate_method now only handles
  method naming, vtable/overload registration and add_param
- the same policy reaches cross-module and generic declares: unannotated vpi functions and
  methods declare void, generic specialization declares use the shared resolver, and the
  list.append call sites emit a void call
- method parameters now carry the const / volatile / pointee-volatile / pure markers that
  the module-level path always had
- FuncGenMixin: the two dry-run helpers that return ints are annotated, as the language
  now requires (an unannotated def is a procedure)

Verified: 41 Test projects pass (MethodProcTest, CrossModuleSigTest, RawPtrParamTest,
AstTest, ListTest, OopInheritTest, ...), ViperC self-hosts with the new compiler, and the
6 tests that still fail reproduce identically with the previous compiler.
2026-10-29 19:37:55 +08:00
TermiNexus 3b3cd42d1c fix(codegen): a procedure never emits a value return
Unannotated functions were typed by scanning the body, which inferred i32, so falling off
the end emitted `llvm.return 0 : i32` inside a function declared void. The MLIR verifier
rejects that ("expected no operands"), which is what broke Scheduler._yield.

- an unannotated `def` is void in both the forward declare and the body, so the implicit
  epilogue emits `ret void`
- translate_return treats a procedure (no annotation, `-> None`, or a void-typed function) as
  void: the expression is evaluated for its side effects and `ret void` is emitted. Bare
  `return`, `return f()` where f is void, and `return <None value>` are legal and never carry
  a value
- body_has_value_return accepts `return f()` and `return <None define>` in a procedure
- `define X = None` is a named None: registered as the string sentinel None, materialized as
  a None value at use sites, and exported through the vpi
2026-10-29 18:13:06 +08:00
TermiNexus 7cbe4e93dc fix(codegen): widen calls by the declared return signedness 2026-10-27 19:51:46 +08:00
TermiNexus a2e9b1848e fix(defines): isolate same-name cross-module DefineT lookups 2026-10-26 17:40:06 +08:00
TermiNexus d88cafa12c feat(pure): integrate pure_str with lifetime and NLL 2026-10-26 13:52:00 +08:00
TermiNexus 782b4d63ff feat(build): 增加 --build-self 与 copyself
- 新增 copyself:延迟后删除目标并复制文件/目录
- ViperC 新增 --build-self:自举到 __vpcbuild_2__ 后由 copyself 替换 __vpcbuild__
- 同步当前 ViperC 工作区已有的 Gen/Diag/Stub 改动
- .gitignore 忽略 __vpcbuild_* 与 _sha1_map.txt
2026-10-26 02:09:45 +08:00
TermiNexus 9c3ebc8a2c fix(ffilib): 为 runtime CDLL thunk 创建 entry block 并移除失败静默返回
- new_builder 的 CurBlock 初值为 None,_emit 会静默丢弃指令,导致 thunk 生成空函数体(mlir-opt: empty block)
- 补 create_block + position_at_end,随后再把全部静默 return None 改为 fatal_error
- 移除两处 [ffiprobe] 调试探针
2026-10-24 23:57:09 +08:00
TermiNexus ecd4a0b14a fix(ffilib): thunk 复用已有 declare,而不是遇到同名就跳过
探针显示 ffi_lib=add_c2 / rt=1 都已正确,说明断点在去重守卫:@add 在 declaration 阶段/vpi 注入已存在为 declare,find_func_in_module 命中后跳过了 thunk,最终留下普通 declare 导致 undefined symbol。改为按状态区分:已存在 declare -> IsDeclared 置 0 并复用(形参类型与名称沿用它的,否则函数体引用不到入参);已是指令体 define 才跳过;不存在则新建 define。
2026-10-24 23:03:14 +08:00
TermiNexus 1508563f1c chore(ffilib): 临时探针(CDLL 抽取 + extern 分支的 ffi_lib/runtime)
现象与"exe 已含最新提交"矛盾:add_c2 仍生成全局、@add 无 thunk、无 _ffilib 引用。加两处 printf 定位断点:_HandleCDLL 入口打印句柄名;translate_function_def 的 extern 分支打印 fd.ffi_lib 与 FfiHandleRuntime 结果。定位后立即移除。
2026-10-24 22:51:31 +08:00
TermiNexus 522075097e fix(ffilib): translate_function_def 的 extern 分支也生成 runtime thunk
现场 temp/02/029af3a930989beb.text.ll 里 @add 是普通直接调用、没有 _ffilib 引用,说明 App 文件的 extern 走的是 translate_function_def 而不是 forward_declare_functions,thunk 校验挂错了地方。两处都挂:各自先查 find_func_in_module 去重;runtime=True 生成 thunk,runtime=False 保持原 declare 路径。
2026-10-24 22:33:14 +08:00
TermiNexus 0acbefafd8 feat(ffilib): runtime CDLL 生成 thunk(绝对路径 LoadLibraryA + 间接调用)
_emit_runtime_ffi_thunk 生成 define <name>(%p0..): Load(path) -> Sym(h,name) -> bitcast 成 <ret>(<params>)* -> call_indirect -> ret;符号名与普通 extern 一致(裸名),调用点零改动。路径与符号名用 ExprGenConst.create_global_string 落成常量操作数(GEP 由该助手处理)。约束:仅标量参数/返回值,结构体按值与变参 fail-fast;declare-only 阶段仍走普通 declare,避免同模块 define/declare 同名并存。
2026-10-24 22:20:55 +08:00
TermiNexus 74a9d96d3c feat(ffilib): extern <lib> name(...) 校验库句柄并按 runtime 决定行为
Pass 0 新增 CDLL 句柄表(变量名 -> runtime):_HandleCDLL 接收赋值目标名,_RegisterFfiHandle 登记,FfiHandleRuntime 提供查询(1=运行时/0=链接期/-1=未登记)。FuncGenDef 在前置声明阶段校验 ffi_lib:未绑定 ffilib.CDLL 报 NameError;runtime=True 报 NotImplementedError(需要 _ffilib 运行时符号绑定,绝不静默退化为静态链接);runtime=False 照常生成裸名 declare。
2026-10-24 21:12:55 +08:00
TermiNexus f54c365b20 feat(overload): vpi 写入端把签名后缀写进 def 名,签名 hash 与上下文无关
_overload_sig_text 算 hash 时固定传 imported_modules/from_imports/trans = None,只靠全局结构体表解析,使定义端、vpi 写入端(translator 尚未创建)、读取端天然算出同一个 hash,无需跨阶段搬运 import 上下文;解析不到即 fail-fast。Converter 新增 _PyiOverloadSuffix:同一作用域同名 def >=2 时追加 _v{hash}(方法跳过 self,@staticmethod 不跳;extern/state/export/main 不加)。读取端 _inject_function_declare 用 fd.name 拼符号,自动与定义端一致,返回/形参注解缓存也按后缀分组不再互相覆盖。
2026-10-24 17:29:51 +08:00
TermiNexus 20e31b8dbd refactor(overload): 抽出不依赖 translator 的签名后缀计算(vpi 两端复用)
_overload_sig_text 拆成 _overload_sig_text_ctx(显式传 imported_modules/from_imports/trans)与薄包装;新增 _overload_sig_suffix_ctx 只返回 _v{16位签名hash}。GenApi.overload_sig_suffix 提供无 translator 的入口,供 vpi 写入端(写 def 名)与读取端(核对注入名)共用同一 hash,避免三处各算一套导致跨模块符号对不上。行为不变(尚无调用方)。注:本提交含此前未提交的既有改动。
2026-10-24 17:18:23 +08:00
TermiNexus faea680116 feat(overload): 类方法与虚函数重载(符号/函数表键/vtable 槽名一致)
类内同名方法 >=2 时,方法短名追加 _v{参数签名hash}(跳过 self,static 不跳):LLVM 符号 {sha1}.Class.m_v{hash}、函数表键 Class.m_v{hash}、vtable 槽名 m_v{hash} 三者一致。vtable 收集改为先用 _method_slot_name 建槽名表:继承槽的覆盖判定按槽名比较(只有签名相同的同名方法才算覆盖),本类槽按槽名去重(重载各占一槽);__init__/__before_init__/__new__ 仍按原始名排除。实例方法调用与 Class.m(obj,...) 两条路径在候选 >=2 时用同一套决议(prefix 模式 + param_base=1),并把 method_name 换成带后缀的短名,使虚调用取到正确槽位。注:本提交含此前未提交的既有改动。
2026-10-24 17:02:33 +08:00
TermiNexus 00c385dc94 fix(overload): 签名文本改用类内 _overload_append,避免跨 mixin 调用 FuncGenBase._append_str
FuncGenDef 与 FuncGenBase 是兄弟 mixin,MRO 中不含对方;在 FuncGenDef 里调用 self._append_str 会让调用点解析失败(method return type cannot be obtained precisely: _append_str)。改为 FuncGenDef 自己的有界追加,并把超长判定并进去重处理。
2026-10-24 16:19:23 +08:00
TermiNexus 195af1101e feat(overload): 模块级函数重载决议与签名符号名
同名顶层 def 组成重载组时符号名为 {模块sha1}.{name}_v{规范参数签名hash}(仅重载组加后缀,其余保持 {sha1}.{name});签名由注解经 SpecFromLLVMType+SpecWithSign 生成,别名展开为 i32/u32,指针为 p:i32、结构体为 st:{模块sha1}.类名。调用点按 C++ 部分序决议:精确 > 提升/拓宽 > 转换(同宽符号性/指针到 void*) > 省略号,返回值不参与;唯一最优才通过,否则歧义、无匹配、实参类型无法定型均 fail-fast;默认参数参与可行性判定。重复签名、extern/state/export/main 同名、泛型同名均报错。注:本提交含此前未提交的既有改动。
2026-10-24 16:02:53 +08:00
TermiNexus 42b094a575 refactor(viperc): 退役 t/c 模块标记,内建类型改由编译器直接识别 2026-10-18 12:56:57 +08:00
TermiNexus 3242560d02 支持 tls 关键字,全面准备清退 t, c 2026-10-17 23:40:06 +08:00
TermiNexus 3e1e1fc1b3 fix(gen): 消除 ViperC 侧 P0 级静默截断
match:case 数超过 MAX_MATCH_CASES 时 fail-fast(原先 break 会静默少分支,need_case 检查也发现不了)。vtable:初始化串按真实方法表动态分配,_vtable_strcat 溢出改 fatal;VTBL_METHOD_MAX 超限不再 break(原先子类 override 静默失效)。符号名:coro_pool_/__tls_init_done_/__decor_rec_/闭包 fn_ptr 的定义与引用改为按实际长度分配,消除 96 vs 128、64 vs 128 的不对称。Stub:_PyiEmit 溢出改 VLogger.error(半截 .vpi 会被当完整文件解析);VpiReader 参数段/返回注解缓存槽放不下时 fail-fast,不再丢段导致形参注解错位。Includes:文件超过 1MiB 拒绝哈希(SHA1 冲突会让两个模块共用缓存);add_file_entry 失败不再被忽略。f-string:格式串按字面量/转换符实际长度分配,字面量与 format_spec 溢出 fail-fast。
2026-10-17 18:46:18 +08:00
TermiNexus d6b87da063 fix(viperc/attr): 不再要求 import c 才认 @__attribute__(否则函数属性被静默丢弃)
ast/parser.vp 的 _DesugarMagicAttribute 会把用户写的 `@__attribute__(...)` 脱糖成
`@c.Attribute(...)`,此处看到的 `c.` 前缀是编译器自己产生的(用户并未写 `@c.Attribute`)。
原先这里要求 is_module_imported(...,"c"),用户没写 `import c` 时整条装饰器被静默丢弃,
stackrealign / always_inline 等函数属性全部失效。现去掉该守卫,与 extract_func_section
(本就没有此守卫)保持一致。
2026-10-14 16:42:16 +08:00
TermiNexus 12da1cbfc1 fix(gen): define 复用前置声明时按源码形参名对齐签名参数名,修签名与函数体两套参数名导致 MLIR「region entry argument already in use」 2026-10-13 20:33:06 +08:00
TermiNexus d206abf3e1 chore: 全仓同步 w32→win32 模块改名与 range(int(...)) 显式收窄适配 2026-10-12 20:59:11 +08:00
TermiNexus ae12ae8581 Revert "feat(gen): 裸类形参按值物化(值语义),调用方 ABI 不变"
This reverts commit 87914b0a51.
2026-10-12 19:56:02 +08:00
TermiNexus 87914b0a51 feat(gen): 裸类形参按值物化(值语义),调用方 ABI 不变 2026-10-12 18:25:04 +08:00
TermiNexus 3384941cd1 chore: 改名同步 TransPyV -> ViperC(源码/配置内的纯替换) 2026-10-12 15:06:28 +08:00
TermiNexus 4e46a25ab1 fix(gen): define 位宽/整数提升/移位/AugAssign 规则收敛,修 va_list 与 traceback 卡死
- define 位宽:cdefine_decl_bits 单一裁决(注解 → 右侧强转 → 值最小可存宽度),定义方与 VpiReader 两处跨模块注册共用;lookup_cdefine_bits 取最后一条非零记录;存储即截断;使用侧改按声明位宽;通用求值器加编译期除零/移位越界 fail-fast
- 消除对无符号强转加宽方向的依赖:define_min_width 改 (value>>32)==0,截断改左移+算术右移,修 TPC/TPV 判定不一致导致 0x80000000 误判 64 位
- 整数提升:算术/移位、比较、一元 +/-/~ 提升到 i32;位运算保持同宽不提升
- AugAssign:y 有效宽度须 <= x、禁 y 显式有符号而 x 无符号;移位计数静态范围检查
- 函数入口复位 va_list 状态与 willFree 失效槽表(FuncGenDef/FuncGenMixin/VarGenMixin 等)
- BuildPipeline:traceback 逐行扫描改 span 判定,去掉对全文 strlen 的 O(n^2)
2026-10-12 12:37:48 +08:00
TermiNexus 82ad5da7c7 fix(narrow): len() 结果赋给 int 的形参/默认值计数改用显式 int(...)
FuncGenDef 的 fd_param_count/fd_default_count/tfd_param_count/tfd_default_count 与 ClassGenVTable 的 md_param_count/md_default_count 原本直接接收 len()(sizet),触发隐式窄化;改 int(len(...)) 保持原有截断语义
2026-10-11 09:34:43 +08:00
TermiNexus a3a627f513 fix(gen): lambda 返回类型完全跟随 body(整数也跟随,不再一律 i32)
承接上一提交:原来只修正指针/浮点两类,整数仍保留 i32 语义(i64 实参会被 trunc 成
i32,静默有损)。现按用户要求改为**完全跟随 body 的实际类型**:
- func.RetTy = body_val.Ty,然后原样 build_ret,不做任何强转;
- void body(如 lambda: <void 调用>)→ RetTy = Void + build_ret_void
  (原来会因 "a void value cannot take part in any operation" 直接报错)。
副作用(预期内):body 为 bool → i1;body 为 i64/u64/f64 → 同宽返回;指针 → 指针。
调用点从函数签名取返回类型(CallGenMixin 读 local_fn.RetTy),自动适配。
注意:这是 ABI 行为变更,重编后必须回归 ClosureTest / ClosureTest2 / ClosureCallTest。
2026-10-10 10:46:51 +08:00
TermiNexus ea57986312 fix(gen): lambda 提升函数按 body 类型修正返回类型(原先恒 i32)
translate_lambda 第 4 步创建提升函数时只能先写 i32(body 尚未翻译);第 11 步原来把
body 值一律 coerce_to_type 到 i32,于是:
- body 返回指针 → 撞 CastError(implicit pointer-to-integer conversion is forbidden);
- body 返回浮点 → fptosi 成 i32(静默有损)。
现按 body 的实际类型修正 func.RetTy(mlirlite 公开字段;本步之后才发 ret,期间无人读
RetTy;调用点读到的已是修正后的签名):
- 指针   → RetTy = body 类型,直接 ret(不再强转);
- 浮点   → 同上(不再 fptosi);
- 整数/其它 → 保持既有 i32 语义(与"无注解嵌套 def 保持 i32"同口径,避免改动既有行为)。
与嵌套 def 的返回类型缺口同类(见上一提交)。
2026-10-10 10:44:07 +08:00
TermiNexus 5d1e604aac fix(gen): 嵌套 def 的返回类型跟随 -> T 注解(原先写死 i32)
现场:def Inner(p: char*) -> char*: return p 报
CastError: implicit pointer-to-integer conversion is forbidden ...
—— 因为 translate_nested_function_def 把提升后的闭包函数写死成
define i32 @__closure_Inner(i8* %env, i8* %p)(grep 过整个文件,从未读 fd.returns),
return p 于是要把 char* 隐式转 i32。即"嵌套 def 只支持 int 返回",此前被同文件
更早的用例报错掩盖(EscapeMethodTest 的 (A)/(B) 因同命裁剪静音后才露出来)。

改动:
- 提升函数按 fd.returns 解析返回类型(resolve_annotation_type);解析不出 -> fail-fast。
  边界:fd.returns 为 None 或注解是 None / t.CVoid 时**保持 i32**(不改既有 ABI,
  避免打断现有无返回值/无注解的嵌套 def)。
- 隐式收尾的零值改为 ConstZero(ret_ty)(原写死 const_int32(0),签名一变 llc 会拒绝),
  取不到零值则 fail-fast。

已知未覆盖:lambda 的提升路径同样写死 i32(见 FuncGenMixin 中 lambda 分支),
本轮不动(lambda 无返回注解可跟随)。
2026-10-10 10:40:36 +08:00
TermiNexus dd24dc670f fix(gen): P2 失效状态改存独立槽表,不再给 VarEntry 加字段
现象:任何工程编译都在函数形参注册刚结束处 access-violation(pc=0,逐字节可复现)。定位:逐层探针把崩点压到 FuncGenDef 的 pre_scan 段,而该段对 Check(body 仅 if+return)应为空操作,唯一变量是 VarEntry 这个热结构被加了 Freed 字段。修法:撤销 VarEntry.Freed,改用 VarGenMixin 的独立失效槽表 _g_freed_slots(键 = 变量槽 alloca,整次翻译内唯一,故全局累积、无需按函数 reset/restore);_FreedMark/_FreedCheck/_FreedClearSlot 三个 API 替换字段读写,P2 语义不变。同时清除全部 TEMP 探针。
2026-10-09 11:51:11 +08:00
TermiNexus 95b076581a chore(dbg): pre-scan 与 _SlifeReset 之间补 p1d 探针(TEMP)
p1c 之后仍崩,最后一段只剩 pre-scan 与 _SlifeReset;p1d 把两者分开。
2026-10-09 11:30:33 +08:00
TermiNexus 054dcf0a0b chore(dbg): 形参注册与 pre-scan 之间补 p1c 探针(TEMP)
add_var 三次全过(esz=56),崩点在其后。p1c 夹出 L700-763(状态保存)与 L765-775(pre-scan)两段。
2026-10-09 11:24:29 +08:00
TermiNexus 9b97470c09 chore(dbg): 函数翻译内段探针 p1/p2/p3
夹住 auto_addr → 形参注册/pre-scan → slife reset → 语句翻译 四段;TEMP,定位后移除。
2026-10-09 10:44:56 +08:00
TermiNexus 400cc6e17b chore(dbg): 再加两个探针(函数名 / slife 赋值 rhs kind)
TR.fn: <name> 定位到具体函数;slife.note rhs_kind=<k> 定位到 _slife_note_assign 的哪条 RHS 路径。均为 TEMP,定位后移除。
2026-10-09 10:19:29 +08:00
TermiNexus c02aa3a2eb fix(gen): @life/@willFree 不再被当作运行时装饰器
自定义装饰器检测(__decor_wrap_<name> 生成路径)此前把 P2 的编译期标注当成 User 装饰器:会生成 wrapper 调用并不存在的 @life/@willFree,并把被装饰的 extern def(如 stdlib.free)变成本模块 internal 声明,llc 报 invalid linkage for function declaration。把 life/willFree 加入该处标记白名单。
2026-10-08 21:43:47 +08:00
TermiNexus 2178970ff7 feat(gen): slife 释放前调度析构 __del__,并禁止手动 del(§3.6 落地)
- 释放统一入口 _SlifeEmitGuardedFree 改为「先析构、再 free」;析构名定案 __del__(对齐 TPC LLVMCG/MemoryOps._emit_local_heap_frees 的释放路径;del obj 那条语句走的仍是 __delete__)。

- 查表沿 MRO / 跨模块 stub 回退(复用 ExprGenOps._resolve_dunder_by_class);类未定义 __del__ 时**不加任何分支**,常见路径零开销。

- 析构用条件分支而不是 select:未拥有的路径必须完全不进析构体(析构体里会解引用 self,传 null 进去会踩空);块标签走 trans._label_counter,避免同函数内重名。

- §2.4 判据5 扩展:对 slife 对象手动 del obj → LifetimeError(否则析构跑两次)。hlife 路径不受影响。

- 为把 trans 传进析构查找,_SlifeEmitFrees / _SlifeEmitGuardedFree / _SlifeDropOwned 加 trans 形参,9 处调用点同步。
2026-10-08 20:34:11 +08:00
TermiNexus 78b2052445 feat(gen): 接线 M3 owned slife 的 RAII 出口释放(函数级 scope guard)
- 所有权影子标志(i8,登记时入口块置 0)+ free(select(影子!=0, load 槽, null)) 保护式释放:赋值在分支/循环里而未执行 → free(NULL);槽里写入外来指针或别名 → 清影子,绝不 free 外来指针;循环反复 new → 赋值前覆盖释放上一轮,不累积。

- 三条函数体转译路径(FuncGenDef 主路径 / FuncGenMixin 嵌套函数提升为 __closure_* / ClassGenVTable 方法体)各自抬升与弹回登记区间;修两处漏 reset 导致内层出口 free 外层对象再被外层 free 一次 = double free(Windows STATUS_HEAP_CORRUPTION)。出口按槽去重做兜底。

- free 由模块前言统一声明(Translator.vp,紧挨 malloc);释放点只查表 + fail-fast,绝不吐指向未声明符号的 llvm.call。

- 赋值处记账:new heap slife → 登记 + 覆盖释放 + 影子置 1;其它 RHS(new stack / hlife / 别名 / 外来指针 / None)→ 已登记则交还所有权。手动 free slife 对象 → LifetimeError。
2026-10-08 20:03:54 +08:00
TermiNexus 2fb648d68a feat(lang): 新增 cif/celif/celse 条件编译与值引用注解 &T/&temp T,assert 改译 testcheck.check
cif 三件套:StmtGenCifMixin 负责常量求值(含 defined(模块宏) 的 Attribute 形式),链式错配与含运行时变量一律 fail-fast;删掉 c.CIf 家族。值引用:TypeGenResolve 让 CRef/CTempRef 与 t.CPtr 走同一解析路径(&void 折叠为 i8*,删除 t.CNeedPtr),CallGenBase 在调用点按形参模式自动取址(ref 只接受左值,右值 fail-fast;temp 物化临时栈),跨模块经 VpiReader/StubMergerBuild 传递模式。assert:StmtGenMixin 合成 testcheck.check(cond, None, msg),Translator 检测到 assert 时自动注入 testcheck 导入(带去重与防环),深递归守卫改用 stdio.printf + stdlib.exit(Translator 无 Gen 成员)。
2026-10-07 19:03:16 +08:00
TermiNexus edca6c3760 chore(detsite): 类型文本 4096 缓冲补插桩
19 处 TypePrint(..., 4096, ...) 对应的 pool.alloc(4096) 全部改用 alloc_tagged
(AssignGenMixin/ClassGenVTable/FuncGenDef/ExprGenBase/ExprGenCdef/CallGenLeafKit/
TypeGenCType/TypeGenResolve/CallGenCBuiltin/ExprGenOps),tag 33..51 见 memhub.vp。
detection==0 时 alloc_tagged 直接转发,无布局与性能变化。
2026-10-07 15:16:52 +08:00
TermiNexus 848dc0ab38 fix(compiler): 跨模块调用补全 int→ptr 转换与别名默认参数;类型文本缓冲 512→4096
1) CallGenMixin.vp(跨模块 extern 实参提升):指针目标形参改为无条件走 coerce_to_type——原守卫按整数位宽比较,而指针类型的 bits 恒为 0,整段提升被跳过,致 VirtualAlloc(0,...) 以 i32 传入指针形参、mlir-opt 报 operand type mismatch(ViperAIChat 失败)。

2) CallGenMixin.vp(默认参数限定键):改用 StructGen._resolve_module_sha1 解析模块 SHA——原只精确匹配模块名,import x as y 这类别名取不到真实 SHA,默认值表落空、跨模块调用实参数目不符(ViperRequestsTest 失败)。

3) 11 个文件的 TypePrint 类型文本缓冲 512→4096(分配与传入 size 成对修改):48 字段类(如 MNIST 的 Net)的 MLIR 结构体类型文本超过 512 被截断并 fail-fast。
2026-10-07 08:48:09 +08:00
TermiNexus 7a9bc5ae75 chore(messages): TransPyV 运行时中文字符串英文化
把 TransPyV/App 下 57 个文件的运行时中文字符串(编译器报错/告警/日志、CLI 帮助与横幅、REPL 提示、Phase1/Phase2 流程日志、Codegen 各 Mixin 的类型与调用报错、Stub/Vpi 诊断等)共 1091 行译为英文。

口径:只改字符串字面量内部文字,行数零变化(+1092/-1092);printf 格式符与转义序列多重集合校验不变(_strcheck 异常 0);译文不引入撇号以免干扰单引号字面量解析。验证:三重重编 SUCCESS(136.20s)+ 全量 77/77 顺序回归通过 + VET 编译 SUCCESS / --search-paths 7 条 exit 0;新产物 help/日志输出已为英文。
2026-10-07 00:03:58 +08:00
TermiNexus cd55a7e214 refactor: rawptr[T] -> T*(R14)+ 修 REnum 前向占位未就地填充
R14:rawptr[X] -> X*(56 文件 / 834 行改动);保留 6 处 rawptr[t.CPtr](存纯裸指针的规范例外)。 修复:class X(t.REnum) 的变体字段写成自引用 X* 时,字段解析在变体扫描期经 ensure_forward_class 建了一个 opaque 前向占位;末尾 register_struct 按 Ty 指针去重会再建第二个同名 entry,而 find_struct 取首个(占位,0 字段)→ X.__sizeof__() == 0,报「已注册但大小为 0(字段链表未填充)」。改为注册前若命中同模块前向占位则就地填充(与 ensure_forward_class 文档口径一致)。TPC 无此问题,属 TPV 侧缺口。 验证:自举三重重编 SUCCESS;全量 77/77 顺序回归通过(修复前卡在 LLvmLiteTest)。
2026-10-05 17:38:28 +08:00
TermiNexus 0f4aeeceff docs(tpv): R11 注释与 docstring 英文化并压缩到 2 行内
按 wiki/新规范:注释只讲作用、不掺杂历史原因、避免超长、尽可能英文(含三引号 __doc__)。全文 79 个 .vp:# 注释 16269 行(中文 13808)与 docstring(中文 1381 处)全部改英文;超 2 行的注释块(2093)与 docstring(397)全部压到 2 行。运行时可见文本未动(fatal_error/VLogger 的中文报错文案、stdio.printf 的横幅格式串)。校验:屏蔽注释与三引号后逐行比对各文件代码骨架,0 漂移。验证:自举重建 153.48s 通过(跨模块内联完成);TPV 顺序回归 77/77 全通过。
2026-10-05 13:38:22 +08:00
TermiNexus f2ef1bb240 refactor(tpv): 新语法 R10 括号内隐式续行并一行(1140 处 / 67 文件) 2026-10-05 07:14:14 +08:00
TermiNexus 4a685d478f refactor(tpv): 新语法 R10 单语句块并一行(7722 处 if/for/while 单语句体) 2026-10-05 03:10:55 +08:00
TermiNexus 30a3da4cd4 refactor(tpv): 新语法 R10(反斜杠续行合并)+ 回退 R5(语义不等价)
- 反斜杠续行合并为单行(304 处),呼应"尽可能不换行"。
- 回退 c.DerefAs(p, v) → *p = v 两处(StructGenMixin):原写法是 bitcast 后
  store 指针位,新写法按 pointee 值类型赋值,类型不符(i8* → List 值),
  语义不等价,保留 c.DerefAs。

种子自举通过。
2026-10-04 22:56:27 +08:00