feat(coro): M7——try/finally、异常消息、自定义异常类、帧池复用
- try/finally(无 except):正常/异常路径都执行 fbody,异常时 finally 后 重新传播(done+br exit);finally 内暂不支持 await - 异常消息:帧加 msg 槽(i8*,index 4),raise X(msg) 存消息,await 传播, coro_exception_msg 查询 - raise 支持自定义异常类(exception_registry 码),多 except 匹配子类码 - 帧池复用:per-type free-list 全局池,create 弹池/空则 malloc,coro_destroy 回池(帧头部存 next),避免反复 malloc/free - 修复 ast.walk 传 list 崩溃(finalbody/For body) - CoroTest 验证:finally 执行、MyError exc=100 msg=boom msg、3 次循环池复用
This commit is contained in:
1 parent
8b9e88287a
commit
8ce08493e8
4 files changed
+191
-40
No files matched your search
+23
-20
@@ -4,35 +4,38 @@ import stdio
|
||||
import coro
|
||||
|
||||
|
||||
class MyError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
async def leaf(x: int) -> int:
|
||||
return x + 1
|
||||
|
||||
|
||||
async def boom(kind: int) -> int:
|
||||
if kind == 1:
|
||||
raise ValueError
|
||||
raise KeyError
|
||||
async def boom() -> int:
|
||||
raise MyError("boom msg")
|
||||
return 0
|
||||
|
||||
|
||||
async def task(kind: int) -> int:
|
||||
caught: int = 0
|
||||
async def task() -> int:
|
||||
fin: int = 0
|
||||
try:
|
||||
await boom(kind)
|
||||
except ValueError as e:
|
||||
caught = 1
|
||||
except KeyError:
|
||||
caught = 2
|
||||
return caught
|
||||
fin = 1
|
||||
await boom()
|
||||
finally:
|
||||
fin = fin + 1
|
||||
stdio.printf("finally ran, fin = %d\n", fin)
|
||||
return 99
|
||||
|
||||
|
||||
def main() -> t.CInt:
|
||||
a: coro.Coroutine = task(1)
|
||||
b: coro.Coroutine = task(2)
|
||||
n: t.CInt = coro.coro_gather(a, b)
|
||||
r1: t.CInt = coro.coro_run(a)
|
||||
r2: t.CInt = coro.coro_run(b)
|
||||
stdio.printf("gather = %d, r1 = %d, r2 = %d\n", n, r1, r2)
|
||||
coro.coro_destroy(a)
|
||||
coro.coro_destroy(b)
|
||||
n: t.CInt = 0
|
||||
for i in range(3):
|
||||
tt: coro.Coroutine = task()
|
||||
r: t.CInt = coro.coro_run(tt)
|
||||
e: t.CInt = coro.coro_exception(tt)
|
||||
m: t.CPtr = coro.coro_exception_msg(tt)
|
||||
stdio.printf("[%d] r = %d, exc = %d, msg = %s\n", i, r, e, m)
|
||||
coro.coro_destroy(tt)
|
||||
n = n + 1
|
||||
return 0
|
||||
@@ -44,3 +44,7 @@ def coro_exception(c: Coroutine) -> t.CInt:
|
||||
def coro_gather(a: Coroutine) -> t.CInt:
|
||||
# M4 占位:编译器将 coro.coro_gather(帧...) 内联翻译为并发推进循环。
|
||||
return 0
|
||||
|
||||
def coro_exception_msg(c: Coroutine) -> t.CPtr:
|
||||
# M7 占位:编译器将 coro.coro_exception_msg(帧) 内联翻译为帧 msg 槽读取。
|
||||
return null
|
||||
@@ -18,7 +18,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
- coro_destroy(帧):释放帧内存(free)。
|
||||
M2 能力:async 参数、嵌套 await 提升(__await_N 槽)、If/While 控制流、动态状态号恢复块。
|
||||
|
||||
帧布局:%Coro_<name> = type { i32 state, i32 done, i32 ret, i32 exc, <参数槽>, <局部槽>, <额外槽(wake/for/await)> }
|
||||
帧布局:%Coro_<name> = type { i32 state, i32 done, i32 ret, i32 exc, i8* msg, <参数槽>, <局部槽>, <额外槽(wake/for/await)> }
|
||||
状态机:create_<name>(args...) 分配帧 + 存参数;resume_<name>(frame) -> i32
|
||||
(0=SUSPEND 1=DONE)按 state 分发到主入口 state0 与各恢复块。
|
||||
"""
|
||||
@@ -97,6 +97,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
'wake_ptr': getattr(Gen, '_coro_wake_ptr', None),
|
||||
'exc_ptr': getattr(Gen, '_coro_exc_ptr', None),
|
||||
'try_stack': getattr(Gen, '_coro_try_stack', None),
|
||||
'msg_ptr': getattr(Gen, '_coro_msg_ptr', None),
|
||||
}
|
||||
try:
|
||||
self.Trans.VarScopes.append({})
|
||||
@@ -141,6 +142,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
Gen._coro_wake_ptr = saved_coro_state['wake_ptr']
|
||||
Gen._coro_exc_ptr = saved_coro_state['exc_ptr']
|
||||
Gen._coro_try_stack = saved_coro_state['try_stack']
|
||||
Gen._coro_msg_ptr = saved_coro_state['msg_ptr']
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 帧结构体与局部变量收集
|
||||
@@ -243,6 +245,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
ir.IntType(32), # 1: done
|
||||
ir.IntType(32), # 2: ret
|
||||
ir.IntType(32), # 3: exc(异常码,0=无异常)
|
||||
ir.PointerType(ir.IntType(8)), # 4: msg(异常消息,null=无)
|
||||
]
|
||||
slot_vars: list[str] = []
|
||||
for pname, pty in params:
|
||||
@@ -336,6 +339,17 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
# create_<name>(args...) -> %Coro_<name>*
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _GetCoroPool(self, name: str, Gen: LlvmCodeGenerator) -> ir.GlobalVariable:
|
||||
"""每帧类型的全局 free-list 池头(i8*),跨 create/destroy 复用帧内存。"""
|
||||
pool_name: str = f'coro_pool_{Gen._mangle_func_name(name)}'
|
||||
for gv in Gen.module.global_values:
|
||||
if getattr(gv, 'name', None) == pool_name:
|
||||
return gv
|
||||
gv: ir.GlobalVariable = ir.GlobalVariable(Gen.module, ir.PointerType(ir.IntType(8)), pool_name)
|
||||
gv.initializer = ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
gv.linkage = 'internal'
|
||||
return gv
|
||||
|
||||
def _GetMalloc(self, Gen: LlvmCodeGenerator) -> ir.Function:
|
||||
for fn in Gen.module.global_values:
|
||||
if getattr(fn, 'name', None) == 'malloc':
|
||||
@@ -364,19 +378,45 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
entry: ir.Block = create_fn.append_basic_block('entry')
|
||||
Gen.builder = ir.IRBuilder(entry)
|
||||
Gen.func = create_fn
|
||||
raw: ir.Value = Gen.builder.call(malloc_fn, [ir.Constant(ir.IntType(64), frame_size)], name='frame_raw')
|
||||
frame_ptr: ir.Value = Gen.builder.bitcast(raw, ir.PointerType(frame_ty), name='frame')
|
||||
zero32: ir.Constant = ir.Constant(ir.IntType(32), 0)
|
||||
null_i8p: ir.Constant = ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
# 帧池:pop(非空则复用,空则 malloc)
|
||||
pool_gv: ir.GlobalVariable = self._GetCoroPool(name, Gen)
|
||||
pool_head: ir.Value = Gen.builder.load(pool_gv, name='pool_head')
|
||||
pool_hit_bb: ir.Block = create_fn.append_basic_block('pool_hit')
|
||||
pool_miss_bb: ir.Block = create_fn.append_basic_block('pool_miss')
|
||||
join_bb: ir.Block = create_fn.append_basic_block('pool_join')
|
||||
head_is_null: ir.Value = Gen.builder.icmp_signed('==', pool_head, null_i8p, name='pool_empty')
|
||||
Gen.builder.cbranch(head_is_null, pool_miss_bb, pool_hit_bb)
|
||||
# pool_hit:弹出一个池节点(帧头部存 next)
|
||||
Gen.builder.position_at_start(pool_hit_bb)
|
||||
next_head: ir.Value = Gen.builder.load(
|
||||
Gen.builder.bitcast(pool_head, ir.PointerType(ir.PointerType(ir.IntType(8))), name='pool_node_next_ptr'),
|
||||
name='pool_next')
|
||||
Gen.builder.store(next_head, pool_gv)
|
||||
hit_frame: ir.Value = Gen.builder.bitcast(pool_head, ir.PointerType(frame_ty), name='frame')
|
||||
Gen.builder.branch(join_bb)
|
||||
# pool_miss:malloc + 状态清零
|
||||
Gen.builder.position_at_start(pool_miss_bb)
|
||||
raw: ir.Value = Gen.builder.call(malloc_fn, [ir.Constant(ir.IntType(64), frame_size)], name='frame_raw')
|
||||
miss_frame: ir.Value = Gen.builder.bitcast(raw, ir.PointerType(frame_ty), name='frame')
|
||||
for i in range(4):
|
||||
slot_ptr: ir.Value = Gen.builder.gep(frame_ptr, [zero32, ir.Constant(ir.IntType(32), i)], name=f'init_slot{i}')
|
||||
slot_ptr: ir.Value = Gen.builder.gep(miss_frame, [zero32, ir.Constant(ir.IntType(32), i)], name=f'init_slot{i}')
|
||||
Gen._store(zero32, slot_ptr)
|
||||
# 参数存入帧槽(4 + i)
|
||||
msg_slot: ir.Value = Gen.builder.gep(miss_frame, [zero32, ir.Constant(ir.IntType(32), 4)], name='init_msg_slot')
|
||||
Gen._store(null_i8p, msg_slot)
|
||||
Gen.builder.branch(join_bb)
|
||||
# join:phi 选择帧 + 参数存入(池取/新建都要写参数槽)
|
||||
Gen.builder.position_at_start(join_bb)
|
||||
frame_phi: Any = Gen.builder.phi(ir.PointerType(frame_ty), name='frame')
|
||||
frame_phi.add_incoming(hit_frame, pool_hit_bb)
|
||||
frame_phi.add_incoming(miss_frame, pool_miss_bb)
|
||||
for i in range(len(params)):
|
||||
slot_ptr = Gen.builder.gep(frame_ptr, [zero32, ir.Constant(ir.IntType(32), 4 + i)], name=f'param{i}_slot')
|
||||
slot_ptr = Gen.builder.gep(frame_phi, [zero32, ir.Constant(ir.IntType(32), 5 + i)], name=f'param{i}_slot')
|
||||
arg_val: ir.Argument = create_fn.args[i]
|
||||
arg_val.name = f'arg{i}'
|
||||
Gen._store(arg_val, slot_ptr)
|
||||
Gen.builder.ret(frame_ptr)
|
||||
Gen.builder.ret(frame_phi)
|
||||
Gen.builder = None
|
||||
Gen.func = None
|
||||
|
||||
@@ -406,7 +446,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
for idx, var in enumerate(slot_vars):
|
||||
slot_ptr: ir.Value = Gen.builder.gep(
|
||||
frame_arg,
|
||||
[zero32, ir.Constant(ir.IntType(32), 4 + idx)],
|
||||
[zero32, ir.Constant(ir.IntType(32), 5 + idx)],
|
||||
name=f'{var}_slot',
|
||||
)
|
||||
local_slot_ptrs[var] = slot_ptr
|
||||
@@ -419,6 +459,8 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
Gen._coro_ret_field_ptr = ret_ptr
|
||||
exc_ptr: ir.Value = Gen.builder.gep(frame_arg, [zero32, ir.Constant(ir.IntType(32), 3)], name='exc_ptr')
|
||||
Gen._coro_exc_ptr = exc_ptr
|
||||
msg_ptr: ir.Value = Gen.builder.gep(frame_arg, [zero32, ir.Constant(ir.IntType(32), 4)], name='msg_ptr')
|
||||
Gen._coro_msg_ptr = msg_ptr
|
||||
Gen._coro_exit_bb = exit_bb
|
||||
Gen._coro_frame_ptr = frame_arg
|
||||
switch_instr: Any = Gen.builder.switch(state_val, exit_bb)
|
||||
@@ -475,7 +517,10 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
self._HandleCoroWhile(stmt, Gen)
|
||||
continue
|
||||
if isinstance(stmt, ast.Try):
|
||||
self._HandleCoroTry(stmt, Gen)
|
||||
if stmt.finalbody and not stmt.handlers:
|
||||
self._HandleCoroTryFinally(stmt, Gen)
|
||||
else:
|
||||
self._HandleCoroTry(stmt, Gen)
|
||||
continue
|
||||
if isinstance(stmt, ast.For):
|
||||
self._HandleCoroFor(stmt, Gen)
|
||||
@@ -683,24 +728,32 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
frame_ptr = Gen.builder.inttoptr(frame_val, ir.PointerType(frame_ty), name='coro_frame')
|
||||
else:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
free_fn: ir.Function = self._GetFree(Gen)
|
||||
raw: ir.Value = Gen.builder.bitcast(frame_ptr, ir.IntType(8).as_pointer(), name='coro_free_ptr')
|
||||
Gen.builder.call(free_fn, [raw])
|
||||
# 帧回池(free-list):帧头部存当前池头,池头指向本帧
|
||||
pool_gv: ir.GlobalVariable = self._GetCoroPool(async_name, Gen)
|
||||
pool_head: ir.Value = Gen.builder.load(pool_gv, name='pool_head')
|
||||
node_next_ptr: ir.Value = Gen.builder.bitcast(
|
||||
frame_ptr, ir.PointerType(ir.PointerType(ir.IntType(8))), name='pool_node_next')
|
||||
Gen.builder.store(pool_head, node_next_ptr)
|
||||
Gen.builder.store(
|
||||
Gen.builder.bitcast(frame_ptr, ir.IntType(8).as_pointer(), name='pool_node'), pool_gv)
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
|
||||
def _ResolveRaiseCode(self, exc_node: ast.expr) -> int | None:
|
||||
"""解析 raise 目标的异常类型码(注册类/内置异常);普通表达式返回 None 走值路径。"""
|
||||
def _ResolveRaiseInfo(self, exc_node: ast.expr) -> tuple[int, ast.expr | None] | None:
|
||||
"""解析 raise 目标的异常类型(返回 (异常码, 消息表达式));普通表达式返回 None 走值路径。"""
|
||||
name: str | None = None
|
||||
msg_node: ast.expr | None = None
|
||||
if isinstance(exc_node, ast.Name):
|
||||
name = exc_node.id
|
||||
elif isinstance(exc_node, ast.Call) and isinstance(exc_node.func, ast.Name):
|
||||
name = exc_node.func.id
|
||||
if exc_node.args:
|
||||
msg_node = exc_node.args[0]
|
||||
elif isinstance(exc_node, ast.Attribute):
|
||||
name = exc_node.attr
|
||||
if name:
|
||||
if name in EXCEPTION_CODE_MAP or name in getattr(self.Trans, 'exception_registry', {}):
|
||||
try:
|
||||
return self.Trans.RaiseHandler._get_exception_code(name)
|
||||
return (self.Trans.RaiseHandler._get_exception_code(name), msg_node)
|
||||
except Exception:
|
||||
return None
|
||||
return None
|
||||
@@ -710,9 +763,15 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
exc_code: ir.Value = ir.Constant(ir.IntType(32), 1)
|
||||
if stmt.exc is not None:
|
||||
v: ir.Value | None = None
|
||||
resolved: int | None = self._ResolveRaiseCode(stmt.exc)
|
||||
resolved: tuple[int, ast.expr | None] | None = self._ResolveRaiseInfo(stmt.exc)
|
||||
if resolved is not None:
|
||||
exc_code = ir.Constant(ir.IntType(32), resolved)
|
||||
exc_code = ir.Constant(ir.IntType(32), resolved[0])
|
||||
msg_node: ast.expr | None = resolved[1]
|
||||
if msg_node is not None:
|
||||
msg_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(msg_node)
|
||||
msg_ptr_r: ir.Value | None = getattr(Gen, '_coro_msg_ptr', None)
|
||||
if msg_val is not None and isinstance(msg_val.type, ir.PointerType) and msg_ptr_r is not None:
|
||||
Gen._store(msg_val, msg_ptr_r)
|
||||
else:
|
||||
v = self.Trans.ExprHandler.HandleExprLlvm(stmt.exc)
|
||||
if v is not None:
|
||||
@@ -768,6 +827,35 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
)
|
||||
return Gen._load(exc_ptr, name='coro_exc')
|
||||
|
||||
def _HandleCoroExceptionMsgLlvm(self, Node: ast.Call, Gen: LlvmCodeGenerator) -> ir.Value:
|
||||
"""coro.coro_exception_msg(帧):返回帧 msg 槽(异常消息指针,null=无)。"""
|
||||
if not Node.args:
|
||||
return ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
arg: ast.expr = Node.args[0]
|
||||
async_name: str | None = None
|
||||
if isinstance(arg, ast.Name):
|
||||
async_name = getattr(Gen, '_coro_var_async', {}).get(arg.id)
|
||||
if not async_name:
|
||||
return ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
frame_ty: ir.IdentifiedStructType | None = getattr(Gen, '_coro_frame_types', {}).get(async_name)
|
||||
if not frame_ty:
|
||||
return ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
frame_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(arg)
|
||||
if frame_val is None:
|
||||
return ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
if isinstance(frame_val.type, ir.PointerType):
|
||||
frame_ptr: ir.Value = Gen.builder.bitcast(frame_val, ir.PointerType(frame_ty), name='coro_frame')
|
||||
elif isinstance(frame_val.type, ir.IntType):
|
||||
frame_ptr = Gen.builder.inttoptr(frame_val, ir.PointerType(frame_ty), name='coro_frame')
|
||||
else:
|
||||
return ir.Constant(ir.PointerType(ir.IntType(8)), None)
|
||||
msg_ptr: ir.Value = Gen.builder.gep(
|
||||
frame_ptr,
|
||||
[ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 4)],
|
||||
name='coro_msg_ptr',
|
||||
)
|
||||
return Gen._load(msg_ptr, name='coro_msg')
|
||||
|
||||
def _CoerceArg(self, v: ir.Value | None, target_ty: ir.Type, Gen: LlvmCodeGenerator, name: str = 'arg') -> ir.Value:
|
||||
"""实参转换到 create 形参类型(int 宽转换 / 指针 bitcast)。"""
|
||||
if v is None:
|
||||
@@ -837,6 +925,15 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
parent_exc_ptr: ir.Value | None = getattr(Gen, '_coro_exc_ptr', None)
|
||||
if parent_exc_ptr is not None:
|
||||
Gen._store(child_exc, parent_exc_ptr)
|
||||
child_msg_ptr: ir.Value = Gen.builder.gep(
|
||||
child,
|
||||
[zero32, ir.Constant(ir.IntType(32), 4)],
|
||||
name='child_msg_ptr',
|
||||
)
|
||||
child_msg: ir.Value = Gen._load(child_msg_ptr, name='child_msg')
|
||||
parent_msg_ptr: ir.Value | None = getattr(Gen, '_coro_msg_ptr', None)
|
||||
if parent_msg_ptr is not None:
|
||||
Gen._store(child_msg, parent_msg_ptr)
|
||||
coro_try: list[ir.Block] | None = getattr(Gen, '_coro_try_stack', None)
|
||||
if coro_try:
|
||||
Gen.builder.branch(coro_try[-1])
|
||||
@@ -1058,6 +1155,49 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
else:
|
||||
Gen.builder.position_at_end(merge_bb)
|
||||
|
||||
def _HandleCoroTryFinally(self, Node: ast.Try, Gen: LlvmCodeGenerator) -> None:
|
||||
"""协程内 try/finally(无 except):正常/异常路径都执行 fbody;
|
||||
异常时 finally 后重新传播(done=1 + br exit);finally 内暂不支持 await。"""
|
||||
if any(isinstance(n, ast.Await) for s in Node.finalbody for n in ast.walk(s)):
|
||||
raise SyntaxError(
|
||||
f"[coro-M7] finally 内暂不支持 await (line {getattr(Node, 'lineno', 0)})"
|
||||
)
|
||||
fin_bb: ir.Block = Gen.func.append_basic_block('coro_fin')
|
||||
fin_exc_bb: ir.Block = Gen.func.append_basic_block('coro_fin_exc')
|
||||
merge_bb: ir.Block = Gen.func.append_basic_block('coro_fin_merge')
|
||||
if not getattr(Gen, '_coro_try_stack', None):
|
||||
Gen._coro_try_stack = []
|
||||
Gen._coro_try_stack.append(fin_bb)
|
||||
self._HandleCoroSegment(Node.body, Gen)
|
||||
if Gen.builder is not None and not Gen.builder.block.is_terminated:
|
||||
Gen.builder.branch(fin_bb)
|
||||
Gen._coro_try_stack.pop()
|
||||
# fin_bb:记录异常标志,执行 fbody
|
||||
Gen.builder.position_at_start(fin_bb)
|
||||
exc_ptr_f: ir.Value | None = getattr(Gen, '_coro_exc_ptr', None)
|
||||
if exc_ptr_f is not None:
|
||||
was_exc: ir.Value = Gen.builder.icmp_signed(
|
||||
'!=', Gen._load(exc_ptr_f, name='coro_fin_exc'),
|
||||
ir.Constant(ir.IntType(32), 0), name='coro_fin_was_exc')
|
||||
else:
|
||||
was_exc = ir.Constant(ir.IntType(1), 0)
|
||||
self._HandleCoroSegment(Node.finalbody, Gen)
|
||||
if Gen.builder is not None and not Gen.builder.block.is_terminated:
|
||||
Gen.builder.cbranch(was_exc, fin_exc_bb, merge_bb)
|
||||
# fin_exc_bb:finally 后异常继续传播
|
||||
Gen.builder.position_at_start(fin_exc_bb)
|
||||
if not fin_exc_bb.is_terminated:
|
||||
done_ptr_f: ir.Value | None = getattr(Gen, '_coro_done_ptr', None)
|
||||
if done_ptr_f is not None:
|
||||
Gen._store(ir.Constant(ir.IntType(32), 1), done_ptr_f)
|
||||
exit_bb_f: ir.Block | None = getattr(Gen, '_coro_exit_bb', None)
|
||||
if exit_bb_f is not None:
|
||||
Gen.builder.branch(exit_bb_f)
|
||||
if not merge_bb.is_terminated:
|
||||
Gen.builder.position_at_start(merge_bb)
|
||||
else:
|
||||
Gen.builder.position_at_end(merge_bb)
|
||||
|
||||
def _HandleCoroFor(self, Node: ast.For, Gen: LlvmCodeGenerator) -> None:
|
||||
if any(isinstance(n, ast.Await) for n in ast.walk(Node)):
|
||||
if not self._IsRangeFor(Node):
|
||||
@@ -1067,7 +1207,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
)
|
||||
self._HandleCoroForRange(Node, Gen)
|
||||
return
|
||||
if any(isinstance(n, ast.Return) for n in ast.walk(Node.body)):
|
||||
if any(isinstance(n, ast.Return) for st in Node.body for n in ast.walk(st)):
|
||||
raise SyntaxError(
|
||||
f"[coro-M2] For 循环体内暂不支持 return(M3 实现)(line {getattr(Node, 'lineno', 0)})"
|
||||
)
|
||||
@@ -1185,7 +1325,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
slot_vars: list[str] = getattr(Gen, '_coro_slot_vars', {}).get(async_name, [])
|
||||
wake_idx: int | None = None
|
||||
if '__coro_wake_us' in slot_vars:
|
||||
wake_idx = 4 + slot_vars.index('__coro_wake_us')
|
||||
wake_idx = 5 + slot_vars.index('__coro_wake_us')
|
||||
if wake_idx is not None:
|
||||
wsleep_bb: ir.Block = Gen.func.append_basic_block('gather_wsleep')
|
||||
wdue_bb: ir.Block = Gen.func.append_basic_block('gather_wdue')
|
||||
@@ -1248,7 +1388,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
wake_idx: int | None = None
|
||||
slot_vars: list[str] = getattr(Gen, '_coro_slot_vars', {}).get(async_name, [])
|
||||
if '__coro_wake_us' in slot_vars:
|
||||
wake_idx = 4 + slot_vars.index('__coro_wake_us')
|
||||
wake_idx = 5 + slot_vars.index('__coro_wake_us')
|
||||
if wake_idx is not None:
|
||||
wake_wait_bb: ir.Block = Gen.func.append_basic_block('coro_wsleep')
|
||||
wake_due_bb: ir.Block = Gen.func.append_basic_block('coro_wdue')
|
||||
|
||||
@@ -286,6 +286,10 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(Node.func, ast.Attribute) and Node.func.attr == 'coro_exception':
|
||||
if isinstance(Node.func.value, ast.Name) and self.Trans.AsyncHandler._IsCoroModule(Node.func.value.id):
|
||||
return self.Trans.AsyncHandler._HandleCoroExceptionLlvm(Node, Gen)
|
||||
# 协程:coro.coro_exception_msg(帧) 内联翻译为帧 msg 槽读取
|
||||
if isinstance(Node.func, ast.Attribute) and Node.func.attr == 'coro_exception_msg':
|
||||
if isinstance(Node.func.value, ast.Name) and self.Trans.AsyncHandler._IsCoroModule(Node.func.value.id):
|
||||
return self.Trans.AsyncHandler._HandleCoroExceptionMsgLlvm(Node, Gen)
|
||||
# 协程:coro.coro_gather(帧...) 内联翻译为并发推进循环
|
||||
if isinstance(Node.func, ast.Attribute) and Node.func.attr == 'coro_gather':
|
||||
if isinstance(Node.func.value, ast.Name) and self.Trans.AsyncHandler._IsCoroModule(Node.func.value.id):
|
||||
|
||||
Reference in new issue
Block a user