StructGen: _get_struct_size/_get_align 去 opaque→8/ptr_size、未知→4 兜底并补 VectorType;LiteralStructType.fields→.elements(llvmlite 无 fields,必然 AttributeError) HandlesClassDef: union 载荷尺寸经不存在的 ir.DataLayout 静默退化成 8 字节;HandlesExprCall/ExprBuiltin: sizeof 各静默 0 分支改 fail-fast,数组元素 sizeof 统一走 _get_struct_size HandlesFor: nonlocal struct/array 堆分配不再退化成 malloc(8) vast/vast_c: 补一元 * / & 解析,装饰器后 extern/export 分派修复,C 侧报错带 token 与行号;StubGen.Converter: 宏展开丢尾随空行修 .pyi 缩进非法 其余为 rawptr 迁移 / fail-fast 口径等历史改动一并入库
84 lines
4.5 KiB
Python
84 lines
4.5 KiB
Python
from __future__ import annotations
|
|
from typing import TYPE_CHECKING
|
|
if TYPE_CHECKING:
|
|
from lib.core.translator import Translator
|
|
from lib.core.Handles.HandlesBase import BaseHandle
|
|
import vast as ast
|
|
import llvmlite.ir as ir
|
|
|
|
|
|
class BodyHandle(BaseHandle):
|
|
def __init__(self, translator: "Translator") -> None:
|
|
super().__init__(translator)
|
|
|
|
def HandleBodyLlvm(self, Body: list[ast.stmt]) -> None:
|
|
Gen: "Translator.LlvmGen" = self.Trans.LlvmGen
|
|
for Node in Body:
|
|
if Gen.builder and Gen.builder.block.is_terminated:
|
|
break
|
|
Gen._set_node_info(Node)
|
|
try:
|
|
if isinstance(Node, ast.Expr):
|
|
self.HandleExprLlvm(Node.value)
|
|
elif isinstance(Node, ast.Return):
|
|
self.Trans.ReturnHandler._HandleReturnLlvm(Node)
|
|
elif isinstance(Node, ast.Assign):
|
|
self.Trans.AssignHandler._HandleAssignLlvm(Node)
|
|
elif isinstance(Node, ast.AugAssign):
|
|
self.Trans.AugAssignHandler._HandleAugAssignLlvm(Node)
|
|
elif isinstance(Node, ast.AnnAssign):
|
|
self.Trans.AnnAssignHandler._HandleAnnAssignLlvm(Node)
|
|
elif isinstance(Node, ast.If):
|
|
self.Trans.IfHandler._HandleIfLlvm(Node)
|
|
elif isinstance(Node, ast.For):
|
|
self.Trans.ForHandler._HandleForLlvm(Node)
|
|
elif isinstance(Node, ast.While):
|
|
self.Trans.WhileHandler._HandleWhileLlvm(Node)
|
|
elif isinstance(Node, ast.Break):
|
|
if Gen.loop_break_targets:
|
|
Gen.builder.branch(Gen.loop_break_targets[-1])
|
|
elif isinstance(Node, ast.Continue):
|
|
if Gen.loop_continue_targets:
|
|
Gen.builder.branch(Gen.loop_continue_targets[-1])
|
|
elif isinstance(Node, ast.With):
|
|
self.Trans.WithHandler._HandleWithLlvm(Node)
|
|
elif isinstance(Node, ast.ClassDef):
|
|
pass
|
|
elif getattr(ast, 'Match', None) and isinstance(Node, ast.Match):
|
|
self.Trans.MatchHandler._HandleMatchLlvm(Node)
|
|
elif isinstance(Node, ast.Try):
|
|
self.Trans.TryHandler._HandleTryLlvm(Node)
|
|
elif isinstance(Node, ast.Raise):
|
|
self.Trans.RaiseHandler._HandleRaiseLlvm(Node)
|
|
elif isinstance(Node, ast.Assert):
|
|
self.Trans.AssertHandler._HandleAssertLlvm(Node)
|
|
elif isinstance(Node, ast.Global):
|
|
self.Trans.ForHandler._HandleGlobalLlvm(Node)
|
|
elif isinstance(Node, ast.FunctionDef):
|
|
self.Trans.ForHandler._HandleNestedFunctionLlvm(Node)
|
|
elif isinstance(Node, ast.Nonlocal):
|
|
self.Trans.ForHandler._HandleNonlocalLlvm(Node)
|
|
elif isinstance(Node, ast.Delete):
|
|
self.Trans.DeleteHandler._HandleDeleteLlvm(Node)
|
|
except Exception as e:
|
|
lineno: int = getattr(Node, 'lineno', 0)
|
|
# 注入行偏移还原:AST 行号含 _inject_auto_imports 在文件头注入的 N 行,
|
|
# 先按精确偏移减回磁盘真实行号(N 由 Phase2Translator 计算并挂到 translator);
|
|
# 报文行号与源码行必须同用还原后的 lineno,二者一致(否则会显示下一行源码)。
|
|
_line_offset: int = int(getattr(self.Trans, '_line_offset', 0) or 0)
|
|
if _line_offset > 0 and lineno > _line_offset:
|
|
lineno -= _line_offset
|
|
source_line: str | None = Gen._get_source_line(lineno)
|
|
src_file: str = Gen._current_source_file or ''
|
|
src_path: str = src_file if src_file else 'unknown'
|
|
line_info: str = "源代码 (%s, line %d)" % (src_path, lineno)
|
|
if source_line:
|
|
line_info += ":\n %d | %s" % (lineno, source_line)
|
|
self.Trans._ErrorStack.append((type(e).__name__, str(e), line_info))
|
|
raise
|
|
if Gen.builder and not Gen.builder.block.is_terminated:
|
|
Gen._EmitTempFrees()
|
|
|
|
def HandleExprLlvm(self, Node: ast.expr, VarType: ir.Type | None = None,
|
|
ConstWidthHint: int | None = None) -> ir.Value | None:
|
|
return self.Trans.ExprHandler.HandleExprLlvm(Node, VarType, ConstWidthHint) |