refactor(tpv): 删除 Handles 目录,核心逻辑合并进 Gen
- 新建 Gen/Translator.vp:Translator 类 + Mixin + 常量 + _mbuddy 自 HandlesTranslator 迁入(删 7 个委托壳与 _g_gen) - GenApi 下沉 7 个 global/nonlocal 管理委托(add/is_global_name、add/is_nonlocal_name、get_nonlocal_type/index、clear_scope_names)+ update_global_func_typestr - CallGenLeafKit 并入 ExprCallHandle 类,NewExprCallHandle 改本地引用 - 删除 Handles/HandlesExpr/ExprCallTable/HandlesBase(60+ 委托零消费者/纯委托壳)与 Handles 目录整体 - 全 App 56 文件 import 改指 lib.core.Gen.*,清理死 import,委托调用改 GenApi,main/BuildPipeline _g_gen 注入删除
This commit is contained in:
1 parent
d99b6268de
commit
24ae2dc966
64 files changed
+11434
-13008
No files matched your search
@@ -16,9 +16,7 @@ import subprocess
|
||||
import viperlib
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.Stub.StubGen.Converter as StubConverter
|
||||
import lib.Projectrans.Config as Config
|
||||
@@ -154,9 +152,6 @@ def TranslateFileGetTrans(mb: memhub.MemBuddy | t.CPtr, file_path: str,
|
||||
# P2-P5: 注入各 Handles 模块级单例(委托函数经本地 _g_gen 访问,
|
||||
# 避免函数体 import 包模块与类/模块名歧义)
|
||||
GenApi._g_gen = gen
|
||||
HandlesTranslator._g_gen = gen
|
||||
HandlesExpr._g_gen = gen
|
||||
HandlesExprCall._g_gen = gen
|
||||
# P6: 注入语句/赋值/变量/导入/翻译驱动模块的单例
|
||||
# 设置当前文件名(供报错使用)
|
||||
GenApi.set_current_file_type(file_path)
|
||||
|
||||
@@ -9,8 +9,7 @@ import w32.win32base
|
||||
import ast
|
||||
import llvmlite
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Gen.Generator as GenGenerator
|
||||
|
||||
@@ -11,8 +11,7 @@ import w32.win32base
|
||||
import ast
|
||||
import llvmlite
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Gen.Generator as GenGenerator
|
||||
|
||||
@@ -10,8 +10,7 @@ import w32.win32base
|
||||
import ast
|
||||
import llvmlite
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Gen.Generator as GenGenerator
|
||||
|
||||
@@ -15,8 +15,7 @@ import llvmlite
|
||||
import subprocess
|
||||
import argparse
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
@@ -13,10 +13,8 @@ import llvmlite
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
import lib.core.Handles.ExprCallTable as ExprCallTable
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -1959,7 +1957,7 @@ def _inject_function_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
# 补全全局函数表 TypeStr(参数已全部添加,对齐 FuncGenDef L211 行为):
|
||||
# vpi 注入路径若不补全,跨模块 vtable/调用解析 find_func_entry_global()
|
||||
# 时 TypeStr 为空 → "vtable 方法找不到函数实现"(依赖模块晚于本模块编译时必现)
|
||||
ExprCallTable.update_global_func_typestr(pool, fd.name, func)
|
||||
GenApi.update_global_func_typestr(pool, fd.name, func)
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -2152,7 +2150,7 @@ def _inject_method_declare(pool: memhub.MemBuddy | t.CPtr,
|
||||
# vpi 注入的方法声明若不补全 TypeStr,跨模块继承 vtable 生成时
|
||||
# find_func_entry_global().TypeStr 为空 → "vtable 方法找不到函数实现"
|
||||
# (astaux.vp 先于 ast.base.vp 编译时必现:AST.accept 仅有 vpi 注入条目)
|
||||
ExprCallTable.update_global_func_typestr(pool, lookup_name, func)
|
||||
GenApi.update_global_func_typestr(pool, lookup_name, func)
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -13,7 +13,7 @@ import sys
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
|
||||
@@ -13,7 +13,7 @@ import sys
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
|
||||
@@ -12,7 +12,7 @@ import sys
|
||||
import ast
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.Projectrans.Utils as Utils
|
||||
|
||||
@@ -9,12 +9,12 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Generator as Generator
|
||||
import lib.Stub.StubGen.VpiReader as VpiReader
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
# ============================================================
|
||||
# AssignGenMixin - 赋值翻译 Mixin(P6 方法化)
|
||||
@@ -789,9 +789,9 @@ class AssignGenMixin:
|
||||
|
||||
# 1. 确定变量作用域类型: 0=local, 1=global, 2=nonlocal
|
||||
scope_type: int = 0
|
||||
if HT.is_global_name(trans, nm.id) != 0:
|
||||
if GenApi.is_global_name(trans, nm.id) != 0:
|
||||
scope_type = 1
|
||||
elif HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
elif GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
scope_type = 2
|
||||
|
||||
# 2. 加载当前值
|
||||
@@ -999,9 +999,9 @@ class AssignGenMixin:
|
||||
return 0
|
||||
|
||||
# global/nonlocal 变量不需要局部 alloca
|
||||
if HT.is_global_name(trans, nm.id) != 0:
|
||||
if GenApi.is_global_name(trans, nm.id) != 0:
|
||||
return 0
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
return 0
|
||||
|
||||
# 模块级全局变量已由 handle_module_level_var 注册到模块作用域。
|
||||
@@ -1161,7 +1161,7 @@ class AssignGenMixin:
|
||||
self.Gen.CallGenLeafKit.register_func_ptr_sig(nm.id, callable_ret)
|
||||
|
||||
# global 变量:写入模块作用域中的全局变量
|
||||
if HT.is_global_name(trans, nm.id) != 0:
|
||||
if GenApi.is_global_name(trans, nm.id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
if mod_alloca is not None and aa.value is not None:
|
||||
@@ -1178,7 +1178,7 @@ class AssignGenMixin:
|
||||
return 0
|
||||
|
||||
# nonlocal 变量:通过闭包 env 写入
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if aa.value is not None:
|
||||
rhs_val: llvmlite.Value | t.CPtr = self.Gen.ExprGen.translate_value(
|
||||
builder, pool, mod, aa.value,
|
||||
@@ -1821,7 +1821,7 @@ class AssignGenMixin:
|
||||
if nm.id is None:
|
||||
continue
|
||||
# global 变量:写入模块作用域中的全局变量
|
||||
if HT.is_global_name(trans, nm.id) != 0:
|
||||
if GenApi.is_global_name(trans, nm.id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm.id)
|
||||
if mod_alloca is None:
|
||||
@@ -1839,7 +1839,7 @@ class AssignGenMixin:
|
||||
continue
|
||||
|
||||
# nonlocal 变量:通过闭包 env 写入
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
trans, nm.id)
|
||||
if nl_ptr is None:
|
||||
|
||||
+2846
-2848
File diff suppressed because it is too large.
Load diff
@@ -4,7 +4,6 @@ import t, c
|
||||
from stdint import *
|
||||
import memhub
|
||||
import llvmlite
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -12,11 +12,8 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Stub.StubMerger.StubMergerCollect as StubMergerCollect
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
|
||||
@@ -11,14 +11,12 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -259,7 +257,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
if a_node is not None and a_node.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm_set: ast.Name | t.CPtr = (ast.Name | t.CPtr)(a_node)
|
||||
if nm_set.id is not None:
|
||||
if HT.is_global_name(trans, nm_set.id) != 0:
|
||||
if GenApi.is_global_name(trans, nm_set.id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm_set.id)
|
||||
if mod_alloca is not None:
|
||||
@@ -271,7 +269,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
sv = self.Gen.ExprGenBase.coerce_to_type(builder, b_val, tg_ty, a_node)
|
||||
llvmlite.build_store(builder, sv, mod_alloca)
|
||||
return b_val
|
||||
if HT.is_nonlocal_name(trans, nm_set.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm_set.id) != 0:
|
||||
nl_ptr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.get_nonlocal_var_ptr(
|
||||
trans, nm_set.id)
|
||||
if nl_ptr is not None:
|
||||
@@ -357,7 +355,7 @@ class CallGenCBuiltin(CallGenBase.CallGenBase):
|
||||
# 不能 lookup_var 跨函数命中父函数 alloca(SSA 编号错乱崩溃)。
|
||||
# 与普通局部 c.Addr(obj) 返回对象指针(load 一次)语义一致。
|
||||
if trans is not None:
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_addr: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl.load_nonlocal_var(
|
||||
trans, nm.id)
|
||||
if nl_addr is not None:
|
||||
|
||||
@@ -11,15 +11,11 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
import lib.core.Handles.ExprCallTable as ExprCallTable
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -417,7 +413,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
mdf_default_count: int = 0
|
||||
mdf_param_count: int = 0
|
||||
if trans is not None and trans._funcs is not None:
|
||||
mdf_entry: GenTypes.FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table(
|
||||
mdf_entry: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_in_table(
|
||||
trans._funcs, trans._func_count, lookup_name)
|
||||
if mdf_entry is not None:
|
||||
mdf_defaults = mdf_entry.Defaults
|
||||
@@ -1370,7 +1366,7 @@ class CallGenCall(CallGenBase.CallGenBase):
|
||||
mdf_default_count: int = 0
|
||||
mdf_param_count: int = 0
|
||||
if trans is not None and trans._funcs is not None:
|
||||
mdf_entry: GenTypes.FuncEntry | t.CPtr = ExprCallTable.find_func_entry_in_table(
|
||||
mdf_entry: GenTypes.FuncEntry | t.CPtr = self.Gen.CallGenLeafKit.find_func_entry_in_table(
|
||||
trans._funcs, trans._func_count, lookup_name)
|
||||
if mdf_entry is not None:
|
||||
mdf_defaults = mdf_entry.Defaults
|
||||
|
||||
@@ -11,15 +11,11 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
import lib.core.Handles.ExprCallTable as ExprCallTable
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
+1699
-1701
File diff suppressed because it is too large.
Load diff
@@ -11,11 +11,8 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
@@ -11,11 +11,9 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenCBuiltin as CallGenCBuiltin
|
||||
@@ -1293,11 +1291,53 @@ class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
|
||||
|
||||
|
||||
def NewExprCallHandle(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr) -> HandlesExprCall.ExprCallHandle | t.CPtr:
|
||||
h: HandlesExprCall.ExprCallHandle | t.CPtr = pool.alloc(HandlesExprCall.ExprCallHandle.__sizeof__())
|
||||
trans: HT.Translator | t.CPtr) -> ExprCallHandle | t.CPtr:
|
||||
h: ExprCallHandle | t.CPtr = pool.alloc(ExprCallHandle.__sizeof__())
|
||||
if h is None:
|
||||
return None
|
||||
string.memset(h, 0, HandlesExprCall.ExprCallHandle.__sizeof__())
|
||||
string.memset(h, 0, ExprCallHandle.__sizeof__())
|
||||
h.Trans = trans
|
||||
return h
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprCallHandle - 函数调用处理器(自 HandlesExprCall 迁入)
|
||||
#
|
||||
# HandleCall / HandlePrintfCall / HandlePrintCall 提供 trans 接口,
|
||||
# 内部委托 GenApi.translate_call 等。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprCallHandle(HT.Mixin):
|
||||
"""函数调用处理器:继承 Mixin 获得 Trans 回指针"""
|
||||
|
||||
def __init__(self, trans: HT.Translator | t.CPtr):
|
||||
self.Trans = trans
|
||||
|
||||
# ============================================================
|
||||
# HandleCall - 翻译函数调用,返回 call 结果 Value
|
||||
# ============================================================
|
||||
def HandleCall(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译函数调用,从 self.Trans 获取共享状态"""
|
||||
return GenApi.translate_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
node,
|
||||
self.Trans._funcs, self.Trans._func_count, self.Trans)
|
||||
|
||||
# ============================================================
|
||||
# HandlePrintfCall - 翻译 printf 调用
|
||||
# ============================================================
|
||||
def HandlePrintfCall(self, cl: ast.Call | t.CPtr):
|
||||
"""翻译 printf 调用,从 self.Trans 获取共享状态"""
|
||||
GenApi.translate_printf_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
cl, self.Trans)
|
||||
|
||||
# ============================================================
|
||||
# HandlePrintCall - 翻译 print 调用
|
||||
# ============================================================
|
||||
def HandlePrintCall(self, cl: ast.Call | t.CPtr):
|
||||
"""翻译 print 调用(类型感知格式化 + 默认换行)"""
|
||||
GenApi.translate_print_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
cl, self.Trans)
|
||||
|
||||
@@ -10,11 +10,8 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
+1356
-1359
File diff suppressed because it is too large.
Load diff
@@ -11,11 +11,8 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
@@ -10,11 +10,8 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
@@ -13,11 +13,8 @@ import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
@@ -10,7 +10,7 @@ import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import stdio
|
||||
import stdlib
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Gen.Class.ClassGenBase as ClassGenBase
|
||||
|
||||
+1304
-1304
File diff suppressed because it is too large.
Load diff
@@ -10,10 +10,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
import lib.Stub.StubMerger.StubMergerBuild as StubMergerBuild
|
||||
@@ -23,6 +20,7 @@ import lib.Projectrans.Utils as Utils
|
||||
|
||||
|
||||
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
# ============================================================
|
||||
# ExprGenAttr - ExprGenMixin 拆分(阶段 D):Attribute/属性访问/全局引用
|
||||
@@ -721,11 +719,11 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
|
||||
if nm.id is not None:
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
raw_nl_a: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(
|
||||
trans, nm.id)
|
||||
if raw_nl_a is not None:
|
||||
nl_ty_a: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(
|
||||
nl_ty_a: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(
|
||||
trans, nm.id)
|
||||
if nl_ty_a is not None:
|
||||
# 对象即指针:Struct/Array 类型直接用堆地址(bitcast 后
|
||||
@@ -1044,11 +1042,11 @@ class ExprGenAttr(ExprGenBase.ExprGenBase):
|
||||
if at.value.kind() == ast.ASTKind.Name and trans is not None:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(at.value)
|
||||
if nm.id is not None:
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
raw_nl_a: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(
|
||||
trans, nm.id)
|
||||
if raw_nl_a is not None:
|
||||
nl_ty_a: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(
|
||||
nl_ty_a: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(
|
||||
trans, nm.id)
|
||||
if nl_ty_a is not None:
|
||||
# 对象即指针:Struct/Array 类型直接用堆地址(bitcast 后
|
||||
|
||||
@@ -10,10 +10,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -9,10 +9,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -12,10 +12,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -10,10 +10,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -9,10 +9,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -9,10 +9,7 @@ import stdio
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -10,10 +10,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
import lib.core.VLogger as VLogger
|
||||
@@ -22,6 +19,7 @@ import lib.Projectrans.Utils as Utils
|
||||
|
||||
|
||||
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
# ============================================================
|
||||
# ExprGenName - ExprGenMixin 拆分(阶段 D):Name/Subscript/下标访问
|
||||
@@ -157,7 +155,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
|
||||
# global 变量:从模块作用域查找(global 声明优先级最高)
|
||||
if trans is not None:
|
||||
if HT.is_global_name(trans, nm_id) != 0:
|
||||
if GenApi.is_global_name(trans, nm_id) != 0:
|
||||
mod_alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_module_var(
|
||||
trans.SymTab, nm_id)
|
||||
if mod_alloca is not None:
|
||||
@@ -181,7 +179,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
return llvmlite.build_load(builder, load_ty, mod_alloca)
|
||||
|
||||
# nonlocal 变量:通过闭包 env 访问
|
||||
if HT.is_nonlocal_name(trans, nm_id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm_id) != 0:
|
||||
return self.Gen.StmtGenDecl.load_nonlocal_var(trans, nm_id)
|
||||
|
||||
# *args va_list:变量名直接解析为指向 24 字节 va_list 缓冲区的 i8* 地址
|
||||
@@ -587,7 +585,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
"""nonlocal 数组/指针下标:从 env 读堆地址 → bitcast → GEP,返回元素指针"""
|
||||
if trans is None or nm_id is None or idx_val is None:
|
||||
return None
|
||||
nl_ty: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(trans, nm_id)
|
||||
nl_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(trans, nm_id)
|
||||
if nl_ty is None:
|
||||
return None
|
||||
raw_nl: llvmlite.Value | t.CPtr = self.Gen.StmtGenDecl._load_raw_var_ptr(trans, nm_id)
|
||||
@@ -702,7 +700,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
# nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能
|
||||
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
|
||||
# 读路径:元素指针 load 出元素值
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
nl_ptr_r: llvmlite.Value | t.CPtr = self._nonlocal_subscript_ptr(
|
||||
builder, pool, trans, nm.id, idx_val)
|
||||
if nl_ptr_r is not None and nl_ptr_r.Ty is not None:
|
||||
@@ -1002,7 +1000,7 @@ class ExprGenName(ExprGenBase.ExprGenBase):
|
||||
if nm.id is not None and trans is not None:
|
||||
# nonlocal 数组/指针:从 env 读共享堆地址(提升函数内不能
|
||||
# lookup_var 外层 alloca——SSA 编号跨函数错乱崩溃)
|
||||
if HT.is_nonlocal_name(trans, nm.id) != 0:
|
||||
if GenApi.is_nonlocal_name(trans, nm.id) != 0:
|
||||
return self._nonlocal_subscript_ptr(
|
||||
builder, pool, trans, nm.id, idx_val)
|
||||
alloca: llvmlite.Value | t.CPtr = self.Gen.VarGen.lookup_var(trans.SymTab, nm.id)
|
||||
|
||||
@@ -10,10 +10,7 @@ import stdlib
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
|
||||
@@ -8,9 +8,7 @@ import viperlib
|
||||
import stdio
|
||||
import stdlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -10,11 +10,9 @@ import viperlib
|
||||
import stdio
|
||||
import stdlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Handles.ExprCallTable as ExprCallTable
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.Gen.Call.CallGenBase as CallGenBase
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -800,7 +798,7 @@ class FuncGenDef(CallGenBase.CallGenBase):
|
||||
trans._cur_func = func
|
||||
trans._cur_builder = func_builder
|
||||
# 清空 global/nonlocal 名称集合(新函数作用域)
|
||||
HT.clear_scope_names(trans)
|
||||
GenApi.clear_scope_names(trans)
|
||||
# 重置链内 nonlocal 堆预建标志(每函数只建一次;多嵌套函数定义
|
||||
# 共享同一堆,防重复 malloc + 二次重定向 VarEntry)
|
||||
trans._nl_chain_done = 0
|
||||
|
||||
+1563
-1564
File diff suppressed because it is too large.
Load diff
@@ -14,7 +14,7 @@ import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Generator as Generator
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -603,3 +603,84 @@ def translate_print_call(pool: memhub.MemBuddy | t.CPtr, builder: llvmlite.IRBui
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.translate_print_call(pool, builder, mod, cl, trans)
|
||||
|
||||
|
||||
# ---------------- add_global_name(委托 TranslatorGenMixin.add_global_name) ----------------
|
||||
def add_global_name(trans: HT.Translator | t.CPtr, name: str) -> None:
|
||||
"""委托到 gen.TranslatorGen.add_global_name(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.add_global_name(trans, name)
|
||||
|
||||
|
||||
# ---------------- is_global_name(委托 TranslatorGenMixin.is_global_name) ----------------
|
||||
def is_global_name(trans: HT.Translator | t.CPtr, name: str) -> int:
|
||||
"""委托到 gen.TranslatorGen.is_global_name(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.is_global_name(trans, name)
|
||||
return 0
|
||||
|
||||
|
||||
# ---------------- add_nonlocal_name(委托 TranslatorGenMixin.add_nonlocal_name) ----------------
|
||||
def add_nonlocal_name(trans: HT.Translator | t.CPtr, name: str,
|
||||
var_ty: llvmlite.LLVMType | t.CPtr = None) -> None:
|
||||
"""委托到 gen.TranslatorGen.add_nonlocal_name(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.add_nonlocal_name(trans, name, var_ty)
|
||||
|
||||
|
||||
# ---------------- get_nonlocal_type(委托 TranslatorGenMixin.get_nonlocal_type) ----------------
|
||||
def get_nonlocal_type(trans: HT.Translator | t.CPtr,
|
||||
name: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""委托到 gen.TranslatorGen.get_nonlocal_type(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.get_nonlocal_type(trans, name)
|
||||
return None
|
||||
|
||||
|
||||
# ---------------- is_nonlocal_name(委托 TranslatorGenMixin.is_nonlocal_name) ----------------
|
||||
def is_nonlocal_name(trans: HT.Translator | t.CPtr, name: str) -> int:
|
||||
"""委托到 gen.TranslatorGen.is_nonlocal_name(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.is_nonlocal_name(trans, name)
|
||||
return 0
|
||||
|
||||
|
||||
# ---------------- get_nonlocal_index(委托 TranslatorGenMixin.get_nonlocal_index) ----------------
|
||||
def get_nonlocal_index(trans: HT.Translator | t.CPtr, name: str) -> int:
|
||||
"""委托到 gen.TranslatorGen.get_nonlocal_index(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.get_nonlocal_index(trans, name)
|
||||
return 0
|
||||
|
||||
|
||||
# ---------------- clear_scope_names(委托 TranslatorGenMixin.clear_scope_names) ----------------
|
||||
def clear_scope_names(trans: HT.Translator | t.CPtr) -> None:
|
||||
"""委托到 gen.TranslatorGen.clear_scope_names(原 Handles 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.TranslatorGen.clear_scope_names(trans)
|
||||
|
||||
|
||||
# ---------------- update_global_func_typestr(委托 CallGenLeafKit.update_global_func_typestr) ----------------
|
||||
def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
|
||||
name: str,
|
||||
func: llvmlite.Function | t.CPtr) -> int:
|
||||
"""委托到 gen.CallGenLeafKit.update_global_func_typestr(原 ExprCallTable 壳)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.update_global_func_typestr(pool, name, func)
|
||||
return 0
|
||||
@@ -11,7 +11,7 @@ import sys
|
||||
import w32.fileio as fileio
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
|
||||
|
||||
|
||||
+1339
-1339
File diff suppressed because it is too large.
Load diff
@@ -10,9 +10,7 @@ import stdlib
|
||||
import stdio
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Projectrans.Config as Config
|
||||
# ============================================================
|
||||
|
||||
@@ -9,12 +9,11 @@ import stdlib
|
||||
import stdio
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Projectrans.Config as Config
|
||||
import lib.core.Gen.Stmt.StmtGenCifMixin as StmtGenCifMixin
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -56,7 +55,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
if nm_node is not None and nm_node.kind() == ast.ASTKind.Name:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(nm_node)
|
||||
if nm.id is not None:
|
||||
HT.add_global_name(trans, nm.id)
|
||||
GenApi.add_global_name(trans, nm.id)
|
||||
return 0
|
||||
|
||||
def translate_nonlocal(self, trans: HT.Translator | t.CPtr,
|
||||
@@ -92,7 +91,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
self.Gen.TypeGenErr.fatal_error(nm_node, f"nonlocal 变量 '{nm.id}' 类型无效(Void/无法解析)", "TypeError")
|
||||
case _:
|
||||
pass
|
||||
HT.add_nonlocal_name(trans, nm.id, var_ty)
|
||||
GenApi.add_nonlocal_name(trans, nm.id, var_ty)
|
||||
return 0
|
||||
|
||||
def translate_expr_stmt(self, trans: HT.Translator | t.CPtr,
|
||||
@@ -330,7 +329,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
|
||||
返回 i8* 类型的 Value,调用方需 bitcast 为具体类型指针后 load/store。
|
||||
"""
|
||||
idx: int = HT.get_nonlocal_index(trans, name)
|
||||
idx: int = GenApi.get_nonlocal_index(trans, name)
|
||||
if idx < 0:
|
||||
return None
|
||||
|
||||
@@ -374,7 +373,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
|
||||
# 获取变量类型(从注册时存储的类型信息)
|
||||
var_ty: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(trans, name)
|
||||
var_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(trans, name)
|
||||
if var_ty is None or self._is_void_type(var_ty) != 0:
|
||||
# 类型缺失/无效直接报错终止(fail-fast),避免生成 "load void, void*" 非法 IR
|
||||
self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法 load", "TypeError")
|
||||
@@ -400,7 +399,7 @@ class StmtGenDeclMixin(StmtGenCifMixin.StmtGenCifMixin):
|
||||
builder: llvmlite.IRBuilder | t.CPtr = trans._cur_builder
|
||||
|
||||
# 获取变量类型
|
||||
var_ty: llvmlite.LLVMType | t.CPtr = HT.get_nonlocal_type(trans, name)
|
||||
var_ty: llvmlite.LLVMType | t.CPtr = GenApi.get_nonlocal_type(trans, name)
|
||||
if var_ty is None or self._is_void_type(var_ty) != 0:
|
||||
# 类型缺失/无效直接报错终止(fail-fast),避免生成 "bitcast ... to void*" 非法 IR
|
||||
self.Gen.TypeGenErr.fatal_error(None, f"nonlocal 变量 '{name}' 类型缺失,无法 load", "TypeError")
|
||||
|
||||
@@ -11,9 +11,7 @@ import stdlib
|
||||
import stdio
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.Projectrans.Config as Config
|
||||
import lib.core.Gen.Stmt.StmtGenDeclMixin as StmtGenDeclMixin
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -7,7 +7,7 @@ import memhub
|
||||
import string
|
||||
import viperlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
|
||||
|
||||
|
||||
@@ -8,10 +8,7 @@ import viperlib
|
||||
import stdio
|
||||
import stdlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
|
||||
@@ -8,10 +8,7 @@ import viperlib
|
||||
import stdio
|
||||
import stdlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
@@ -322,7 +319,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
# ExprGenMixin 方法,TypeGenMixin 直接调用会生成未定义引用)
|
||||
if (from_imports is not None or imported_modules is not None) \
|
||||
and pool is not None:
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
x_val: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
|
||||
pool, nm.id, from_imports, imported_modules)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
@@ -355,7 +351,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
|
||||
for mi in range(mod_len):
|
||||
fi_buf[2 + mi] = at_mod.id[mi]
|
||||
fi_buf[2 + mod_len] = '\0'
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
av: int = self.Gen.ExprGenCdef._lookup_cross_module_cdefine(
|
||||
pool, at.attr, fi_buf, imported_modules)
|
||||
if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
|
||||
|
||||
+395
-395
@@ -1,396 +1,396 @@
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Generator as Generator
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import viperlib
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
|
||||
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeGenErr - TypeGenMixin 拆分(阶段 D):错误上报/源行读取/类型推断(fatal_error/infer_* 等)
|
||||
#
|
||||
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
"""错误上报/源行读取/类型推断(fatal_error/infer_* 等)"""
|
||||
|
||||
def _read_source_line(self, file_path: str, lineno: int) -> str:
|
||||
"""从源文件读取第 lineno 行内容"""
|
||||
if file_path is None or lineno <= 0:
|
||||
return None
|
||||
f: fileio.File | t.CPtr = fileio.File(file_path, fileio.MODE.R)
|
||||
if f.closed:
|
||||
return None
|
||||
# 按文件实际大小分配缓冲区:固定 256KB 会截断大源文件,末尾行号读不到 →
|
||||
# 误报"文件不存在或行号超出范围"(如 CallGenMixin.vp 555KB/9236 行的第
|
||||
# 8390 行)。64MB 上限防御异常超大文件整体读取。
|
||||
fsize: LONGLONG = f.size()
|
||||
if fsize <= 0 or fsize > 67108864:
|
||||
f.close()
|
||||
return None
|
||||
src_size: t.CSizeT = t.CSizeT(fsize)
|
||||
buf: bytes = stdlib.malloc(src_size + 1)
|
||||
if buf is None:
|
||||
f.close()
|
||||
return None
|
||||
bytes_read: LONG = f.read_all(buf, ULONG(src_size + 1))
|
||||
f.close()
|
||||
if bytes_read <= 0:
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
# 逐行查找第 lineno 行
|
||||
cur_line: int = 1
|
||||
line_start: t.CSizeT = 0
|
||||
for i in range(bytes_read):
|
||||
if buf[i] == '\n':
|
||||
if cur_line == lineno:
|
||||
line_len: t.CSizeT = i - line_start
|
||||
if line_len > 0 and buf[line_start + line_len - 1] == '\r':
|
||||
line_len -= 1
|
||||
line_buf: bytes = stdlib.malloc(line_len + 1)
|
||||
if line_buf is not None:
|
||||
string.strncpy(line_buf, buf + line_start, line_len)
|
||||
line_buf[line_len] = '\0'
|
||||
stdlib.free(buf)
|
||||
return line_buf
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
cur_line += 1
|
||||
line_start = i + 1
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
def read_source_line(self, file_path: str, lineno: int) -> str:
|
||||
"""公开包装:从源文件读取第 lineno 行内容(供 traceback 展示)"""
|
||||
return self._read_source_line(file_path, lineno)
|
||||
def dump_parse_traceback(self, file_path: str) -> None:
|
||||
"""解析失败时以 Python 风格输出 traceback(仿 fatal_error)"""
|
||||
err_line: int = ast.get_parse_err_line()
|
||||
err_col: int = ast.get_parse_err_col()
|
||||
err_msg: str = ast.get_parse_err_msg()
|
||||
stdio.printf("Traceback (most recent call last):\n")
|
||||
if file_path is None or file_path[0] == 0:
|
||||
file_path = "<unknown>"
|
||||
if err_line > 0:
|
||||
stdio.printf(' File "%s", line %d\n', file_path, err_line)
|
||||
src: str = self._read_source_line(file_path, err_line)
|
||||
if src is not None:
|
||||
stdio.printf(" %s\n", src)
|
||||
# 列标记:在出错 token 起始列下方标 ^(parser 的 col_offset 是 0-based,
|
||||
# 前缀 4 空格 + err_col 个空格后落点恰好是该 token 首字符)
|
||||
if err_col > 0:
|
||||
stdio.printf(" ")
|
||||
c: int
|
||||
for c in range(err_col):
|
||||
stdio.printf(" ")
|
||||
stdio.printf("^\n")
|
||||
stdlib.free(src)
|
||||
else:
|
||||
stdio.printf(' File "%s"\n', file_path)
|
||||
if err_msg is None or err_msg[0] == 0:
|
||||
err_msg = "语法错误"
|
||||
stdio.printf("SyntaxError: %s\n", err_msg)
|
||||
def fatal_error(self, node: ast.AST | t.CPtr, msg: str,
|
||||
err_type: str = "SyntaxError",
|
||||
col_start: int = 0, col_end: int = 0):
|
||||
"""以 Python 风格报错并退出(支持多帧、错误类型、列范围)
|
||||
|
||||
向后兼容:err_type/col_start/col_end 有默认值,旧调用 fatal_error(node, msg) 仍可用。
|
||||
"""
|
||||
stdio.printf("Traceback (most recent call last):\n")
|
||||
# 输出调用栈帧(从底到顶)
|
||||
i: int
|
||||
for i in range(self.Gen.TypeGenBase.TraceCount):
|
||||
frame: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(i)
|
||||
if frame is not None and frame.file_name is not None:
|
||||
if frame.lineno > 0:
|
||||
stdio.printf(' File "%s", line %d\n', frame.file_name, frame.lineno)
|
||||
src: str = self._read_source_line(frame.file_name, frame.lineno)
|
||||
if src is not None:
|
||||
stdio.printf(" %s\n", src)
|
||||
stdlib.free(src)
|
||||
else:
|
||||
stdio.printf(' File "%s"\n', frame.file_name)
|
||||
# 输出当前帧(node 对应的位置)
|
||||
lineno: int = 0
|
||||
if node is not None:
|
||||
lineno = node.lineno
|
||||
file_name: str = self.Gen.TypeGenResolve.get_current_file()
|
||||
if file_name is None:
|
||||
file_name = "<unknown>"
|
||||
# 行号兜底:克隆/构造节点 lineno 可能为 0(如泛型特化 _clone_arguments 的
|
||||
# ast.Arg 构造器硬编码 0,astaux.vp L139)。此时回退到 trace 栈最后一个
|
||||
# 有效帧(文件+行号)作为出错位置,避免输出误导性的 "line 0"。
|
||||
if lineno <= 0 and self.Gen.TypeGenBase.TraceCount > 0:
|
||||
ti_b: int = self.Gen.TypeGenBase.TraceCount - 1
|
||||
while ti_b >= 0:
|
||||
tfb: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(ti_b)
|
||||
if tfb is not None and tfb.file_name is not None and tfb.lineno > 0:
|
||||
file_name = tfb.file_name
|
||||
lineno = tfb.lineno
|
||||
break
|
||||
ti_b -= 1
|
||||
# 行号合理性防御:先读取该行源码,验证 node.lineno 是否落在当前文件内。
|
||||
# 若读不到(文件不存在或行号超出范围),说明文件/行号归属不可信
|
||||
# (如 AST 树被内存复用/串扰后跨文件报错),打印警告而非误导性行号。
|
||||
src_line: str = None
|
||||
line_ok: int = 1
|
||||
if lineno > 0 and string.strcmp(file_name, "<unknown>") != 0:
|
||||
src_line = self._read_source_line(file_name, lineno)
|
||||
if src_line is None:
|
||||
line_ok = 0
|
||||
if line_ok == 0:
|
||||
stdio.printf(' File "%s", line %d (!! 无法读取该行源码:文件不存在或行号超出范围,错误可能来自被复用的 AST 树,请以错误消息为准)\n',
|
||||
file_name, lineno)
|
||||
else:
|
||||
stdio.printf(' File "%s", line %d\n', file_name, lineno)
|
||||
if src_line is not None:
|
||||
stdio.printf(" %s\n", src_line)
|
||||
# 列范围标记:在源代码行下方用 ^ 标记出错范围
|
||||
if col_start > 0 and col_end >= col_start:
|
||||
stdio.printf(" ")
|
||||
j: int
|
||||
for j in range(col_end):
|
||||
if j >= col_start - 1 and j < col_end:
|
||||
stdio.printf("^")
|
||||
else:
|
||||
stdio.printf(" ")
|
||||
stdio.printf("\n")
|
||||
stdlib.free(src_line)
|
||||
# 输出错误类型 + 消息
|
||||
if err_type is None or err_type[0] == 0:
|
||||
err_type = "SyntaxError"
|
||||
stdio.printf("%s: %s\n", err_type, msg)
|
||||
sys.exit(1)
|
||||
|
||||
def fatal_type_error(self, node: ast.AST | t.CPtr, msg: str,
|
||||
col_start: int = 0, col_end: int = 0):
|
||||
"""以 Python 风格报错并退出(TypeError 版本)"""
|
||||
self.fatal_error(node, msg, "TypeError", col_start, col_end)
|
||||
def try_extract_callable_ret(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
annot: ast.AST | t.CPtr,
|
||||
imported_modules: str,
|
||||
from_imports: str,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""提取 t.Callable 注解的返回类型 LLVMType;非 Callable 注解返回 None"""
|
||||
if annot is None or annot.kind() != ast.ASTKind.Subscript:
|
||||
return None
|
||||
sub_cr: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(annot)
|
||||
if sub_cr.value is None or sub_cr.value.kind() != ast.ASTKind.Attribute:
|
||||
return None
|
||||
at_cr: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(sub_cr.value)
|
||||
if at_cr.attr is None or string.strcmp(at_cr.attr, "Callable") != 0:
|
||||
return None
|
||||
# slice 必须是 Tuple(elts=[args_list, ret_node])
|
||||
if sub_cr.slice is None or sub_cr.slice.kind() != ast.ASTKind.Tuple:
|
||||
return None
|
||||
tp_cr: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub_cr.slice)
|
||||
if tp_cr.elts is None or len(tp_cr.elts) != 2:
|
||||
return None
|
||||
ret_node_cr: ast.AST | t.CPtr = tp_cr.elts.get(1)
|
||||
if ret_node_cr is None:
|
||||
return None
|
||||
return self.Gen.TypeGenResolve.resolve_annotation_type(pool, ret_node_cr, imported_modules, from_imports, trans, 0)
|
||||
def has_decorator_marker(self, node: ast.AST | t.CPtr,
|
||||
marker_name: str,
|
||||
depth: int = 0) -> int:
|
||||
"""检测类型注解中是否包含指定的装饰器标记"""
|
||||
if node is None or marker_name is None:
|
||||
return 0
|
||||
# 递归深度守卫:vpi stub 注入时对每个函数 returns 调用本函数,
|
||||
# vpi tree 深层节点可能被覆盖损坏成回指环(VpiReader L810-813),
|
||||
# BinOp 递归无守卫会无限递归直至栈耗尽。fail-fast 终止。
|
||||
if depth > 128:
|
||||
self.fatal_type_error(node, "装饰器标记检测递归过深(AST 环或嵌套超过 128 层)")
|
||||
|
||||
k: int = node.kind()
|
||||
|
||||
# Attribute 节点: t.CExtern, t.State, t.CExport, t.CInline
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
|
||||
if at.attr is not None:
|
||||
if string.strcmp(at.attr, marker_name) == 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
# BinOp 节点: int | t.CExtern(递归检测左右子节点)
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
if self.has_decorator_marker(bop.left, marker_name, depth + 1) != 0:
|
||||
return 1
|
||||
if self.has_decorator_marker(bop.right, marker_name, depth + 1) != 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
return 0
|
||||
def is_pass_body(self, body: list[ast.AST | t.CPtr] | t.CPtr) -> int:
|
||||
"""检测函数体是否为 pass(空体或仅含 pass 语句)"""
|
||||
if body is None:
|
||||
return 1
|
||||
bn: t.CSizeT = len(body)
|
||||
if bn == 0:
|
||||
return 1
|
||||
if bn == 1:
|
||||
stmt: ast.AST | t.CPtr = body.get(0)
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Pass:
|
||||
return 1
|
||||
return 0
|
||||
def get_llvm_type_bits(self, ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""获取 LLVM 整数类型的位宽,非整数类型返回 0"""
|
||||
if ty is None:
|
||||
return 0
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Int(bits):
|
||||
return bits
|
||||
case _:
|
||||
return 0
|
||||
def infer_expr_type(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
param_types: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""推断表达式的 LLVM 类型
|
||||
|
||||
param_types 格式: "name:bits,name:bits,..."
|
||||
"""
|
||||
if node is None:
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
k: int = node.kind()
|
||||
|
||||
if k == ast.ASTKind.Constant:
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
elif k == ast.ASTKind.Name:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
|
||||
if nm.id is not None and param_types is not None:
|
||||
# 在 param_types 中查找: "name:bits" 格式
|
||||
search_key: str = pool.alloc(64)
|
||||
if search_key is not None:
|
||||
viperlib.snprintf(search_key, 64, "%s:", nm.id)
|
||||
found: str = string.strstr(param_types, search_key)
|
||||
if found is not None:
|
||||
colon_pos: t.CSizeT = string.strlen(nm.id) + 1
|
||||
bits_str: str = found + colon_pos
|
||||
bits: int = 0
|
||||
for bi in range(4):
|
||||
ch: t.CChar = bits_str[bi]
|
||||
if ch >= '0' and ch <= '9':
|
||||
bits = bits * 10 + (ch - '0')
|
||||
else:
|
||||
break
|
||||
if bits == 64:
|
||||
return llvmlite.Int64(pool)
|
||||
elif bits == 16:
|
||||
return llvmlite.Int16(pool)
|
||||
elif bits == 8:
|
||||
return llvmlite.Int8(pool)
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
elif k == ast.ASTKind.BinOp:
|
||||
binop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
lhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
|
||||
pool, binop.left, param_types)
|
||||
rhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
|
||||
pool, binop.right, param_types)
|
||||
lhs_bits: int = self.get_llvm_type_bits(lhs_ty)
|
||||
rhs_bits: int = self.get_llvm_type_bits(rhs_ty)
|
||||
if lhs_bits >= rhs_bits:
|
||||
return lhs_ty
|
||||
return rhs_ty
|
||||
|
||||
return llvmlite.Int32(pool)
|
||||
def infer_return_type(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
body: list[ast.AST | t.CPtr] | t.CPtr,
|
||||
param_types: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""扫描函数体中的 return 语句,推断返回类型"""
|
||||
if body is None:
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
||||
bn: t.CSizeT = len(body)
|
||||
for bi in range(bn):
|
||||
stmt: ast.AST | t.CPtr = body.get(bi)
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
|
||||
rt: ast.Return | t.CPtr = (ast.Return | t.CPtr)(stmt)
|
||||
if rt.value is not None:
|
||||
expr_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
|
||||
pool, rt.value, param_types)
|
||||
if expr_ty is not None:
|
||||
cur_bits: int = self.get_llvm_type_bits(ret_ty)
|
||||
new_bits: int = self.get_llvm_type_bits(expr_ty)
|
||||
if new_bits > cur_bits:
|
||||
ret_ty = expr_ty
|
||||
return ret_ty
|
||||
def build_param_types_str(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
args_node: ast.AST | t.CPtr) -> str:
|
||||
"""构建参数类型编码字符串 "name:bits,name:bits,..." """
|
||||
if args_node is None:
|
||||
return None
|
||||
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
|
||||
if ags.args is None:
|
||||
return None
|
||||
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
|
||||
an: t.CSizeT = len(alist)
|
||||
if an == 0:
|
||||
return None
|
||||
|
||||
buf_size: t.CSizeT = an * 32 + 1
|
||||
buf: str = pool.alloc(buf_size)
|
||||
if buf is None:
|
||||
return None
|
||||
buf[0] = '\0'
|
||||
|
||||
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
||||
for ai in range(an):
|
||||
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
|
||||
if arg is not None and arg.arg is not None:
|
||||
param_ty: llvmlite.LLVMType | t.CPtr = i32_ty
|
||||
if arg.annotation is not None:
|
||||
# 直接调用 map_t_type 解析 Attribute 注解
|
||||
if arg.annotation.kind() == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation)
|
||||
if at.attr is not None:
|
||||
resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, at.attr)
|
||||
if resolved is not None:
|
||||
param_ty = resolved
|
||||
bits: int = self.get_llvm_type_bits(param_ty)
|
||||
if bits == 0:
|
||||
bits = 32
|
||||
tmp: str = pool.alloc(32)
|
||||
if tmp is not None:
|
||||
viperlib.snprintf(tmp, 32, "%s:%d", arg.arg, bits)
|
||||
if ai > 0:
|
||||
self._strappend(buf, buf_size, ",")
|
||||
self._strappend(buf, buf_size, tmp)
|
||||
return buf
|
||||
def _strappend(self, dst: str, dst_size: t.CSizeT, src: str):
|
||||
"""将 src 追加到 dst 末尾"""
|
||||
if dst is None or src is None:
|
||||
return
|
||||
dlen: t.CSizeT = string.strlen(dst)
|
||||
slen: t.CSizeT = string.strlen(src)
|
||||
remain: t.CSizeT = dst_size - dlen
|
||||
if remain <= 0:
|
||||
return
|
||||
# 内联 min(slen, remain - 1) 避免 builtin min 未定义(TransPyV 无 builtin min)
|
||||
limit: t.CSizeT = slen
|
||||
cap: t.CSizeT = remain - 1
|
||||
if cap < limit:
|
||||
limit = cap
|
||||
for i in range(limit):
|
||||
dst[dlen + i] = src[i]
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Generator as Generator
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import viperlib
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.Gen.Translator as HT
|
||||
|
||||
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeGenErr - TypeGenMixin 拆分(阶段 D):错误上报/源行读取/类型推断(fatal_error/infer_* 等)
|
||||
#
|
||||
# 继承 TypeGenBase(1 级,TPV self 调用仅支持 1 级父类)。
|
||||
# 跨 Mixin 调用统一走 HandlesType 委托(经 _g_gen)。
|
||||
# @t.NoVTable:静态绑定。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeGenErr(TypeGenBase.TypeGenBase):
|
||||
"""错误上报/源行读取/类型推断(fatal_error/infer_* 等)"""
|
||||
|
||||
def _read_source_line(self, file_path: str, lineno: int) -> str:
|
||||
"""从源文件读取第 lineno 行内容"""
|
||||
if file_path is None or lineno <= 0:
|
||||
return None
|
||||
f: fileio.File | t.CPtr = fileio.File(file_path, fileio.MODE.R)
|
||||
if f.closed:
|
||||
return None
|
||||
# 按文件实际大小分配缓冲区:固定 256KB 会截断大源文件,末尾行号读不到 →
|
||||
# 误报"文件不存在或行号超出范围"(如 CallGenMixin.vp 555KB/9236 行的第
|
||||
# 8390 行)。64MB 上限防御异常超大文件整体读取。
|
||||
fsize: LONGLONG = f.size()
|
||||
if fsize <= 0 or fsize > 67108864:
|
||||
f.close()
|
||||
return None
|
||||
src_size: t.CSizeT = t.CSizeT(fsize)
|
||||
buf: bytes = stdlib.malloc(src_size + 1)
|
||||
if buf is None:
|
||||
f.close()
|
||||
return None
|
||||
bytes_read: LONG = f.read_all(buf, ULONG(src_size + 1))
|
||||
f.close()
|
||||
if bytes_read <= 0:
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
# 逐行查找第 lineno 行
|
||||
cur_line: int = 1
|
||||
line_start: t.CSizeT = 0
|
||||
for i in range(bytes_read):
|
||||
if buf[i] == '\n':
|
||||
if cur_line == lineno:
|
||||
line_len: t.CSizeT = i - line_start
|
||||
if line_len > 0 and buf[line_start + line_len - 1] == '\r':
|
||||
line_len -= 1
|
||||
line_buf: bytes = stdlib.malloc(line_len + 1)
|
||||
if line_buf is not None:
|
||||
string.strncpy(line_buf, buf + line_start, line_len)
|
||||
line_buf[line_len] = '\0'
|
||||
stdlib.free(buf)
|
||||
return line_buf
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
cur_line += 1
|
||||
line_start = i + 1
|
||||
stdlib.free(buf)
|
||||
return None
|
||||
def read_source_line(self, file_path: str, lineno: int) -> str:
|
||||
"""公开包装:从源文件读取第 lineno 行内容(供 traceback 展示)"""
|
||||
return self._read_source_line(file_path, lineno)
|
||||
def dump_parse_traceback(self, file_path: str) -> None:
|
||||
"""解析失败时以 Python 风格输出 traceback(仿 fatal_error)"""
|
||||
err_line: int = ast.get_parse_err_line()
|
||||
err_col: int = ast.get_parse_err_col()
|
||||
err_msg: str = ast.get_parse_err_msg()
|
||||
stdio.printf("Traceback (most recent call last):\n")
|
||||
if file_path is None or file_path[0] == 0:
|
||||
file_path = "<unknown>"
|
||||
if err_line > 0:
|
||||
stdio.printf(' File "%s", line %d\n', file_path, err_line)
|
||||
src: str = self._read_source_line(file_path, err_line)
|
||||
if src is not None:
|
||||
stdio.printf(" %s\n", src)
|
||||
# 列标记:在出错 token 起始列下方标 ^(parser 的 col_offset 是 0-based,
|
||||
# 前缀 4 空格 + err_col 个空格后落点恰好是该 token 首字符)
|
||||
if err_col > 0:
|
||||
stdio.printf(" ")
|
||||
c: int
|
||||
for c in range(err_col):
|
||||
stdio.printf(" ")
|
||||
stdio.printf("^\n")
|
||||
stdlib.free(src)
|
||||
else:
|
||||
stdio.printf(' File "%s"\n', file_path)
|
||||
if err_msg is None or err_msg[0] == 0:
|
||||
err_msg = "语法错误"
|
||||
stdio.printf("SyntaxError: %s\n", err_msg)
|
||||
def fatal_error(self, node: ast.AST | t.CPtr, msg: str,
|
||||
err_type: str = "SyntaxError",
|
||||
col_start: int = 0, col_end: int = 0):
|
||||
"""以 Python 风格报错并退出(支持多帧、错误类型、列范围)
|
||||
|
||||
向后兼容:err_type/col_start/col_end 有默认值,旧调用 fatal_error(node, msg) 仍可用。
|
||||
"""
|
||||
stdio.printf("Traceback (most recent call last):\n")
|
||||
# 输出调用栈帧(从底到顶)
|
||||
i: int
|
||||
for i in range(self.Gen.TypeGenBase.TraceCount):
|
||||
frame: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(i)
|
||||
if frame is not None and frame.file_name is not None:
|
||||
if frame.lineno > 0:
|
||||
stdio.printf(' File "%s", line %d\n', frame.file_name, frame.lineno)
|
||||
src: str = self._read_source_line(frame.file_name, frame.lineno)
|
||||
if src is not None:
|
||||
stdio.printf(" %s\n", src)
|
||||
stdlib.free(src)
|
||||
else:
|
||||
stdio.printf(' File "%s"\n', frame.file_name)
|
||||
# 输出当前帧(node 对应的位置)
|
||||
lineno: int = 0
|
||||
if node is not None:
|
||||
lineno = node.lineno
|
||||
file_name: str = self.Gen.TypeGenResolve.get_current_file()
|
||||
if file_name is None:
|
||||
file_name = "<unknown>"
|
||||
# 行号兜底:克隆/构造节点 lineno 可能为 0(如泛型特化 _clone_arguments 的
|
||||
# ast.Arg 构造器硬编码 0,astaux.vp L139)。此时回退到 trace 栈最后一个
|
||||
# 有效帧(文件+行号)作为出错位置,避免输出误导性的 "line 0"。
|
||||
if lineno <= 0 and self.Gen.TypeGenBase.TraceCount > 0:
|
||||
ti_b: int = self.Gen.TypeGenBase.TraceCount - 1
|
||||
while ti_b >= 0:
|
||||
tfb: GenTypes.TraceFrame | t.CPtr = self.Gen.TypeGenBase._get_trace_frame(ti_b)
|
||||
if tfb is not None and tfb.file_name is not None and tfb.lineno > 0:
|
||||
file_name = tfb.file_name
|
||||
lineno = tfb.lineno
|
||||
break
|
||||
ti_b -= 1
|
||||
# 行号合理性防御:先读取该行源码,验证 node.lineno 是否落在当前文件内。
|
||||
# 若读不到(文件不存在或行号超出范围),说明文件/行号归属不可信
|
||||
# (如 AST 树被内存复用/串扰后跨文件报错),打印警告而非误导性行号。
|
||||
src_line: str = None
|
||||
line_ok: int = 1
|
||||
if lineno > 0 and string.strcmp(file_name, "<unknown>") != 0:
|
||||
src_line = self._read_source_line(file_name, lineno)
|
||||
if src_line is None:
|
||||
line_ok = 0
|
||||
if line_ok == 0:
|
||||
stdio.printf(' File "%s", line %d (!! 无法读取该行源码:文件不存在或行号超出范围,错误可能来自被复用的 AST 树,请以错误消息为准)\n',
|
||||
file_name, lineno)
|
||||
else:
|
||||
stdio.printf(' File "%s", line %d\n', file_name, lineno)
|
||||
if src_line is not None:
|
||||
stdio.printf(" %s\n", src_line)
|
||||
# 列范围标记:在源代码行下方用 ^ 标记出错范围
|
||||
if col_start > 0 and col_end >= col_start:
|
||||
stdio.printf(" ")
|
||||
j: int
|
||||
for j in range(col_end):
|
||||
if j >= col_start - 1 and j < col_end:
|
||||
stdio.printf("^")
|
||||
else:
|
||||
stdio.printf(" ")
|
||||
stdio.printf("\n")
|
||||
stdlib.free(src_line)
|
||||
# 输出错误类型 + 消息
|
||||
if err_type is None or err_type[0] == 0:
|
||||
err_type = "SyntaxError"
|
||||
stdio.printf("%s: %s\n", err_type, msg)
|
||||
sys.exit(1)
|
||||
|
||||
def fatal_type_error(self, node: ast.AST | t.CPtr, msg: str,
|
||||
col_start: int = 0, col_end: int = 0):
|
||||
"""以 Python 风格报错并退出(TypeError 版本)"""
|
||||
self.fatal_error(node, msg, "TypeError", col_start, col_end)
|
||||
def try_extract_callable_ret(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
annot: ast.AST | t.CPtr,
|
||||
imported_modules: str,
|
||||
from_imports: str,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""提取 t.Callable 注解的返回类型 LLVMType;非 Callable 注解返回 None"""
|
||||
if annot is None or annot.kind() != ast.ASTKind.Subscript:
|
||||
return None
|
||||
sub_cr: ast.Subscript | t.CPtr = (ast.Subscript | t.CPtr)(annot)
|
||||
if sub_cr.value is None or sub_cr.value.kind() != ast.ASTKind.Attribute:
|
||||
return None
|
||||
at_cr: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(sub_cr.value)
|
||||
if at_cr.attr is None or string.strcmp(at_cr.attr, "Callable") != 0:
|
||||
return None
|
||||
# slice 必须是 Tuple(elts=[args_list, ret_node])
|
||||
if sub_cr.slice is None or sub_cr.slice.kind() != ast.ASTKind.Tuple:
|
||||
return None
|
||||
tp_cr: ast.Tuple | t.CPtr = (ast.Tuple | t.CPtr)(sub_cr.slice)
|
||||
if tp_cr.elts is None or len(tp_cr.elts) != 2:
|
||||
return None
|
||||
ret_node_cr: ast.AST | t.CPtr = tp_cr.elts.get(1)
|
||||
if ret_node_cr is None:
|
||||
return None
|
||||
return self.Gen.TypeGenResolve.resolve_annotation_type(pool, ret_node_cr, imported_modules, from_imports, trans, 0)
|
||||
def has_decorator_marker(self, node: ast.AST | t.CPtr,
|
||||
marker_name: str,
|
||||
depth: int = 0) -> int:
|
||||
"""检测类型注解中是否包含指定的装饰器标记"""
|
||||
if node is None or marker_name is None:
|
||||
return 0
|
||||
# 递归深度守卫:vpi stub 注入时对每个函数 returns 调用本函数,
|
||||
# vpi tree 深层节点可能被覆盖损坏成回指环(VpiReader L810-813),
|
||||
# BinOp 递归无守卫会无限递归直至栈耗尽。fail-fast 终止。
|
||||
if depth > 128:
|
||||
self.fatal_type_error(node, "装饰器标记检测递归过深(AST 环或嵌套超过 128 层)")
|
||||
|
||||
k: int = node.kind()
|
||||
|
||||
# Attribute 节点: t.CExtern, t.State, t.CExport, t.CInline
|
||||
if k == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(node)
|
||||
if at.attr is not None:
|
||||
if string.strcmp(at.attr, marker_name) == 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
# BinOp 节点: int | t.CExtern(递归检测左右子节点)
|
||||
if k == ast.ASTKind.BinOp:
|
||||
bop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
if self.has_decorator_marker(bop.left, marker_name, depth + 1) != 0:
|
||||
return 1
|
||||
if self.has_decorator_marker(bop.right, marker_name, depth + 1) != 0:
|
||||
return 1
|
||||
return 0
|
||||
|
||||
return 0
|
||||
def is_pass_body(self, body: list[ast.AST | t.CPtr] | t.CPtr) -> int:
|
||||
"""检测函数体是否为 pass(空体或仅含 pass 语句)"""
|
||||
if body is None:
|
||||
return 1
|
||||
bn: t.CSizeT = len(body)
|
||||
if bn == 0:
|
||||
return 1
|
||||
if bn == 1:
|
||||
stmt: ast.AST | t.CPtr = body.get(0)
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Pass:
|
||||
return 1
|
||||
return 0
|
||||
def get_llvm_type_bits(self, ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""获取 LLVM 整数类型的位宽,非整数类型返回 0"""
|
||||
if ty is None:
|
||||
return 0
|
||||
match ty:
|
||||
case llvmlite.LLVMType.Int(bits):
|
||||
return bits
|
||||
case _:
|
||||
return 0
|
||||
def infer_expr_type(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
param_types: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""推断表达式的 LLVM 类型
|
||||
|
||||
param_types 格式: "name:bits,name:bits,..."
|
||||
"""
|
||||
if node is None:
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
k: int = node.kind()
|
||||
|
||||
if k == ast.ASTKind.Constant:
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
elif k == ast.ASTKind.Name:
|
||||
nm: ast.Name | t.CPtr = (ast.Name | t.CPtr)(node)
|
||||
if nm.id is not None and param_types is not None:
|
||||
# 在 param_types 中查找: "name:bits" 格式
|
||||
search_key: str = pool.alloc(64)
|
||||
if search_key is not None:
|
||||
viperlib.snprintf(search_key, 64, "%s:", nm.id)
|
||||
found: str = string.strstr(param_types, search_key)
|
||||
if found is not None:
|
||||
colon_pos: t.CSizeT = string.strlen(nm.id) + 1
|
||||
bits_str: str = found + colon_pos
|
||||
bits: int = 0
|
||||
for bi in range(4):
|
||||
ch: t.CChar = bits_str[bi]
|
||||
if ch >= '0' and ch <= '9':
|
||||
bits = bits * 10 + (ch - '0')
|
||||
else:
|
||||
break
|
||||
if bits == 64:
|
||||
return llvmlite.Int64(pool)
|
||||
elif bits == 16:
|
||||
return llvmlite.Int16(pool)
|
||||
elif bits == 8:
|
||||
return llvmlite.Int8(pool)
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
elif k == ast.ASTKind.BinOp:
|
||||
binop: ast.BinOp | t.CPtr = (ast.BinOp | t.CPtr)(node)
|
||||
lhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
|
||||
pool, binop.left, param_types)
|
||||
rhs_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
|
||||
pool, binop.right, param_types)
|
||||
lhs_bits: int = self.get_llvm_type_bits(lhs_ty)
|
||||
rhs_bits: int = self.get_llvm_type_bits(rhs_ty)
|
||||
if lhs_bits >= rhs_bits:
|
||||
return lhs_ty
|
||||
return rhs_ty
|
||||
|
||||
return llvmlite.Int32(pool)
|
||||
def infer_return_type(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
body: list[ast.AST | t.CPtr] | t.CPtr,
|
||||
param_types: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""扫描函数体中的 return 语句,推断返回类型"""
|
||||
if body is None:
|
||||
return llvmlite.Int32(pool)
|
||||
|
||||
ret_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
||||
bn: t.CSizeT = len(body)
|
||||
for bi in range(bn):
|
||||
stmt: ast.AST | t.CPtr = body.get(bi)
|
||||
if stmt is not None and stmt.kind() == ast.ASTKind.Return:
|
||||
rt: ast.Return | t.CPtr = (ast.Return | t.CPtr)(stmt)
|
||||
if rt.value is not None:
|
||||
expr_ty: llvmlite.LLVMType | t.CPtr = self.infer_expr_type(
|
||||
pool, rt.value, param_types)
|
||||
if expr_ty is not None:
|
||||
cur_bits: int = self.get_llvm_type_bits(ret_ty)
|
||||
new_bits: int = self.get_llvm_type_bits(expr_ty)
|
||||
if new_bits > cur_bits:
|
||||
ret_ty = expr_ty
|
||||
return ret_ty
|
||||
def build_param_types_str(self, pool: memhub.MemBuddy | t.CPtr,
|
||||
args_node: ast.AST | t.CPtr) -> str:
|
||||
"""构建参数类型编码字符串 "name:bits,name:bits,..." """
|
||||
if args_node is None:
|
||||
return None
|
||||
ags: ast.Arguments | t.CPtr = (ast.Arguments | t.CPtr)(args_node)
|
||||
if ags.args is None:
|
||||
return None
|
||||
alist: list[ast.AST | t.CPtr] | t.CPtr = ags.args
|
||||
an: t.CSizeT = len(alist)
|
||||
if an == 0:
|
||||
return None
|
||||
|
||||
buf_size: t.CSizeT = an * 32 + 1
|
||||
buf: str = pool.alloc(buf_size)
|
||||
if buf is None:
|
||||
return None
|
||||
buf[0] = '\0'
|
||||
|
||||
i32_ty: llvmlite.LLVMType | t.CPtr = llvmlite.Int32(pool)
|
||||
for ai in range(an):
|
||||
arg: ast.Arg | t.CPtr = (ast.Arg | t.CPtr)(alist.get(ai))
|
||||
if arg is not None and arg.arg is not None:
|
||||
param_ty: llvmlite.LLVMType | t.CPtr = i32_ty
|
||||
if arg.annotation is not None:
|
||||
# 直接调用 map_t_type 解析 Attribute 注解
|
||||
if arg.annotation.kind() == ast.ASTKind.Attribute:
|
||||
at: ast.Attribute | t.CPtr = (ast.Attribute | t.CPtr)(arg.annotation)
|
||||
if at.attr is not None:
|
||||
resolved: llvmlite.LLVMType | t.CPtr = self.Gen.TypeGenResolve.map_t_type(pool, at.attr)
|
||||
if resolved is not None:
|
||||
param_ty = resolved
|
||||
bits: int = self.get_llvm_type_bits(param_ty)
|
||||
if bits == 0:
|
||||
bits = 32
|
||||
tmp: str = pool.alloc(32)
|
||||
if tmp is not None:
|
||||
viperlib.snprintf(tmp, 32, "%s:%d", arg.arg, bits)
|
||||
if ai > 0:
|
||||
self._strappend(buf, buf_size, ",")
|
||||
self._strappend(buf, buf_size, tmp)
|
||||
return buf
|
||||
def _strappend(self, dst: str, dst_size: t.CSizeT, src: str):
|
||||
"""将 src 追加到 dst 末尾"""
|
||||
if dst is None or src is None:
|
||||
return
|
||||
dlen: t.CSizeT = string.strlen(dst)
|
||||
slen: t.CSizeT = string.strlen(src)
|
||||
remain: t.CSizeT = dst_size - dlen
|
||||
if remain <= 0:
|
||||
return
|
||||
# 内联 min(slen, remain - 1) 避免 builtin min 未定义(TransPyV 无 builtin min)
|
||||
limit: t.CSizeT = slen
|
||||
cap: t.CSizeT = remain - 1
|
||||
if cap < limit:
|
||||
limit = cap
|
||||
for i in range(limit):
|
||||
dst[dlen + i] = src[i]
|
||||
dst[dlen + i] = '\0' # i 退出值存疑
|
||||
@@ -11,7 +11,7 @@ import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.core.Gen.Type.TypeGenBase as TypeGenBase
|
||||
|
||||
|
||||
|
||||
@@ -11,10 +11,7 @@ import string
|
||||
import viperlib
|
||||
import stdlib
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HT
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
|
||||
import lib.core.CompilerFactory as CompilerFactory
|
||||
|
||||
@@ -1,197 +0,0 @@
|
||||
import lib.core.Gen.GenTypes as GenTypes
|
||||
import lib.core.Gen.Call.CallGenLeafKit as CallGenLeafKit
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
|
||||
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
|
||||
# ============================================================
|
||||
# ExprCallTable - HandlesExprCall 拆分(阶段 E):ExprCallTable
|
||||
#
|
||||
# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅
|
||||
# 保留 _g_gen/常量/类;调用方经本模块前缀访问。
|
||||
# ============================================================
|
||||
|
||||
# ============================================================
|
||||
# 初始化函数表
|
||||
# ============================================================
|
||||
def init_func_table(pool: memhub.MemBuddy | t.CPtr,
|
||||
max_count: int) -> GenTypes.FuncEntry | t.CPtr:
|
||||
"""分配并清零函数表数组(委托到 gen.init_func_table)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.init_func_table(pool, max_count)
|
||||
return None
|
||||
# ============================================================
|
||||
# 查找函数
|
||||
# ============================================================
|
||||
def find_func_in_table(funcs: GenTypes.FuncEntry | t.CPtr,
|
||||
func_count: int,
|
||||
name: str) -> llvmlite.Function | t.CPtr:
|
||||
"""在函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_in_table)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.find_func_in_table(funcs, func_count, name)
|
||||
return None
|
||||
# ============================================================
|
||||
# 添加函数到函数表
|
||||
# ============================================================
|
||||
def add_func_to_table(funcs: GenTypes.FuncEntry | t.CPtr,
|
||||
func_count: int,
|
||||
name: str,
|
||||
func: llvmlite.Function | t.CPtr,
|
||||
max_count: int,
|
||||
defaults: t.CVoid | t.CPtr = None,
|
||||
default_count: int = 0,
|
||||
param_count: int = 0,
|
||||
pool: memhub.MemBuddy | t.CPtr = None) -> int:
|
||||
"""添加函数到函数表,返回 0 成功(委托到 gen.add_func_to_table)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.add_func_to_table(funcs, func_count, name, func, max_count,
|
||||
defaults, default_count, param_count, pool)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
# 全局函数注册表(跨模块函数查找)
|
||||
#
|
||||
# 所有模块翻译的函数都会注册到此表(通过 add_func_to_table 自动注册)。
|
||||
# 主要用途: vtable 初始化时查找跨模块继承方法的 Function 对象,
|
||||
# 以获取函数类型信息构造 bitcast 字符串。
|
||||
# ============================================================
|
||||
GLOBAL_FUNC_MAX: t.CDefine = 8192
|
||||
def _init_global_func_table() -> int:
|
||||
"""初始化全局函数表(用 stdlib.malloc 分配,生命周期=整个程序)(委托到 gen._init_global_func_table)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit._init_global_func_table()
|
||||
return 0
|
||||
# _build_func_type_str — 从 Function 对象生成函数类型文本(stdlib 存储)
|
||||
#
|
||||
# 格式: ret_ty(param1_ty, param2_ty, ...),与 vtable bitcast 需要一致。
|
||||
# 用 stdlib.malloc 分配返回,跨文件永久存活(1b reset 不回收)。
|
||||
# 返回 None 表示失败。
|
||||
def _build_func_type_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
func: llvmlite.Function | t.CPtr) -> str:
|
||||
"""生成函数类型文本(stdlib 分配)(委托到 gen._build_func_type_str)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit._build_func_type_str(pool, func)
|
||||
return None
|
||||
def _register_global_func(name: str, func: llvmlite.Function | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr = None) -> int:
|
||||
"""注册函数到全局表(已存在则跳过),返回 0 成功(委托到 gen._register_global_func)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit._register_global_func(name, func, pool)
|
||||
return 0
|
||||
def update_global_func_typestr(pool: memhub.MemBuddy | t.CPtr,
|
||||
name: str,
|
||||
func: llvmlite.Function | t.CPtr) -> int:
|
||||
"""更新全局函数表的 TypeStr(在函数参数全部添加完成后调用)(委托到 gen.update_global_func_typestr)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.update_global_func_typestr(pool, name, func)
|
||||
return 0
|
||||
def find_func_global(name: str) -> llvmlite.Function | t.CPtr:
|
||||
"""在全局函数表中按名称查找,返回 Function 指针或 None(委托到 gen.find_func_global)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.find_func_global(name)
|
||||
return None
|
||||
def find_func_entry_global(name: str) -> GenTypes.FuncEntry | t.CPtr:
|
||||
"""在全局函数表中按名称查找,返回完整 GenTypes.FuncEntry(含 TypeStr)或 None(委托到 gen.find_func_entry_global)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.find_func_entry_global(name)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 全局默认参数注册表(跨模块默认参数填充)
|
||||
#
|
||||
# 独立于 _global_funcs,因为 _register_global_func 可能在
|
||||
# add_func_to_table 之前被调用(如 stub 注入),此时 defaults 还不可用。
|
||||
# ============================================================
|
||||
GLOBAL_DEFAULTS_MAX: t.CDefine = 4096
|
||||
def _init_global_defaults_table() -> int:
|
||||
"""初始化全局默认参数表(委托到 gen._init_global_defaults_table)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit._init_global_defaults_table()
|
||||
return 0
|
||||
def _register_global_defaults(name: str,
|
||||
defaults: t.CVoid | t.CPtr,
|
||||
default_count: int,
|
||||
param_count: int) -> int:
|
||||
"""注册函数默认参数到全局表,返回 0 成功(委托到 gen._register_global_defaults)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit._register_global_defaults(name, defaults, default_count, param_count)
|
||||
return 0
|
||||
def find_func_defaults(name: str) -> GenTypes.FuncDefaultsEntry | t.CPtr:
|
||||
"""按函数名查找默认参数信息,返回 GenTypes.FuncDefaultsEntry 或 None(委托到 gen.find_func_defaults)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit.find_func_defaults(name)
|
||||
return None
|
||||
# _build_const_from_snapshot — 从常量快照重建常量 IR 值
|
||||
#
|
||||
# 用于跨模块默认参数填充:gd_entry.Defaults(pool 内 AST)可能已被 reset 回收,
|
||||
# 改用注册时提取的 stdlib 常量快照(ConstKinds/ConstInts/ConstStrs)重建常量 IR。
|
||||
# 返回 llvmlite.Value*,失败返回 None。
|
||||
def _build_const_from_snapshot(pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
gd_entry: GenTypes.FuncDefaultsEntry | t.CPtr,
|
||||
di: int,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
builder: llvmlite.IRBuilder | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""从快照重建第 di 个默认值常量 IR(委托到 gen._build_const_from_snapshot)"""
|
||||
import lib.core.Gen.Generator as Generator
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(HandlesExprCall._g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.CallGenLeafKit._build_const_from_snapshot(pool, mod, gd_entry, di, trans, builder)
|
||||
return None
|
||||
def find_func_entry_in_table(funcs: GenTypes.FuncEntry | t.CPtr,
|
||||
func_count: int,
|
||||
name: str) -> GenTypes.FuncEntry | t.CPtr:
|
||||
"""在函数表中按名称查找,返回完整 GenTypes.FuncEntry 或 None"""
|
||||
if name is None or funcs is None:
|
||||
return None
|
||||
entry_size: t.CSizeT = GenTypes.FuncEntry.__sizeof__()
|
||||
i: int = 0
|
||||
while i < func_count:
|
||||
entry_addr: t.CUInt64T = t.CUInt64T(funcs) + i * entry_size
|
||||
entry: GenTypes.FuncEntry | t.CPtr = (GenTypes.FuncEntry | t.CPtr)(t.CVoid(entry_addr, t.CPtr))
|
||||
if entry.Name is not None:
|
||||
if string.strcmp(entry.Name, name) == 0:
|
||||
return entry
|
||||
i += 1
|
||||
return None
|
||||
@@ -1,262 +0,0 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
import string
|
||||
import viperlib
|
||||
import memhub
|
||||
import hashtable
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeKind - 类型种类枚举
|
||||
#
|
||||
# 替代 TransPyC 中 CType.position frozenset 的元属性系统。
|
||||
# 每个 TypeInfo 通过 Kind 字段标记其种类,避免 Python ClassVar 反射。
|
||||
# ============================================================
|
||||
class TypeKind(t.CEnum):
|
||||
Basic: t.State # 基本类型(int/char/float/double/bool 等)
|
||||
Pointer: t.State # 指针(T*)— 指针层数由 TypeInfo.PtrCount 表达
|
||||
Struct: t.State # 结构体/类
|
||||
Union: t.State # 联合体
|
||||
Enum: t.State # 枚举
|
||||
Typedef: t.State # 类型别名
|
||||
Function: t.State # 函数指针
|
||||
Array: t.State # 数组 T[N]
|
||||
Void: t.State # void
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeInfo - 类型信息结构
|
||||
#
|
||||
# 设计原则(相对 TransPyC CTypeInfo 的简化):
|
||||
# - POD 数据结构,无虚函数,无 Python 元特性(ClassVar/Generic/frozenset)
|
||||
# - 通过 mbuddy 分配,调用方管理生命周期(参考 llvmlite Module 模式)
|
||||
# - 通过 Kind 枚举代替 position frozenset
|
||||
# - PtrCount 表达指针层数(0=非指针, 1=T*, 2=T**)
|
||||
# - IsSigned 三态:-1=不适用(void/float), 0=unsigned, 1=signed
|
||||
#
|
||||
# 字段布局(8 字段):
|
||||
# Kind : i32 类型种类(TypeKind 枚举值)
|
||||
# Name : i8* 类型名(如 'int', 'CInt', 'MyStruct'),可能为 None
|
||||
# Size : i32 位宽(0=void/未知;int=32, char=8, double=64, long long=64)
|
||||
# Align : i32 对齐字节数(0=默认)
|
||||
# IsSigned : i32 -1=N/A, 0=unsigned, 1=signed
|
||||
# PtrCount : i32 指针层数
|
||||
# IsConst : i32 const 限定符(0/1)
|
||||
# IsVolatile : i32 volatile 限定符(0/1)
|
||||
#
|
||||
# 注意:Size 使用位宽(bit width)而非字节数,与 LLVM IR 的 i{N} 和
|
||||
# TransPyC CType.Size 约定一致(CInt.Size=32, CChar.Size=8)。
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class TypeInfo:
|
||||
Kind: int
|
||||
Name: str
|
||||
Size: int
|
||||
Align: int
|
||||
IsSigned: int
|
||||
PtrCount: int
|
||||
IsConst: int
|
||||
IsVolatile: int
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeRegistry - 类型注册表
|
||||
#
|
||||
# 维护 name(str) → TypeInfo* 映射,基于 HashTable 实现 O(1) 查找。
|
||||
# 替代 TransPyC CTypeRegistry 的 _name_to_class dict。
|
||||
# 内置基本类型(int/char/void/...)由 InitBasicTypes 注册。
|
||||
# ============================================================
|
||||
class TypeRegistry:
|
||||
_ht: hashtable.HashTable | t.CPtr
|
||||
__mbuddy__: memhub.MemBuddy | t.CPtr
|
||||
|
||||
def Register(self, ti: TypeInfo | t.CPtr) -> int:
|
||||
"""注册一个 TypeInfo。ti.Name 字段必须已设置。
|
||||
|
||||
Returns:
|
||||
1 表示成功,0 表示失败(ti 为 None 或 Name 为 None)
|
||||
"""
|
||||
if ti is None:
|
||||
return 0
|
||||
if ti.Name is None:
|
||||
return 0
|
||||
self._ht[ti.Name] = ti
|
||||
return 1
|
||||
|
||||
def Lookup(self, name: str) -> TypeInfo | t.CPtr:
|
||||
"""按名称查找 TypeInfo。
|
||||
|
||||
Returns:
|
||||
找到返回 TypeInfo*,找不到返回 None
|
||||
"""
|
||||
if name is None:
|
||||
return None
|
||||
return self._ht[name]
|
||||
|
||||
def Has(self, name: str) -> int:
|
||||
"""检查类型是否已注册。"""
|
||||
if name is None:
|
||||
return 0
|
||||
return name in self._ht
|
||||
|
||||
|
||||
# ============================================================
|
||||
# NewTypeInfo - 工厂函数:分配并初始化一个 TypeInfo
|
||||
#
|
||||
# 默认值:Kind=Basic, IsSigned=-1, 其余=0/None
|
||||
# ============================================================
|
||||
def NewTypeInfo(pool: memhub.MemBuddy | t.CPtr) -> TypeInfo | t.CPtr:
|
||||
ptr: TypeInfo | t.CPtr = pool.alloc(TypeInfo.__sizeof__())
|
||||
if ptr is None:
|
||||
return None
|
||||
string.memset(ptr, 0, TypeInfo.__sizeof__())
|
||||
ptr.Kind = TypeKind.Basic
|
||||
ptr.IsSigned = -1
|
||||
return ptr
|
||||
|
||||
|
||||
# ============================================================
|
||||
# NewTypeRegistry - 工厂函数:创建类型注册表
|
||||
# ============================================================
|
||||
def NewTypeRegistry(pool: memhub.MemBuddy | t.CPtr) -> TypeRegistry | t.CPtr:
|
||||
ptr: TypeRegistry | t.CPtr = pool.alloc(TypeRegistry.__sizeof__())
|
||||
if ptr is None:
|
||||
return None
|
||||
string.memset(ptr, 0, TypeRegistry.__sizeof__())
|
||||
ptr.__mbuddy__ = pool
|
||||
ptr._ht = hashtable.HashTable(pool)
|
||||
return ptr
|
||||
|
||||
|
||||
# ============================================================
|
||||
# TypeToLLVM - 将 TypeInfo 转换为 LLVM IR 类型字符串
|
||||
#
|
||||
# 规则:
|
||||
# - Kind == Void 或 (Size==0 且 IsSigned==-1 且 PtrCount==0) → "void"
|
||||
# - void 有 PtrCount > 0 → "i8" + PtrCount 个 "*"
|
||||
# - IsSigned == -1 且 Size > 0 → 浮点: half/float/double/fp128
|
||||
# - IsSigned != -1 且 Size > 0 → 整数: i{Size}
|
||||
# - 未知 → "i8*"
|
||||
#
|
||||
# Args:
|
||||
# buf: 输出缓冲区(i8*)
|
||||
# buf_size: 缓冲区容量
|
||||
# ti: TypeInfo 指针
|
||||
#
|
||||
# Returns:
|
||||
# 写入的字符数(不含 NUL),失败返回 -1
|
||||
# ============================================================
|
||||
def TypeToLLVM(buf: str, buf_size: t.CSizeT,
|
||||
ti: TypeInfo | t.CPtr) -> int:
|
||||
if buf is None:
|
||||
return -1
|
||||
if ti is None:
|
||||
return -1
|
||||
if buf_size == 0:
|
||||
return -1
|
||||
|
||||
# 判定 void
|
||||
is_void: int = 0
|
||||
if ti.Kind == TypeKind.Void:
|
||||
is_void = 1
|
||||
elif ti.Size == 0 and ti.IsSigned == -1 and ti.PtrCount == 0:
|
||||
is_void = 1
|
||||
|
||||
# 写入 base 类型字符串到 buf
|
||||
base_len: int = 0
|
||||
if is_void == 1:
|
||||
if ti.PtrCount == 0:
|
||||
# "void"
|
||||
if buf_size < 5:
|
||||
return -1
|
||||
string.strcpy(buf, "void")
|
||||
base_len = 4
|
||||
else:
|
||||
# void* → i8*(LLVM 中 void* 表示为 i8*)
|
||||
if buf_size < 4:
|
||||
return -1
|
||||
string.strcpy(buf, "i8")
|
||||
base_len = 2
|
||||
elif ti.IsSigned == -1:
|
||||
# 浮点
|
||||
if ti.Size == 16:
|
||||
if buf_size < 5:
|
||||
return -1
|
||||
string.strcpy(buf, "half")
|
||||
base_len = 4
|
||||
elif ti.Size == 32:
|
||||
if buf_size < 6:
|
||||
return -1
|
||||
string.strcpy(buf, "float")
|
||||
base_len = 5
|
||||
elif ti.Size == 64:
|
||||
if buf_size < 7:
|
||||
return -1
|
||||
string.strcpy(buf, "double")
|
||||
base_len = 6
|
||||
elif ti.Size == 128:
|
||||
if buf_size < 6:
|
||||
return -1
|
||||
string.strcpy(buf, "fp128")
|
||||
base_len = 5
|
||||
else:
|
||||
# 未知浮点尺寸 → double 兜底
|
||||
if buf_size < 7:
|
||||
return -1
|
||||
string.strcpy(buf, "double")
|
||||
base_len = 6
|
||||
else:
|
||||
# 整数: i{Size},用 snprintf 安全写入
|
||||
if ti.Size <= 0:
|
||||
# 无效尺寸 → i8 兜底
|
||||
if buf_size < 4:
|
||||
return -1
|
||||
string.strcpy(buf, "i8")
|
||||
base_len = 2
|
||||
else:
|
||||
viperlib.snprintf(buf, buf_size, "i%d", ti.Size)
|
||||
base_len = string.strlen(buf)
|
||||
|
||||
# 追加 PtrCount 个 "*"
|
||||
if base_len + ti.PtrCount + 1 > buf_size:
|
||||
return -1
|
||||
pos: int = base_len
|
||||
for i in range(ti.PtrCount):
|
||||
buf[pos] = '*'
|
||||
pos += 1
|
||||
buf[pos] = 0
|
||||
return pos
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Mixin - 所有 Handle 的非多态基类(对应 TransPyC 的 BaseHandle)
|
||||
#
|
||||
# @t.NoVTable 继承:字段展平嵌入子类,无 vtable 开销(对应 C++ 非多态继承)。
|
||||
# 子类继承 Trans 字段 + 共享工具方法,编译器自动生成子类方法包装
|
||||
# (self bitcast 为父类指针后调用),子类可直接调用继承的方法。
|
||||
#
|
||||
# 用法:
|
||||
# @t.NoVTable
|
||||
# class AssignHandle(Mixin):
|
||||
# _CurrentClass: str
|
||||
# def __init__(self, trans):
|
||||
# self.InitMixin(trans)
|
||||
# self._CurrentClass = None
|
||||
# def Handle(self, node) -> int:
|
||||
# rhs = self.Trans.ExprH.HandleValue(node.value)
|
||||
# ...
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class Mixin:
|
||||
"""所有 Handle 的非多态基类:持有 Translator 回指针 + 共享委托方法"""
|
||||
Trans: HT.Translator | t.CPtr
|
||||
|
||||
def InitMixin(self, trans: HT.Translator | t.CPtr) -> int:
|
||||
"""初始化 Mixin 字段(子类 __init__ 中调用)"""
|
||||
self.Trans = trans
|
||||
return 0
|
||||
|
||||
|
||||
# 全局 mbuddy 指针
|
||||
_mbuddy: t.CVoid | t.CPtr
|
||||
@@ -1,953 +0,0 @@
|
||||
import lib.core.Gen.Expr.ExprGenAttr as ExprGenAttr
|
||||
import lib.core.Gen.Expr.ExprGenBase as ExprGenBase
|
||||
import lib.core.Gen.Expr.ExprGenCdef as ExprGenCdef
|
||||
import lib.core.Gen.Expr.ExprGenCls as ExprGenCls
|
||||
import lib.core.Gen.Expr.ExprGenConst as ExprGenConst
|
||||
import lib.core.Gen.Expr.ExprGenFstr as ExprGenFstr
|
||||
import lib.core.Gen.Expr.ExprGenMixin as ExprGenMixin
|
||||
import lib.core.Gen.Expr.ExprGenName as ExprGenName
|
||||
import lib.core.Gen.Expr.ExprGenOps as ExprGenOps
|
||||
import lib.core.Gen.Func.FuncGenMixin as FuncGenMixin
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import memhub
|
||||
import string
|
||||
import llvmlite
|
||||
import stdlib
|
||||
import stdio
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.Projectrans.Config as Config
|
||||
import lib.Projectrans.Utils as Utils
|
||||
import lib.core.Gen.Generator as Generator
|
||||
|
||||
|
||||
# ============================================================
|
||||
# HandlesExpr - 表达式处理(P3 对象化后的委托层)
|
||||
#
|
||||
# 全部模块级函数已迁移为 lib.core.Gen.ExprGenMixin 的方法
|
||||
# (全局状态迁入 gen 字段),本模块保留同名模块级函数作为
|
||||
# "一行委托":延迟 import Gen 取全局单例(BuildPipeline/main
|
||||
# 创建后 set_global_gen 注册),再调用 gen 的对应方法。签名与
|
||||
# 旧函数完全一致,调用方零改动。
|
||||
#
|
||||
# ExprHandle 类及其 NewExprHandle 工厂保留(translator handler 模式)。
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
|
||||
# ============================================================
|
||||
_g_gen: Generator.Generator | t.CPtr = None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 委托函数:延迟 import Gen 取全局单例 → 调 gen 方法
|
||||
# (gen 未注册时正常流程不会发生;有返回值函数返回默认值)
|
||||
# ============================================================
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 从 AST 节点提取函数名
|
||||
# ============================================================
|
||||
def get_func_name(func_node: ast.AST | t.CPtr) -> str:
|
||||
"""从函数节点提取函数名(委托到 gen.get_func_name)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.get_func_name(func_node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 转义 LLVM IR 字符串字面量
|
||||
# ============================================================
|
||||
def escape_llvm_string(pool: memhub.MemBuddy | t.CPtr,
|
||||
src: str) -> str:
|
||||
"""将字符串转换为 LLVM IR 字符串字面量 c"...\\00"(委托到 gen.escape_llvm_string)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.escape_llvm_string(pool, src)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 获取 LLVM 整数类型的位宽
|
||||
# ============================================================
|
||||
def get_llvm_type_bits(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""获取 LLVM 整数类型的位宽,非整数类型返回 0(委托到 gen.get_llvm_type_bits)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.get_llvm_type_bits(ty)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 获取 LLVM 浮点类型的位宽
|
||||
# ============================================================
|
||||
def get_llvm_float_bits(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""获取 LLVM 浮点类型的位宽,非浮点类型返回 0(委托到 gen.get_llvm_float_bits)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.get_llvm_float_bits(ty)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# is_ptr_type - 检查类型是否为 Ptr
|
||||
#
|
||||
# 返回 1=是, 0=否。作为类型检查工具函数被广泛使用(50+ 处调用)。
|
||||
# ============================================================
|
||||
def is_ptr_type(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""检查 ty 是否是 Ptr 类型,返回 1=是, 0=否(委托到 gen.is_ptr_type)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.is_ptr_type(ty)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# get_ptr_level - 计算指针层级
|
||||
#
|
||||
# 返回值:
|
||||
# 0 = 非指针(数值/结构体等)
|
||||
# 1 = 一级指针(如 i8*, Struct*)
|
||||
# 2 = 二级指针(如 i8**, Struct**)
|
||||
# 3+ = 更高级指针
|
||||
# ============================================================
|
||||
def get_ptr_level(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""计算指针层级,0=非指针, 1=一级指针, 2=二级指针...(委托到 gen.get_ptr_level)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.get_ptr_level(ty)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# is_array_type - 检查类型是否为 Array
|
||||
#
|
||||
# 返回 1=是, 0=否。类型检查工具函数。
|
||||
# ============================================================
|
||||
def is_array_type(ty: llvmlite.LLVMType | t.CPtr) -> int:
|
||||
"""检查 ty 是否是 Array 类型,返回 1=是, 0=否(委托到 gen.is_array_type)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.is_array_type(ty)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _zext_index_to_i32 - 数组下标索引零扩展
|
||||
#
|
||||
# LLVM GEP 对窄整数索引默认符号扩展:i8 0xE2(226) 会被当成 -30,
|
||||
# 导致数组下标越界读(字节 >= 128 的乱码根因)。
|
||||
# 数组下标语义为非负,<32 位整数索引一律 zext 到 i32。
|
||||
# ============================================================
|
||||
def _zext_index_to_i32(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
idx_val: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""将 <32 位整数下标零扩展到 i32(数组下标非负语义)(委托到 gen._zext_index_to_i32)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase._zext_index_to_i32(builder, idx_val)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _get_custom_struct_cls_nm - 检查类型是否为已注册的自定义结构体
|
||||
#
|
||||
# 处理两种情况:
|
||||
# - ty 直接是 Struct → 检查是否注册
|
||||
# - ty 是 Ptr(Struct) → 检查 pointee 是否注册
|
||||
# ============================================================
|
||||
def _get_custom_struct_cls_nm(pool: memhub.MemBuddy | t.CPtr,
|
||||
ty: llvmlite.LLVMType | t.CPtr) -> str:
|
||||
"""检查 ty 或 ty 的 pointee 是否是已注册的自定义结构体,返回类名或 None(委托到 gen._get_custom_struct_cls_nm)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase._get_custom_struct_cls_nm(pool, ty)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _is_list_subscript_base - 判断下标基座是否为 list[T] 变量
|
||||
# ============================================================
|
||||
def _is_list_subscript_base(pool: memhub.MemBuddy | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
sub_node: ast.AST | t.CPtr) -> int:
|
||||
"""判断下标基座是否为 list[T] 变量(1=是)(委托到 gen._is_list_subscript_base)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase._is_list_subscript_base(pool, trans, sub_node)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _sub_base_class_name - 解析下标基座变量的结构体类名
|
||||
# ============================================================
|
||||
def _sub_base_class_name(pool: memhub.MemBuddy | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
sub_node: ast.AST | t.CPtr) -> str:
|
||||
"""解析下标基座变量的结构体类名(无则 None)(委托到 gen._sub_base_class_name)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase._sub_base_class_name(pool, trans, sub_node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _sub_base_uses_getitem - 下标基座是否应走 __getitem__ 语义
|
||||
# ============================================================
|
||||
def _sub_base_uses_getitem(pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
sub_node: ast.AST | t.CPtr) -> int:
|
||||
"""下标基座应走 __getitem__ 语义时返回 1,否则 0(应走 GEP 地址语义)(委托到 gen._sub_base_uses_getitem)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase._sub_base_uses_getitem(pool, mod, trans, sub_node)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _deref_if_ptr_ptr - 如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用
|
||||
# ============================================================
|
||||
def _deref_if_ptr_ptr(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
obj_ptr: llvmlite.Value | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""如果 obj_ptr 是 Ptr(Ptr(...)),load 解引用获取内层指针(委托到 gen._deref_if_ptr_ptr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase._deref_if_ptr_ptr(builder, obj_ptr)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 类型强制转换:整数 sext/trunc,浮点 fpext/fptrunc,int↔float si2fp/fp2si
|
||||
# ============================================================
|
||||
def coerce_to_type(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
target_ty: llvmlite.LLVMType | t.CPtr,
|
||||
node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""将 val 强制转换为 target_ty(委托到 gen.coerce_to_type)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.coerce_to_type(builder, val, target_ty, node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# translate_ptr_arith - 指针算术: ptr + int / ptr - int
|
||||
#
|
||||
# 用 getelementptr(按 pointee 元素大小缩放索引),对齐 TPC
|
||||
# ExprGen.emit_binary_op / HandlesAugAssign.py。
|
||||
# ============================================================
|
||||
def translate_ptr_arith(pool: memhub.MemBuddy | t.CPtr,
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
ptr_val: llvmlite.Value | t.CPtr,
|
||||
int_val: llvmlite.Value | t.CPtr,
|
||||
op: int) -> llvmlite.Value | t.CPtr:
|
||||
"""指针算术: ptr + int / ptr - int → GEP(按元素大小缩放索引)(委托到 gen.translate_ptr_arith)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenBase.translate_ptr_arith(pool, builder, ptr_val, int_val, op)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 创建全局字符串常量
|
||||
# ============================================================
|
||||
def create_global_string(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
str_val: str,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""创建全局字符串常量并返回 i8* bitcast(委托到 gen.create_global_string)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenConst.create_global_string(builder, pool, mod, str_val, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 模块引用 AST → 模块路径字符串(递归拼接 Attribute 链)
|
||||
# ============================================================
|
||||
def attr_module_path_str(pool: memhub.MemBuddy | t.CPtr,
|
||||
node: ast.AST | t.CPtr) -> str:
|
||||
"""把模块引用 AST 转成模块路径字符串(Name('sys')→"sys"、
|
||||
Attribute(Attribute(Name('os'),'_win32'))→"os._win32";非模块引用形态返回 None)
|
||||
|
||||
跨 mixin 委托:CallGenMixin 等不能 self. 直接调用 ExprGenMixin 的方法
|
||||
(@t.NoVTable 静态绑定会 mangle 成当前类名 → undefined reference)。
|
||||
"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr._attr_module_path_str(pool, node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译常量表达式
|
||||
# ============================================================
|
||||
def translate_constant(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译常量(int/str/bool)(委托到 gen.translate_constant)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenConst.translate_constant(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _infer_elem_type_from_value — 从 LLVM Value 推断 list 元素类型名
|
||||
# ============================================================
|
||||
def _infer_elem_type_from_value(pool: memhub.MemBuddy | t.CPtr,
|
||||
value: llvmlite.Value | t.CPtr) -> str:
|
||||
"""从 LLVM Value 的类型推断 list 元素类型名(委托到 gen._infer_elem_type_from_value)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenConst._infer_elem_type_from_value(pool, value)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _find_pool_var — 查找上下文中的 pool 变量
|
||||
#
|
||||
# 依次尝试 "pool", "_mbuddy", "mbuddy", "mb"
|
||||
# ============================================================
|
||||
def _find_pool_var(trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""查找上下文中的 pool 变量,返回 alloca 或 None(委托到 gen._find_pool_var)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenConst._find_pool_var(trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# translate_list_literal — 翻译 list 字面量 [a, b, c]
|
||||
#
|
||||
# 将 list 字面量翻译为 list[T](pool) 构造 + append 调用序列
|
||||
# ============================================================
|
||||
def translate_list_literal(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
elem_type_name: str,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译 list 字面量 [a, b, c] → list[T](pool) + append 序列(委托到 gen.translate_list_literal)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenConst.translate_list_literal(builder, pool, mod, node, elem_type_name, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译值表达式(RHS 分派)— 模块级版本
|
||||
# ============================================================
|
||||
def translate_value(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
funcs_ptr: t.CPtr = None,
|
||||
func_count: int = 0,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译值表达式为 LLVM Value(委托到 gen.translate_value)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGen.translate_value(builder, pool, mod, node, funcs_ptr, func_count, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译 lambda 表达式 — 模块级委托
|
||||
#
|
||||
# translate_lambda 定义在 FuncGenMixin(跨 Mixin 方法),ExprGenMixin
|
||||
# 不能 self. 直接调用(NoVTable 下方法 mangle 成定义类符号,跨 Mixin
|
||||
# self 调用会解析失败),与 translate_value 同模式走模块级委托。
|
||||
# ============================================================
|
||||
def translate_lambda(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译 lambda 表达式,返回闭包指针(i8*)(委托到 gen.translate_lambda)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.FuncGen.translate_lambda(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译三元表达式 IfExp(test, body, orelse)
|
||||
# ============================================================
|
||||
def translate_ifexp(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译三元表达式 (body if test else orelse),返回 phi 结果 Value(委托到 gen.translate_ifexp)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps.translate_ifexp(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译比较表达式 Compare(left, ops, comparators)
|
||||
# ============================================================
|
||||
def should_zext_widen(pool: memhub.MemBuddy | t.CPtr,
|
||||
narrow_val: llvmlite.Value | t.CPtr,
|
||||
wide_val: llvmlite.Value | t.CPtr,
|
||||
narrow_node: ast.AST | t.CPtr = None) -> int:
|
||||
"""判断整数拓宽方向:1=zext(无符号语义),0=sext(委托到 gen.should_zext_widen)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps.should_zext_widen(pool, narrow_val, wide_val, narrow_node)
|
||||
return 0
|
||||
|
||||
|
||||
def _node_type_unsigned(pool: memhub.MemBuddy | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> int:
|
||||
"""轻量判断 AST 节点是否解析为无符号整数类型(1=是,0=否/未知)(委托到 gen._node_type_unsigned)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps._node_type_unsigned(pool, node, trans)
|
||||
return 0
|
||||
|
||||
|
||||
def _type_name_unsigned(type_name: str) -> int:
|
||||
"""类型名是否为无符号整数类型(精确匹配,避免子串误伤如 nUIntCount)(委托到 gen._type_name_unsigned)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps._type_name_unsigned(type_name)
|
||||
return 0
|
||||
|
||||
|
||||
def translate_compare(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译比较表达式,返回 i1 结果(委托到 gen.translate_compare)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps.translate_compare(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译一元运算表达式 UnaryOp(op, operand)
|
||||
# ============================================================
|
||||
def translate_unaryop(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译一元运算(-x, +x, not x, ~x)(委托到 gen.translate_unaryop)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps.translate_unaryop(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译布尔运算 BoolOp(op, values) — 短路求值,返回 i1
|
||||
# ============================================================
|
||||
def translate_boolop(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
funcs_ptr: t.CPtr = None,
|
||||
func_count: int = 0,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译布尔运算(and/or)的短路求值,返回 i1(委托到 gen.translate_boolop)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps.translate_boolop(builder, pool, mod, node, funcs_ptr, func_count, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _build_source_path_from_sha1 - 通过 SHA1 从存储器构建源 .vp/.py 文件路径
|
||||
# ============================================================
|
||||
def _build_source_path_from_sha1(sha1: str) -> str:
|
||||
"""通过 SHA1 从全局存储器构建源 .py 文件路径(委托到 gen._build_source_path_from_sha1)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCdef._build_source_path_from_sha1(sha1)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _lookup_cross_module_cdefine - 跨模块查找 CDefine 常量
|
||||
# ============================================================
|
||||
def _lookup_cross_module_cdefine(pool: memhub.MemBuddy | t.CPtr,
|
||||
name: str,
|
||||
from_imports: str,
|
||||
imported_modules: str = None,
|
||||
depth: int = 0,
|
||||
node: ast.AST | t.CPtr = None) -> t.CInt64T:
|
||||
"""跨模块查找 CDefine 常量,返回值(64 位)或 -1(未找到)(委托到 gen._lookup_cross_module_cdefine)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCdef._lookup_cross_module_cdefine(pool, name, from_imports, imported_modules, depth, node)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _is_cdefine_name_pattern - 检查名字是否符合 CDefine 命名约定
|
||||
# ============================================================
|
||||
def _is_cdefine_name_pattern(name: str) -> int:
|
||||
"""检查名字是否符合 CDefine 命名约定(全大写+下划线+数字)(委托到 gen._is_cdefine_name_pattern)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCdef._is_cdefine_name_pattern(name)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译变量引用(Name 节点)→ load
|
||||
# ============================================================
|
||||
def translate_name_value(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译变量引用(Name 节点)→ load(委托到 gen.translate_name_value)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName.translate_name_value(builder, pool, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprHandle - 表达式处理器(Mixin 继承模式)
|
||||
#
|
||||
# HandleValue 提供 trans 接口,委托到模块级 translate_value
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprHandle(HandlesBase.Mixin):
|
||||
"""表达式处理器:继承 Mixin 获得 Trans 回指针"""
|
||||
|
||||
def __init__(self, trans: HT.Translator | t.CPtr):
|
||||
self.Trans = trans
|
||||
|
||||
# ============================================================
|
||||
# HandleValue - 翻译值表达式为 LLVM Value
|
||||
# ============================================================
|
||||
def HandleValue(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译值表达式,从 self.Trans 获取共享状态"""
|
||||
return translate_value(
|
||||
self.Trans._cur_builder, self.Trans.Pool, self.Trans.Module,
|
||||
node,
|
||||
self.Trans._funcs, self.Trans._func_count, self.Trans)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# NewExprHandle - 工厂函数
|
||||
# ============================================================
|
||||
def NewExprHandle(pool: memhub.MemBuddy | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr) -> ExprHandle | t.CPtr:
|
||||
h: ExprHandle | t.CPtr = pool.alloc(ExprHandle.__sizeof__())
|
||||
if h is None:
|
||||
return None
|
||||
string.memset(h, 0, ExprHandle.__sizeof__())
|
||||
h.Trans = trans
|
||||
return h
|
||||
|
||||
|
||||
# ============================================================
|
||||
# list_getitem_inline — 内联生成 list[T] __getitem__ 逻辑
|
||||
#
|
||||
# list 结构布局 (6 字段 × 8 字节):
|
||||
# __data__(0) __count__(8) __capacity__(16) __pool__(24) __elem_size__(32) __iter_index__(40)
|
||||
# 返回元素地址 (i8*),调用方根据元素类型 load 正确的值
|
||||
# ============================================================
|
||||
def list_getitem_inline(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
lm_obj: llvmlite.Value | t.CPtr,
|
||||
idx_val: llvmlite.Value | t.CPtr,
|
||||
node: ast.AST | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""内联生成 list __getitem__ 逻辑,返回元素地址 (i8*)(委托到 gen.list_getitem_inline)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName.list_getitem_inline(builder, pool, lm_obj, idx_val, node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _list_elem_type_from_name — 从 list 类型名提取元素 LLVM 类型
|
||||
# ============================================================
|
||||
def _list_elem_type_from_name(pool: memhub.MemBuddy | t.CPtr,
|
||||
struct_name: str) -> llvmlite.LLVMType | t.CPtr:
|
||||
"""从 list 类型名提取元素 LLVM 类型(委托到 gen._list_elem_type_from_name)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName._list_elem_type_from_name(pool, struct_name)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# list_setitem_inline — 内联生成 list[T] __setitem__ 逻辑
|
||||
# ============================================================
|
||||
def list_setitem_inline(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
lm_obj: llvmlite.Value | t.CPtr,
|
||||
idx_val: llvmlite.Value | t.CPtr,
|
||||
rhs_val: llvmlite.Value | t.CPtr,
|
||||
node: ast.AST | t.CPtr = None) -> int:
|
||||
"""内联生成 list __setitem__ 逻辑,返回 0(委托到 gen.list_setitem_inline)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName.list_setitem_inline(builder, pool, lm_obj, idx_val, rhs_val, node)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# is_list_subscript — 检查 Subscript 节点是否是 list[T] 类型
|
||||
#
|
||||
# 返回 list 对象指针 (Ptr(list[T])) 或 None
|
||||
# ============================================================
|
||||
def is_list_subscript(node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""检查 Subscript 节点是否是 list[T] 类型,返回 list 对象指针或 None(委托到 gen.is_list_subscript)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName.is_list_subscript(node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译下标表达式 Subscript(value, slice, ctx) — ptr[i] / arr[i]
|
||||
# ============================================================
|
||||
def translate_subscript(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译下标表达式,返回加载的元素值(委托到 gen.translate_subscript)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName.translate_subscript(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# find_global_in_module - 在模块全局变量链表中按名称查找
|
||||
#
|
||||
# 查找策略:
|
||||
# 1. 精确匹配 (如 "_mbuddy" 匹配 @_mbuddy)
|
||||
# 2. 后缀匹配 (如 "_mbuddy" 匹配 @"sha1._mbuddy")
|
||||
# ============================================================
|
||||
def find_global_in_module(mod: llvmlite.LLVMModule | t.CPtr,
|
||||
name: str) -> llvmlite.GlobalVariable | t.CPtr:
|
||||
"""在模块全局变量链表中按名称查找全局变量(委托到 gen.find_global_in_module)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr.find_global_in_module(mod, name)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# make_global_ref - 创建全局变量引用 (@name,类型为 ty*)
|
||||
# ============================================================
|
||||
def make_global_ref(pool: memhub.MemBuddy | t.CPtr,
|
||||
name: str,
|
||||
ty: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""创建全局变量引用 (类型为 ty*,名称为 @name)(委托到 gen.make_global_ref)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr.make_global_ref(pool, name, ty)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _is_t_type_object_name - 检查 name 是否是 t.py 中的类型对象名
|
||||
# ============================================================
|
||||
def _is_t_type_object_name(name: str) -> int:
|
||||
"""检查 name 是否是 t.py 中的类型对象名(CPtr/CInt/CDouble 等)(委托到 gen._is_t_type_object_name)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr._is_t_type_object_name(name)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _resolve_module_attribute_global - 解析模块属性访问的全局变量引用
|
||||
# ============================================================
|
||||
def _resolve_module_attribute_global(pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
at: ast.Attribute | t.CPtr,
|
||||
ty_hint: llvmlite.LLVMType | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""解析模块属性访问,返回全局变量引用 (用于跨模块 global 访问)(委托到 gen._resolve_module_attribute_global)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr._resolve_module_attribute_global(pool, mod, trans, at, ty_hint)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _get_cderef_attr_base - c.Deref(ptr).attr 属性访问的 base 指针
|
||||
# ============================================================
|
||||
def _get_cderef_attr_base(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
at_value: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""检测 at.value 是否为 c.Deref(ptr) 调用,返回 ptr 指针(不做 load)(委托到 gen._get_cderef_attr_base)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr._get_cderef_attr_base(builder, pool, mod, at_value, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译属性访问 Attribute(value, attr, ctx) — obj.field
|
||||
# ============================================================
|
||||
def translate_attribute(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译属性访问,返回加载的字段值(委托到 gen.translate_attribute)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr.translate_attribute(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 获取下标表达式的元素指针(不加载值,用于赋值)
|
||||
# ============================================================
|
||||
def get_subscript_ptr(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""获取下标表达式的元素指针(用于赋值 lhs)(委托到 gen.get_subscript_ptr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenName.get_subscript_ptr(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 获取属性访问的字段指针(不加载值,用于赋值)
|
||||
# ============================================================
|
||||
def get_attribute_ptr(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""获取属性访问的字段指针(用于赋值 lhs)(委托到 gen.get_attribute_ptr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr.get_attribute_ptr(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译 f-string(JoinedStr → snprintf 生成 i8* 栈缓冲)— 模块级委托
|
||||
# ============================================================
|
||||
def translate_joined_str(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译 f-string(委托到 gen.translate_joined_str,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenFstr.translate_joined_str(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译裸 FormattedValue(f"{expr:spec}" 无字面量)— 模块级委托
|
||||
# ============================================================
|
||||
def translate_formatted_value(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译裸 FormattedValue(委托到 gen.translate_formatted_value,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenFstr.translate_formatted_value(builder, pool, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# CDefine 整数常量 → LLVM 常量(64 位升级规则)— 模块级委托
|
||||
# ============================================================
|
||||
def _const_int_for_cdefine(pool: memhub.MemBuddy | t.CPtr,
|
||||
value: t.CInt64T) -> llvmlite.Value | t.CPtr:
|
||||
"""CDefine 整数常量 → LLVM 常量(委托到 gen._const_int_for_cdefine,定义于 ExprGenCdef)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCdef._const_int_for_cdefine(pool, value)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 解析嵌套 Attribute 链的 docstring 归属 — 模块级委托
|
||||
# ============================================================
|
||||
def _resolve_doc_symbol_attr(trans: HT.Translator | t.CPtr,
|
||||
at: ast.Attribute | t.CPtr,
|
||||
out_mod: str, out_sym: str) -> int:
|
||||
"""解析嵌套 Attribute 链的 docstring 归属(委托到 gen._resolve_doc_symbol_attr,定义于 ExprGenCls)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCls._resolve_doc_symbol_attr(trans, at, out_mod, out_sym)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 解析 Name 符号的 docstring 归属 — 模块级委托
|
||||
# ============================================================
|
||||
def _resolve_doc_symbol_name(trans: HT.Translator | t.CPtr, name_id: str,
|
||||
out_mod: str, out_sym: str) -> int:
|
||||
"""解析 Name 符号的 docstring 归属(委托到 gen._resolve_doc_symbol_name,定义于 ExprGenCls)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCls._resolve_doc_symbol_name(trans, name_id, out_mod, out_sym)
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 查找 docstring 内容(key="{module_sha1}.{symbol}")— 模块级委托
|
||||
# ============================================================
|
||||
def lookup_docstring(module_sha1: str, symbol: str) -> str:
|
||||
"""查找 docstring 内容(委托到 gen.lookup_docstring,定义于 ExprGenCls)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenCls.lookup_docstring(module_sha1, symbol)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 解析属性链(a.b.c)中 c 字段的注解类名 — 模块级委托
|
||||
# ============================================================
|
||||
def _resolve_attr_field_class(pool: memhub.MemBuddy | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr,
|
||||
attr_node: ast.AST | t.CPtr) -> str:
|
||||
"""解析属性链最终字段的注解类名(委托到 gen._resolve_attr_field_class,定义于 ExprGenAttr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenAttr._resolve_attr_field_class(pool, trans, attr_node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 翻译二元运算(自动类型提升)— 模块级委托
|
||||
# ============================================================
|
||||
def translate_binop(pool: memhub.MemBuddy | t.CPtr,
|
||||
builder: llvmlite.IRBuilder | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译二元运算(委托到 gen.translate_binop,定义于 ExprGenOps)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps.translate_binop(pool, builder, mod, node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# binop op → dunder 方法名(如 Add → "__add__")— 模块级委托
|
||||
# ============================================================
|
||||
def _binop_to_dunder(op: int) -> str:
|
||||
"""binop op → dunder 方法名(委托到 gen._binop_to_dunder,定义于 ExprGenOps)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps._binop_to_dunder(op)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# unaryop op → dunder 方法名(如 USub → "__neg__")— 模块级委托
|
||||
# ============================================================
|
||||
def _unaryop_to_dunder(op: int) -> str:
|
||||
"""unaryop op → dunder 方法名(委托到 gen._unaryop_to_dunder,定义于 ExprGenOps)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenOps._unaryop_to_dunder(op)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# f-string 尾部:全局格式串 + 固定栈缓冲 + snprintf — 模块级委托
|
||||
# ============================================================
|
||||
def _fstr_finalize(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
mod: llvmlite.LLVMModule | t.CPtr,
|
||||
fmt_buf: str,
|
||||
arg_head: llvmlite.Value | t.CPtr,
|
||||
arg_tail: llvmlite.Value | t.CPtr,
|
||||
arg_count: int,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""f-string 尾部(委托到 gen._fstr_finalize,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenFstr._fstr_finalize(builder, pool, mod, fmt_buf, arg_head, arg_tail, arg_count, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 追加字面量到格式串(% 转义)— 模块级委托
|
||||
# ============================================================
|
||||
def _fstr_append_literal(fmt_buf: str, lit: str) -> None:
|
||||
"""追加字面量到格式串(委托到 gen._fstr_append_literal,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
g.ExprGenFstr._fstr_append_literal(fmt_buf, lit)
|
||||
|
||||
|
||||
# ============================================================
|
||||
# Python format_spec → C printf 格式串 — 模块级委托
|
||||
# ============================================================
|
||||
def _fstr_parse_format_spec(pool: memhub.MemBuddy | t.CPtr,
|
||||
spec_node: ast.AST | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
arg_node: ast.AST | t.CPtr) -> str:
|
||||
"""Python format_spec → C printf 格式串(委托到 gen._fstr_parse_format_spec,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenFstr._fstr_parse_format_spec(pool, spec_node, val, arg_node)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 无 format_spec 时按值类型推断 C printf 格式 — 模块级委托
|
||||
# ============================================================
|
||||
def _fstr_infer_c_fmt(pool: memhub.MemBuddy | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
arg_node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr) -> str:
|
||||
"""按值类型推断 C printf 格式(委托到 gen._fstr_infer_c_fmt,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenFstr._fstr_infer_c_fmt(pool, val, arg_node, trans)
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 按 C 格式转换值类型(i8/i16→i32、bool→i32、f32→f64)— 模块级委托
|
||||
# ============================================================
|
||||
def _fstr_cast_value(builder: llvmlite.IRBuilder | t.CPtr,
|
||||
pool: memhub.MemBuddy | t.CPtr,
|
||||
val: llvmlite.Value | t.CPtr,
|
||||
c_fmt: str,
|
||||
arg_node: ast.AST | t.CPtr,
|
||||
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""按 C 格式转换值类型(委托到 gen._fstr_cast_value,定义于 ExprGenFstr)"""
|
||||
g: Generator.Generator | t.CPtr = (Generator.Generator | t.CPtr)(t.CVoid(_g_gen, t.CPtr))
|
||||
if g is not None:
|
||||
return g.ExprGenFstr._fstr_cast_value(builder, pool, val, c_fmt, arg_node, trans)
|
||||
return None
|
||||
@@ -1,137 +0,0 @@
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
import t, c
|
||||
from stdint import *
|
||||
import ast
|
||||
import llvmlite
|
||||
import memhub
|
||||
import string
|
||||
import stdio
|
||||
import stdlib
|
||||
import sys
|
||||
import viperlib
|
||||
import w32.fileio as fileio
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HT
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
import lib.core.Gen.Generator as Generator
|
||||
|
||||
# ============================================================
|
||||
# 全局 gen 单例(模块级镜像,同 HandlesType/HandlesStruct 模式)
|
||||
# ============================================================
|
||||
_g_gen: Generator.Generator | t.CPtr = None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 本地常量(阶段 E 拆分时随函数块误删,补回;子模块经 HandlesExprCall.常量 引用)
|
||||
# ============================================================
|
||||
_CEXPORT_MAX: t.CDefine = 256
|
||||
ASM_MAX_OPERANDS: t.CDefine = 16
|
||||
ASM_TEXT_BUF_SIZE: t.CDefine = 2048
|
||||
ASM_CONST_BUF_SIZE: t.CDefine = 512
|
||||
ASM_ARGS_BUF_SIZE: t.CDefine = 512
|
||||
ASM_LINE_BUF_SIZE: t.CDefine = 4096
|
||||
LLVMIR_MAX_OPS: t.CDefine = 16
|
||||
LLVMIR_TEMPLATE_BUF: t.CDefine = 512
|
||||
MAX_CLOSURE_NAMES: t.CDefine = 128
|
||||
MAX_FUNC_PTR_SIGS: t.CDefine = 64
|
||||
GLOBAL_FUNC_MAX: t.CDefine = 8192
|
||||
GLOBAL_DEFAULTS_MAX: t.CDefine = 4096
|
||||
|
||||
|
||||
|
||||
# ============================================================
|
||||
# AsmOperand - 内联汇编操作数条目
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class AsmOperand:
|
||||
"""内联汇编操作数条目"""
|
||||
Value: llvmlite.Value | t.CPtr # 输入值或输出 alloca
|
||||
Constraint: str # 约束字符串 (如 "r", "=r")
|
||||
IsOutput: int # 1=输出, 0=输入
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ============================================================
|
||||
# FuncEntry 结构体(用于函数表)
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class FuncEntry:
|
||||
"""函数表条目"""
|
||||
Name: str
|
||||
Func: llvmlite.Function | t.CPtr
|
||||
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr]),None=无默认值
|
||||
DefaultCount: int # 默认值数量
|
||||
ParamCount: int # 形参数量(不含 self)
|
||||
# TypeStr: 函数类型文本(stdlib 深拷贝,跨文件安全)
|
||||
# 1b 每文件 reset_to(mark1) 回收 pool 内 Function 对象后,
|
||||
# vtable 生成 find_func_global 读类型改用此文本,避免悬空。
|
||||
TypeStr: str
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@t.NoVTable
|
||||
class FuncDefaultsEntry:
|
||||
"""默认参数表条目"""
|
||||
Name: str
|
||||
Defaults: t.CVoid | t.CPtr # defaults 列表节点指针 (list[AST | CPtr])(pool 内,可能被 reset)
|
||||
DefaultCount: int
|
||||
ParamCount: int # 形参数量(不含 self)
|
||||
# 常量快照(stdlib 分配,跨文件永久存活):
|
||||
# 注册时提取每个默认值 Constant 的值,跨模块调用时优先用快照重建常量 IR,
|
||||
# 避免读取已被 1b reset_to(mark1) 回收的 pool 内 AST。
|
||||
ConstKinds: t.CInt | t.CPtr # const_kind 数组(DefaultCount 个 i32)
|
||||
ConstInts: t.CInt64T | t.CPtr # int_val 数组(DefaultCount 个 i64)
|
||||
ConstStrs: t.CSizeT | t.CPtr # str_val 指针数组(DefaultCount 个 i8*)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# ============================================================
|
||||
# ExprCallHandle - 函数调用处理器(Mixin 继承模式)
|
||||
#
|
||||
# HandleCall / HandlePrintfCall 提供 trans 接口
|
||||
# ============================================================
|
||||
@t.NoVTable
|
||||
class ExprCallHandle(HandlesBase.Mixin):
|
||||
"""函数调用处理器:继承 Mixin 获得 Trans 回指针"""
|
||||
|
||||
def __init__(self, trans: HT.Translator | t.CPtr):
|
||||
self.Trans = trans
|
||||
|
||||
# ============================================================
|
||||
# HandleCall - 翻译函数调用,返回 call 结果 Value
|
||||
# ============================================================
|
||||
def HandleCall(self, node: ast.AST | t.CPtr) -> llvmlite.Value | t.CPtr:
|
||||
"""翻译函数调用,从 self.Trans 获取共享状态"""
|
||||
return GenApi.translate_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
node,
|
||||
self.Trans._funcs, self.Trans._func_count, self.Trans)
|
||||
|
||||
# ============================================================
|
||||
# HandlePrintfCall - 翻译 printf 调用
|
||||
# ============================================================
|
||||
def HandlePrintfCall(self, cl: ast.Call | t.CPtr):
|
||||
"""翻译 printf 调用,从 self.Trans 获取共享状态"""
|
||||
GenApi.translate_printf_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
cl, self.Trans)
|
||||
|
||||
# ============================================================
|
||||
# HandlePrintCall - 翻译 print 调用
|
||||
# ============================================================
|
||||
def HandlePrintCall(self, cl: ast.Call | t.CPtr):
|
||||
"""翻译 print 调用(类型感知格式化 + 默认换行)"""
|
||||
GenApi.translate_print_call(
|
||||
self.Trans.Pool, self.Trans._cur_builder, self.Trans.Module,
|
||||
cl, self.Trans)
|
||||
@@ -1,9 +0,0 @@
|
||||
import t, c
|
||||
from stdint import *
|
||||
|
||||
# Handles 实体模块(去除委托层后保留:数据类/Translator/实体逻辑)
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Handles.ExprCallTable as ExprCallTable
|
||||
+1
-6
@@ -1,8 +1,6 @@
|
||||
import lib.core.Gen.GenApi as GenApi
|
||||
import lib.core.VLogger as VLogger
|
||||
import lib.core.Handles.HandlesTranslator as HandlesTranslator
|
||||
import lib.core.Handles.HandlesExpr as HandlesExpr
|
||||
import lib.core.Handles.HandlesExprCall as HandlesExprCall
|
||||
import lib.core.Gen.Translator as HandlesTranslator
|
||||
import lib.Phase.BuildPipeline as BuildPipeline
|
||||
import lib.core.IncludesScanner as IncludesScanner
|
||||
import lib.Stub.StubMerger as StubMerger
|
||||
@@ -118,9 +116,6 @@ def main() -> int:
|
||||
# 种子 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 并打印启动日志
|
||||
|
||||
Reference in new issue
Block a user