This commit is contained in:
2026-07-30 13:34:26 +08:00
parent a2cc28a6ab
commit f79c8ca643
43 changed files with 1690 additions and 1016 deletions

View File

@@ -464,7 +464,11 @@ def release(args: ParsedArgs | t.CPtr):
if args.__mbuddy__ is None:
return
if args._ht is not None:
if args._ht.__slots__ is not None:
args.__mbuddy__.free(args._ht.__slots__)
args.__mbuddy__.free(t.CVoid(t.CUInt64T(args._ht), t.CPtr))
# 用临时变量拆分链式属性访问,避免 args._ht.__slots__ 跨模块类型推断失败
# 注意:类型注解必须用 hashtable.HashTable带模块前缀
# 否则编译器无法解析 HashTable 类型,导致 ht.__slots__ 属性访问失败
ht: hashtable.HashTable | t.CPtr = args._ht
if ht.__slots__ is not None:
args.__mbuddy__.free(ht.__slots__)
args.__mbuddy__.free(t.CVoid(t.CUInt64T(ht), t.CPtr))
args.__mbuddy__.free(t.CVoid(t.CUInt64T(args), t.CPtr))

View File

@@ -1740,7 +1740,7 @@ def _parse_if(ps: Parser | t.CPtr) -> AST | t.CPtr:
_expect_op(ps, TokOp.Colon)
# 先用空 orelse 构造,后面填充
empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
node: AST | t.CPtr = If(ps.pool, test, empty)
node: If | t.CPtr = If(ps.pool, test, empty)
_parse_suite_into_children(ps, node)
orelse: list[AST | t.CPtr] | t.CPtr = _parse_if_tail(ps)
node.orelse = orelse
@@ -1761,7 +1761,7 @@ def _parse_if_tail(ps: Parser | t.CPtr) -> list[AST | t.CPtr] | t.CPtr:
elif_test: AST | t.CPtr = _parse_test(ps)
_expect_op(ps, TokOp.Colon)
empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
elif_node: AST | t.CPtr = If(ps.pool, elif_test, empty)
elif_node: If | t.CPtr = If(ps.pool, elif_test, empty)
_parse_suite_into_children(ps, elif_node)
elif_orelse: list[AST | t.CPtr] | t.CPtr = _parse_if_tail(ps)
elif_node.orelse = elif_orelse
@@ -1789,7 +1789,7 @@ def _parse_while(ps: Parser | t.CPtr) -> AST | t.CPtr:
test: AST | t.CPtr = _parse_test(ps)
_expect_op(ps, TokOp.Colon)
empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
node: AST | t.CPtr = While(ps.pool, test, empty)
node: While | t.CPtr = While(ps.pool, test, empty)
_parse_suite_into_children(ps, node)
if _cur_kw(ps) == Keyword.Else:
_advance(ps)
@@ -1813,7 +1813,7 @@ def _parse_for(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
iter_: AST | t.CPtr = _parse_or_test(ps)
_expect_op(ps, TokOp.Colon)
empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
node: AST | t.CPtr = For(ps.pool, target, iter_, empty, is_async)
node: For | t.CPtr = For(ps.pool, target, iter_, empty, is_async)
_fix_store_ctx(target)
_parse_suite_into_children(ps, node)
if _cur_kw(ps) == Keyword.Else:
@@ -1832,7 +1832,7 @@ def _parse_try(ps: Parser | t.CPtr) -> AST | t.CPtr:
_advance(ps) # try
_expect_op(ps, TokOp.Colon)
empty: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
node: AST | t.CPtr = Try(ps.pool, empty, empty, empty)
node: Try | t.CPtr = Try(ps.pool, empty, empty, empty)
_parse_suite_into_children(ps, node)
# handlers (except)
handlers: list[AST | t.CPtr] | t.CPtr = list[AST | t.CPtr](ps.pool, 8)
@@ -1895,7 +1895,7 @@ def _parse_with(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
if _cur_type(ps) == TokenType.NewLine or _cur_type(ps) == TokenType.Nl:
break
_expect_op(ps, TokOp.Colon)
node: AST | t.CPtr = With(ps.pool, items, is_async)
node: With | t.CPtr = With(ps.pool, items, is_async)
_parse_suite_into_children(ps, node)
_set_pos(node, lineno, col, 0, 0)
return node
@@ -1936,7 +1936,7 @@ def _parse_funcdef(ps: Parser | t.CPtr, is_async: t.CInt) -> AST | t.CPtr:
_expect_op(ps, TokOp.Colon)
dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators
ps.pending_decorators = None
node: AST | t.CPtr = FunctionDef(ps.pool, name, args, dec_list, returns, is_async)
node: FunctionDef | t.CPtr = FunctionDef(ps.pool, name, args, dec_list, returns, is_async)
_parse_suite_into_children(ps, node)
_set_pos(node, lineno, col, 0, 0)
return node
@@ -1991,7 +1991,7 @@ def _parse_classdef(ps: Parser | t.CPtr) -> AST | t.CPtr:
_expect_op(ps, TokOp.Colon)
dec_list: list[AST | t.CPtr] | t.CPtr = ps.pending_decorators
ps.pending_decorators = None
node: AST | t.CPtr = ClassDef(ps.pool, name, bases, keywords, dec_list, type_params)
node: ClassDef | t.CPtr = ClassDef(ps.pool, name, bases, keywords, dec_list, type_params)
_parse_suite_into_children(ps, node)
_set_pos(node, lineno, col, 0, 0)
return node
@@ -2380,6 +2380,6 @@ def parse_tokens(pool: memhub.MemManager | t.CPtr,
ps: Parser | t.CPtr = new_parser(pool)
if ps is None: return None
_parser_init(ps, tokens, pool)
module_node: AST | t.CPtr = Module(pool)
module_node: Module | t.CPtr = Module(pool)
_parse_module_body(ps, module_node)
return module_node

View File

@@ -13,9 +13,8 @@ def __atomic_test_and_set(ptr: t.CUInt64T | t.CPtr, order: t.CInt) -> t.CBool:
result: t.CUInt8T = 1
c.Asm(f"""mov al, 1
xchg byte ptr [{c.AsmInp(ptr, t.ASM_DESCR.REG_ANY)}], al
mov {c.AsmOut(result, t.ASM_DESCR.OUTPUT_REG)}, al""",
mov $0, al""",
out = [c.AsmOut(result, t.ASM_DESCR.OUTPUT_REG)],
inp = [c.AsmInp(ptr, t.ASM_DESCR.REG_ANY)],
op = [t.ASM_DESCR.CLOBBER_MEMORY, t.ASM_DESCR.CLOBBER_RAX])
return t.CBool(result)

View File

@@ -7,7 +7,7 @@ import stdio
from linkedlist import GSListNode, GSList
from .__types import LLVMType, TypePrint
from .__values import Value, new_value, SSAValue
from .__function import Function, BasicBlock, block_append_text, function_move_block_to_end, _ll_name_needs_quote
from .__function import Function, BasicBlock, block_append_text, block_set_terminated, block_get_terminated, function_move_block_to_end, _ll_name_needs_quote
# ============================================================
# IRBuilder: 游标式 IR 指令发射器
@@ -104,20 +104,19 @@ def _emit(builder: IRBuilder | t.CPtr, text: t.CChar | t.CPtr):
def _mark_terminated(builder: IRBuilder | t.CPtr):
"""标记当前块已终止"""
if builder is None or builder.CurBlock is None: return
builder.CurBlock.IsTerminated = 1
block_set_terminated(builder.CurBlock, 1)
def builder_cur_block_is_terminated(builder: IRBuilder | t.CPtr) -> t.CInt:
"""检查当前块的 IsTerminated 标志
供其他模块绕过 stub 类型限制使用:
builder.CurBlock.IsTerminated 在 stub 类型中 BasicBlock 为 opaque
直接访问会被 TransPyC 静默跳过(不生成 GEP不报错
导致返回寄存器残留值br 回边指令被错误跳过。
通过 block_get_terminated 辅助函数访问,避免链式属性
builder.CurBlock.IsTerminated 在跨模块场景下 BasicBlock 为 opaque
导致的 GEP 静默跳过问题。
"""
if builder is None or builder.CurBlock is None:
return 1
return builder.CurBlock.IsTerminated
return block_get_terminated(builder.CurBlock)
# ============================================================

View File

@@ -218,6 +218,19 @@ def block_append_line(block: BasicBlock | t.CPtr, line: Line | t.CPtr):
block.Lines.append(line)
def block_set_terminated(block: BasicBlock | t.CPtr, val: t.CInt):
"""设置块的终止标志(供跨模块调用,避免链式属性访问的 opaque 类型问题)"""
if block is None: return
block.IsTerminated = val
def block_get_terminated(block: BasicBlock | t.CPtr) -> t.CInt:
"""获取块的终止标志(供跨模块调用,避免链式属性访问的 opaque 类型问题)"""
if block is None:
return 1
return block.IsTerminated
def block_append_text(pool: memhub.MemBuddy | t.CPtr, block: BasicBlock | t.CPtr,
text: t.CChar | t.CPtr):
"""创建指令行并追加到基本块"""