From bd3705d68bf25cfef3e24ef880b7bf894b3ddefa Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 25 Aug 2026 18:07:55 +0800 Subject: [PATCH] =?UTF-8?q?feat(tpv):=20--build-dir=20=E5=91=BD=E4=BB=A4?= =?UTF-8?q?=E8=A1=8C=E8=A6=86=E7=9B=96=20project.vpj=20=E7=9A=84=20build?= =?UTF-8?q?=5Fdir?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 新增 --build-dir 参数:在 Config.resolve_paths 前覆盖 BuildDir,相对路径仍基于 project_dir 解析(_join_path),绝对路径(/ 或 \\ 开头)原样保留。用于隔离构建目录验证(如 --build-dir ./tpv_build2 避免陈旧缓存干扰)。 --- App/main.vp | 30 +++++++++++++++++++++++++++--- 1 file changed, 27 insertions(+), 3 deletions(-) diff --git a/App/main.vp b/App/main.vp index 80ba002..240e0a4 100644 --- a/App/main.vp +++ b/App/main.vp @@ -20,6 +20,7 @@ import stdlib import memhub import argparse import w32.win32console as w32cmd +import w32.win32base as w32base import w32.fileio as fileio import sys import ast @@ -57,6 +58,15 @@ def main() -> int: w32cmd.SetConsoleOutputCP(CODE_PAGE) w32cmd.SetConsoleCP(CODE_PAGE) + # [DET] 分配检测开关:在创建内存池前扫描命令行(sys._init_argv 依赖 mb, + # 不能提前;GetCommandLineA 直接读原始命令行,不含任何 pool 分配)。 + # --detection 开启后 mb/perm_pool 均启用前后 0xCDCD 标记 + 记录表探测 + # 越界写(定位"存活块被部分覆盖"的写入者,如 KwEntry cargs)。 + detect_flag: int = 0 + cmd_line_d: str = w32base.GetCommandLineA() + if cmd_line_d is not None and string.strstr(cmd_line_d, "--detection") is not None: + detect_flag = 1 + # Initialize the mbuddy memory pool arena: bytes = stdlib.malloc(POOL_SIZE) if arena is None: @@ -68,12 +78,12 @@ def main() -> int: stdio.printf("FAIL: malloc for perm_pool arena failed\n") return 1 - mb: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, POOL_SIZE) + mb: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(arena, POOL_SIZE, detect_flag) if mb is None: stdio.printf("FAIL: MemBuddy init failed\n") return 1 - perm_pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(perm_arena, PERM_POOL_SIZE) + perm_pool: memhub.MemBuddy | t.CPtr = memhub.MemBuddy(perm_arena, PERM_POOL_SIZE, detect_flag) if perm_pool is None: stdio.printf("FAIL: perm_pool init failed\n") return 1 @@ -107,8 +117,14 @@ def main() -> int: gen.__init__(mb) GenGenerator._g_gen = gen - # P2-P5: 注入各 Handles 模块级单例(Phase1 阶段即调用其状态函数) + # P2-P5: 注入各 Handles 模块级单例(Phase1 阶段即调用其状态函数)。 + # 注意:TPV 编译模块级全局带 sha1 前缀(模块隔离),必须逐个模块赋值; + # 种子 TPC 时代用裸名 @_g_gen(全局共享),遗漏三个 Handles 模块无感, + # 自举后 HT/HE/HEC 委托读各自 _g_gen=None 恒失效(is_global_name 恒 0 误报) GenApi._g_gen = gen + HandlesTranslator._g_gen = gen + HandlesExpr._g_gen = gen + HandlesExprCall._g_gen = gen # P6: 注入语句/赋值/变量/导入/翻译驱动模块的单例 # 初始化 VLogger 并打印启动日志 @@ -136,6 +152,8 @@ def main() -> int: parser.add_argument("--asan", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "ASan mode: .ll first opt -passes=asan then link -fsanitize=address") parser.add_argument("--phase2command", None, argparse.STRING, 0, None, False, argparse.STORE, "Do not run llc/link: write Phase2 llc(opt+llc) and clang link commands to the given .bat path") parser.add_argument("--nowarn-register", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Suppress Phase A dependency WARN") + parser.add_argument("--detection", None, argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Enable MemBuddy allocation detection (0xCDCD markers + record-table probe for out-of-bounds writes; applies to both mb and perm_pool)") + parser.add_argument("--build-dir", None, argparse.STRING, 0, None, False, argparse.STORE, "Override project.vpj build_dir (default ./.tpv_build; relative paths resolve against the project dir)") parser.add_argument("--version", "-v", argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Show version and exit") parser.add_argument("--help", "-h", argparse.BOOL, 0, None, False, argparse.STORE_TRUE, "Show help and exit") @@ -177,6 +195,7 @@ Target: %s output: str = args.get_str("output") phase: str = args.get_str("phase") cc: str = args.get_str("cc") + build_dir: str = args.get_str("build-dir") _gb_clean: INT = args.get_bool("clean") #if project is not None: stdio.printf(" --project: %s\n", project) #else: stdio.printf(" --project: (未指定)\n") @@ -281,6 +300,11 @@ Target: %s if proj_dir is not None: string.memcpy(proj_dir, proj_path, slash_pos) proj_dir[slash_pos] = '\0' + # [--build-dir] 命令行覆盖 project.vpj 的 build_dir:在 resolve_paths 前 + # 设置,使相对路径仍基于 project_dir 解析(如 ./tpv_build2 → Test/tpv_build2), + # 绝对路径(/ 或 \ 开头)由 _join_path 原样保留。 + if build_dir is not None: + Config.BuildDir = build_dir Config.resolve_paths(proj_dir) Config.print_config()