Files
ViperC/App/lib/core/Handles/ExprCallHandle.vp
T
TermiNexus 55d4c4102a fix(call): super() void 命中用 hit_box 区分未命中 + CTypedef 预注册修复 mode_t NameError
- CallGenDispatch/CallGenMixin/ExprCallHandle: super() 命中 void 方法返回 None 属预期,用 hit_box 命中标志区分未命中,避免误走裸名调用报 'super 未定义'
- HandlesAnnAssign.Handle + TranslatorGenMixin.handle_module_level_var: CTypedef 按需注册(翻译期表已被 clear_ctypedefs 清空),修复 posix.vp S_ISREG(mode: mode_t) 参数解析 NameError
2026-08-19 00:28:48 +08:00

288 lines
16 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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.core.Handles.HandlesVar as HandlesVar
import lib.core.Handles.HandlesType as HandlesType
import lib.core.Handles.HandlesNonlocal as HandlesNonlocal
import lib.core.Handles.HandlesStruct as HandlesStruct
import lib.core.Handles.HandlesImports as HandlesImports
import lib.core.Handles.HandlesClassDef as HandlesClassDef
import lib.core.StubMerger as StubMerger
import lib.core.Handles.ExprCallBase as ExprCallBase
import lib.core.Handles.ExprCallDeref as ExprCallDeref
import lib.core.Handles.ExprCallCtor as ExprCallCtor
import lib.core.Handles.ExprCallCall as ExprCallCall
import lib.core.Handles.ExprCallTable as ExprCallTable
import lib.core.Handles.HandlesExprCall as HandlesExprCall
# ============================================================
# ExprCallHandle - HandlesExprCall 拆分(阶段 E):ExprCallHandle
#
# 直接移动模式:委托函数迁至此模块,原 HandlesExprCall.vp 仅
# 保留 _g_gen/常量/类;调用方经本模块前缀访问。
# ============================================================
# ============================================================
# NewExprCallHandle - 工厂函数
# ============================================================
def NewExprCallHandle(pool: memhub.MemBuddy | t.CPtr,
trans: HT.Translator | t.CPtr) -> HandlesExprCall.ExprCallHandle | t.CPtr:
"""新建 HandlesExprCall.ExprCallHandle 工厂(委托到 gen.NewExprCallHandle)"""
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.NewExprCallHandle(pool, trans)
return None
# ============================================================
# _make_vtable_ref_i8 / _emit_eh_guarded_call / _translate_isinstance
# (追加91:CallGenMixin 拆分后顶层经委托调用 CallGenLeafKit 方法——
# TPV self 调用仅支持 1 级父类,跨 Mixin 统一走 HandlesExprCall._g_gen 委托)
# ============================================================
def _make_vtable_ref_i8(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
class_name: str,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""构造类 vtable 地址引用(i8*)(委托到 gen._make_vtable_ref_i8)"""
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._make_vtable_ref_i8(pool, builder, mod, class_name, trans)
return None
def _emit_eh_guarded_call(builder: llvmlite.IRBuilder | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
trans: HT.Translator | t.CPtr,
func: llvmlite.Function | t.CPtr,
call_name: str,
head: llvmlite.Value | t.CPtr,
count: int,
ret_ty: llvmlite.LLVMType | t.CPtr,
is_variadic: int) -> llvmlite.Value | t.CPtr:
"""带 try-except EH 检测的函数调用(委托到 gen._emit_eh_guarded_call)"""
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._emit_eh_guarded_call(builder, pool, mod, trans, func, call_name, head, count, ret_ty, is_variadic)
return None
def _translate_isinstance(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
obj_node: ast.AST | t.CPtr,
cls_node: ast.AST | t.CPtr,
trans: HT.Translator | t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""翻译 isinstance()(委托到 gen._translate_isinstance)"""
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._translate_isinstance(pool, builder, mod, obj_node, cls_node, trans)
return None
# ============================================================
# _is_sha1_mangled_call / _is_list_builtin_method / _translate_fakeduck_call /
# _translate_super_call(阶段 B:CallGenMixin 拆分后顶层经委托调用这些方法)
# ============================================================
def _is_sha1_mangled_call(call_name: str) -> int:
"""判断 call_name 是否为跨模块 Viper 函数(委托到 gen._is_sha1_mangled_call)"""
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._is_sha1_mangled_call(call_name)
return 0
def _is_list_builtin_method(class_name: str, method_name: str) -> int:
"""判断(class_name, method_name) 是否是 list 泛型内置方法(委托到 gen._is_list_builtin_method)"""
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._is_list_builtin_method(class_name, method_name)
return 0
def _translate_fakeduck_call(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cls_name: str,
method_name: str,
cl: ast.Call | t.CPtr,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""FakeDuck: str 变量方法调用(委托到 gen._translate_fakeduck_call)"""
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._translate_fakeduck_call(pool, builder, mod, cls_name, method_name, cl, trans)
return None
def _translate_super_call(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
method_name: str,
trans: HT.Translator | t.CPtr) -> llvmlite.Value | t.CPtr:
"""super().method(args) → 父类方法静态调用(委托到 gen._translate_super_call)"""
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._translate_super_call(pool, builder, mod, cl, method_name, trans)
return None
# ============================================================
# translate_call 前置检测 helper(阶段 C:CallGenMixin 拆分后顶层经委托
# 调用 CallGenDispatch 方法。每个返回 Value|CPtr,None = 未命中继续主路径)
# ============================================================
def _tc_h1_super_ctraits(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""super()/ctraits 编译期检测(委托到 gen._tc_h1_super_ctraits)"""
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._tc_h1_super_ctraits(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, hit_box)
return None
def _tc_h2_c_special(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""c.Deref/Asm/LLVMIR 等特殊调用(委托到 gen._tc_h2_c_special)"""
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._tc_h2_c_special(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, hit_box)
return None
def _tc_h3_stdarg_cast(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
"""stdarg 糖 + str/int/bool 内置强转(委托到 gen._tc_h3_stdarg_cast)"""
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._tc_h3_stdarg_cast(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
return None
def _tc_h4_type_casts(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
"""t.XXX / typedef 类型转换(委托到 gen._tc_h4_type_casts)"""
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._tc_h4_type_casts(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
return None
def _tc_h5_sizeof_len_isinst(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT) -> llvmlite.Value | t.CPtr:
"""__sizeof__/len/isinstance 内置(委托到 gen._tc_h5_sizeof_len_isinst)"""
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._tc_h5_sizeof_len_isinst(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can)
return None
def _tc_h6_method_dispatch(pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
cl: ast.Call | t.CPtr,
funcs_ptr: t.CPtr,
func_count: int,
trans: HT.Translator | t.CPtr,
func_name: str,
cargs: list[ast.AST | t.CPtr] | t.CPtr,
can: t.CSizeT,
hit_box: t.CPtr = None) -> llvmlite.Value | t.CPtr:
"""静态类/方法调用/表达式接收者/self.field/list 内置(委托到 gen._tc_h6_method_dispatch)"""
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._tc_h6_method_dispatch(pool, builder, mod, cl, funcs_ptr, func_count, trans, func_name, cargs, can, hit_box)
return None
# ============================================================
# FuncGen 跨 Mixin 委托(阶段 D:FuncGenMixin 拆 Base/Def 后顶层经
# 此调用这些方法。参数与目标方法一致,去 self)
# ============================================================
def extract_func_attrs(pool: memhub.MemBuddy | t.CPtr,
decorator_list: list[ast.AST | t.CPtr] | t.CPtr,
imported_modules: str) -> str:
"""从 decorator_list 提取 c.Attribute 属性(委托到 gen.extract_func_attrs)"""
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.extract_func_attrs(pool, decorator_list, imported_modules)
return None
def _mangle_name(trans: HT.Translator | t.CPtr, name: str) -> str:
"""为任意名称添加 SHA1 前缀(委托到 gen._mangle_name)"""
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._mangle_name(trans, name)
return name
def _mangle_func_name(trans: HT.Translator | t.CPtr, name: str,
has_export: int) -> str:
"""为函数名添加 SHA1 前缀(委托到 gen._mangle_func_name)"""
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._mangle_func_name(trans, name, has_export)
return name
def _body_has_raise(fd: ast.FunctionDef | t.CPtr) -> int:
"""函数体顶层是否含 raise(委托到 gen._body_has_raise)"""
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._body_has_raise(fd)
return 0
def _prepare_chain_nonlocals(trans: HT.Translator | t.CPtr,
node: ast.AST | t.CPtr,
pool: memhub.MemBuddy | t.CPtr,
builder: llvmlite.IRBuilder | t.CPtr,
mod: llvmlite.LLVMModule | t.CPtr,
i8_ty: llvmlite.LLVMType | t.CPtr,
i8_ptr_ty: llvmlite.LLVMType | t.CPtr) -> int:
"""准备嵌套函数 nonlocals 链(委托到 gen._prepare_chain_nonlocals)"""
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._prepare_chain_nonlocals(trans, node, pool, builder, mod, i8_ty, i8_ptr_ty)
return 0