Fixed
This commit is contained in:
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -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):
|
||||
"""创建指令行并追加到基本块"""
|
||||
|
||||
Reference in New Issue
Block a user