修正了 args 传参问题
This commit is contained in:
1 parent
fcd4d8a438
commit
4e17365b76
86 files changed
+417
-208
No files matched your search
@@ -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
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in new issue
Block a user