修正了 args 传参问题

This commit is contained in:
TermiNexus committed 2026-07-31 17:15:54 +08:00
1 parent fcd4d8a438
commit 4e17365b76
86 files changed
+417 -208

No files matched your search

+14
View File
@@ -121,6 +121,10 @@ class AssignHandle(BaseHandle):
return
ExistingPtr: ir.Value | None = None
# BUG-8 修复:清除读取全局变量时缓存的 GlobalVariable(非显式 global 声明)
if (VarName in Gen.variables and VarName not in Gen.global_vars
and isinstance(Gen.variables[VarName], ir.GlobalVariable)):
del Gen.variables[VarName]
if VarName in Gen.variables and Gen.variables[VarName] is not None:
VarPtr: ir.Value = Gen.variables[VarName]
if isinstance(VarPtr.type.pointee, ir.PointerType):
@@ -248,6 +252,10 @@ class AssignHandle(BaseHandle):
if VarName in ('mctx', 's1ctx', 's2ctx', 's5ctx'):
pass
if isinstance(Value.type, ir.PointerType) and isinstance(Value.type.pointee, (ir.LiteralStructType, ir.IdentifiedStructType)):
# BUG-8 修复:清除读取全局变量时缓存的 GlobalVariable(非显式 global 声明)
if (VarName in Gen.variables and VarName not in Gen.global_vars
and isinstance(Gen.variables[VarName], ir.GlobalVariable)):
del Gen.variables[VarName]
if VarName in Gen.variables and Gen.variables[VarName] is not None:
Gen._store(Value, Gen.variables[VarName])
else:
@@ -302,6 +310,12 @@ class AssignHandle(BaseHandle):
var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=VarName)
Gen._store(OldVal, var)
Gen.variables[VarName] = var
# BUG-8 修复:清除读取全局变量时缓存的 GlobalVariable(非显式 global 声明)。
# Python 语义:函数内无 global 声明时赋值应创建局部变量,
# 而非修改被读取缓存的全局变量。清除后走 L339 的正确逻辑。
if (VarName in Gen.variables and VarName not in Gen.global_vars
and isinstance(Gen.variables[VarName], ir.GlobalVariable)):
del Gen.variables[VarName]
if VarName in Gen.variables and Gen.variables[VarName] is not None:
VarPtr: ir.Value = Gen.variables[VarName]
TargetType: ir.Type | None = VarPtr.type.pointee if isinstance(VarPtr.type, ir.PointerType) else None
+31 -19
View File
@@ -1,20 +1,31 @@
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from lib.core.translator import Translator
from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin
import ast
import os
import re
import llvmlite.ir as ir
from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta
from lib.core.VLogger import get_logger as _vlog
from lib.constants.config import mode as _config_mode
from lib.includes import t
from lib.includes.t import CTypeRegistry
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from lib.core.translator import Translator
from lib.core.Translator.LlvmGenerator import LlvmGeneratorMixin
import ast
import os
import re
import llvmlite.ir as ir
from lib.core.Handles.HandlesBase import BaseHandle, CTypeInfo, FuncMeta
from lib.core.VLogger import get_logger as _vlog
from lib.constants.config import mode as _config_mode
from lib.includes import t
from lib.includes.t import CTypeRegistry
from lib.core.SymbolUtils import IsTModule, ExtractTypeNameFromBinOp
def _safe_ptr_type(ty: ir.Type) -> ir.Type:
"""LLVM IR 中不允许 void* 指针,Ptr(VoidType) 统一替换为 i8*(对应 C 的 void* 语义)"""
if isinstance(ty, ir.PointerType):
cur: ir.Type = ty
while isinstance(cur, ir.PointerType):
if isinstance(cur.pointee, ir.VoidType):
return ir.IntType(8).as_pointer()
cur = cur.pointee
return ty
class ExprCallHandle(BaseHandle):
def _append_eh_msg_out_arg(self, CallArgs: list[ir.Value], func: ir.Function | None, Gen: LlvmGeneratorMixin) -> None:
if not func:
@@ -335,7 +346,7 @@ class ExprCallHandle(BaseHandle):
if ClosureInfo is not None:
# 闭包结构体解包:{i8* env, i8* fn} -> 加载 env 和 fn,构造正确函数签名
FnRetType: ir.Type = ClosureInfo[0]
NonlocalArgTypes: list[ir.Type] = ClosureInfo[1]
NonlocalArgTypes: list[ir.Type] = [_safe_ptr_type(t) for t in ClosureInfo[1]]
I8PtrType: ir.PointerType = ir.IntType(8).as_pointer()
ClosureStructType: ir.LiteralStructType = ir.LiteralStructType([I8PtrType, I8PtrType])
ClosureStructPtr: ir.Value = Gen.builder.bitcast(closure_ptr, ir.PointerType(ClosureStructType), name=f"cast_closure_{FuncName}")
@@ -356,10 +367,10 @@ class ExprCallHandle(BaseHandle):
FullArgTypes: list[ir.Type] = list(NonlocalArgTypes) + UserArgTypes
FullFnType: ir.FunctionType = ir.FunctionType(FnRetType, FullArgTypes)
FullFnPtr: ir.Value = Gen.builder.bitcast(FnVal, ir.PointerType(FullFnType), name=f"cast_fn_{FuncName}")
# 调用参数:env 对应 nonlocal 参数,bitcast 到正确类型
# 调用参数:env 对应 nonlocal 参数,bitcast 到正确类型(需 _safe_ptr_type 兜底避免 void*)
CallArgs: list[ir.Value] = []
if NonlocalArgTypes:
CallArgs.append(Gen.builder.bitcast(EnvVal, NonlocalArgTypes[0], name=f"cast_env_{FuncName}"))
CallArgs.append(Gen.builder.bitcast(EnvVal, _safe_ptr_type(NonlocalArgTypes[0]), name=f"cast_env_{FuncName}"))
CallArgs.extend(UserCallArgs)
return Gen.builder.call(FullFnPtr, CallArgs, name=f"call_{FuncName}")
# 普通函数指针调用(无闭包):从调用参数构造函数类型,默认返回 i32
@@ -391,9 +402,10 @@ class ExprCallHandle(BaseHandle):
if len(call_args) < len(expected_fn_type.args):
while len(call_args) < len(expected_fn_type.args):
call_args.append(ir.Constant(expected_fn_type.args[len(call_args)], 0))
# 如果函数期望的 env 类型与闭包中存储的 i8* 不同,做 bitcast
# 如果函数期望的 env 类型与闭包中存储的 i8* 不同,做 bitcast(避免 void*)
if len(expected_fn_type.args) > 0 and call_args[0].type != expected_fn_type.args[0]:
call_args[0] = Gen.builder.bitcast(call_args[0], expected_fn_type.args[0], name=f"cast_env_{FuncName}")
safe_env_type: ir.Type = _safe_ptr_type(expected_fn_type.args[0])
call_args[0] = Gen.builder.bitcast(call_args[0], safe_env_type, name=f"cast_env_{FuncName}")
return Gen.builder.call(fn_val, call_args, name=f"call_{FuncName}")
raise Exception(f"Undefined function: '{FuncName}'")
if isinstance(Node.func, ast.Subscript):
+21 -5
View File
@@ -7,6 +7,22 @@ import ast
import llvmlite.ir as ir
def _safe_ptr_type(ty: ir.Type) -> ir.Type:
"""LLVM IR 中不允许 void* 指针,统一替换为 i8*(对应 C 的 void* 语义)
当 ty 是 Ptr(VoidType) / Ptr(Ptr(VoidType)) / 任何包含 VoidType 作为 pointee 的指针链,
替换为 Ptr(i8)。非指针类型原样返回。
"""
if isinstance(ty, ir.PointerType):
# 单级 / 多级 void 指针全部降级为 i8*
cur: ir.Type = ty
while isinstance(cur, ir.PointerType):
if isinstance(cur.pointee, ir.VoidType):
return ir.IntType(8).as_pointer()
cur = cur.pointee
return ty
class ForHandle(BaseHandle):
def _HandleForLlvm(self, Node: ast.For) -> None:
Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
@@ -361,14 +377,14 @@ class ForHandle(BaseHandle):
for var_name in nonlocal_var_names:
if var_name in Gen.variables and Gen.variables[var_name] is not None:
var: ir.Value = Gen.variables[var_name]
extra_params.append((var_name, var.type))
extra_params.append((var_name, _safe_ptr_type(var.type)))
elif var_name in Gen._reg_values:
OldVal: ir.Value = Gen._reg_values[var_name]
var: ir.AllocaInstr = Gen._allocaEntry(OldVal.type, name=var_name)
Gen._store(OldVal, var)
Gen.variables[var_name] = var
del Gen._reg_values[var_name]
extra_params.append((var_name, var.type))
extra_params.append((var_name, _safe_ptr_type(var.type)))
else:
# Search outer scope stack for the variable
found_var: ir.Value | None = None
@@ -379,13 +395,13 @@ class ForHandle(BaseHandle):
if found_var is not None:
# Add to current scope so it can be passed to nested functions
Gen.variables[var_name] = found_var
extra_params.append((var_name, found_var.type))
extra_params.append((var_name, _safe_ptr_type(found_var.type)))
else:
var = Gen._allocaEntry(ir.IntType(32), name=var_name)
Gen.variables[var_name] = var
extra_params.append((var_name, var.type))
extra_params.append((var_name, _safe_ptr_type(var.type)))
if extra_params:
Gen.nonlocal_params[Node.name] = [(name, ptr_type) for name, ptr_type in extra_params]
Gen.nonlocal_params[Node.name] = [(name, _safe_ptr_type(ptr_type)) for name, ptr_type in extra_params]
# Push current variables to scope stack before compiling nested function
Gen._variable_scope_stack.append(Gen.variables.copy())
saved_builder: ir.IRBuilder = Gen.builder
+12 -1
View File
@@ -7,6 +7,17 @@ import ast
import llvmlite.ir as ir
def _safe_ptr_type(ty: ir.Type) -> ir.Type:
"""LLVM IR 中不允许 void* 指针,Ptr(VoidType) 统一替换为 i8*"""
if isinstance(ty, ir.PointerType):
cur: ir.Type = ty
while isinstance(cur, ir.PointerType):
if isinstance(cur.pointee, ir.VoidType):
return ir.IntType(8).as_pointer()
cur = cur.pointee
return ty
class ReturnHandle(BaseHandle):
def _find_active_finally(self, Gen: "Translator.LlvmGen") -> tuple[ir.Block, ir.AllocaInstr, ir.AllocaInstr | None] | None:
for item in reversed(Gen.eh_finally_stack):
@@ -24,7 +35,7 @@ class ReturnHandle(BaseHandle):
nested_fn: ir.Function = Gen.functions[ret_name]
nonlocal_params: list[tuple[str, ir.Type]] = Gen.nonlocal_params[ret_name]
fn_return_type: ir.Type = nested_fn.function_type.return_type
nonlocal_types: list[ir.Type] = [t for _, t in nonlocal_params]
nonlocal_types: list[ir.Type] = [_safe_ptr_type(t) for _, t in nonlocal_params]
# 构建 env:收集所有 nonlocal 变量指针
env_ptrs: list[ir.Value] = []
for var_name, _ in nonlocal_params: