feat(coro): M4——异常传播(帧 exc 槽 + raise + await 传播)+ gather 并发调度
- 帧布局加固定 exc 槽(i32,0=无异常),协程内 raise 存异常码并终止 - await 子协程后检测异常并传播到父帧(父协程带异常终止,状态机短路) - return await x:await 值直接存父帧 ret 槽(挂起前),修复 child_ret 跨块 dominate 错误;挂起不再写 ret=0(避免覆盖返回值) - coro.coro_gather(帧...):并发推进全部协程到完成(含 coro_sleep 轮询), 返回完成数 - coro.vp 追加 coro_exception/coro_gather 占位 - CoroTest 验证:异常传播 exc=42;gather=2 r1=2 r2=3
This commit is contained in:
1 parent
c979f0f94d
commit
411e0bb774
4 files changed
+201
-26
No files matched your search
+14
-10
@@ -8,17 +8,21 @@ async def leaf(x: int) -> int:
|
||||
return x + 1
|
||||
|
||||
|
||||
async def task(base: int) -> int:
|
||||
s: int = 0
|
||||
for i in range(base):
|
||||
s = s + await leaf(i)
|
||||
await coro_sleep(100)
|
||||
return s
|
||||
async def t1() -> int:
|
||||
return await leaf(1)
|
||||
|
||||
|
||||
async def t2() -> int:
|
||||
return await leaf(2)
|
||||
|
||||
|
||||
def main() -> t.CInt:
|
||||
tt: coro.Coroutine = task(5)
|
||||
r: t.CInt = coro.coro_run(tt)
|
||||
stdio.printf("coro result = %d\n", r)
|
||||
coro.coro_destroy(tt)
|
||||
a: coro.Coroutine = t1()
|
||||
b: coro.Coroutine = t2()
|
||||
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)
|
||||
return 0
|
||||
@@ -36,3 +36,11 @@ def coro_sleep(ms: t.CInt) -> t.CInt:
|
||||
def coro_destroy(c: Coroutine) -> t.CVoid:
|
||||
# M3 占位:编译器将 coro.coro_destroy(帧) 内联翻译为 free。
|
||||
return
|
||||
|
||||
def coro_exception(c: Coroutine) -> t.CInt:
|
||||
# M4 占位:编译器将 coro.coro_exception(帧) 内联翻译为帧 exc 槽读取。
|
||||
return 0
|
||||
|
||||
def coro_gather(a: Coroutine) -> t.CInt:
|
||||
# M4 占位:编译器将 coro.coro_gather(帧...) 内联翻译为并发推进循环。
|
||||
return 0
|
||||
@@ -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, <参数槽>, <局部槽>, <额外槽(wake/for/await)> }
|
||||
帧布局:%Coro_<name> = type { i32 state, i32 done, i32 ret, i32 exc, <参数槽>, <局部槽>, <额外槽(wake/for/await)> }
|
||||
状态机:create_<name>(args...) 分配帧 + 存参数;resume_<name>(frame) -> i32
|
||||
(0=SUSPEND 1=DONE)按 state 分发到主入口 state0 与各恢复块。
|
||||
"""
|
||||
@@ -95,6 +95,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
'hoist_counter': getattr(Gen, '_coro_hoist_counter', None),
|
||||
'for_counter': getattr(Gen, '_coro_for_counter', None),
|
||||
'wake_ptr': getattr(Gen, '_coro_wake_ptr', None),
|
||||
'exc_ptr': getattr(Gen, '_coro_exc_ptr', None),
|
||||
}
|
||||
try:
|
||||
self.Trans.VarScopes.append({})
|
||||
@@ -137,6 +138,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
Gen._coro_hoist_counter = saved_coro_state['hoist_counter']
|
||||
Gen._coro_for_counter = saved_coro_state['for_counter']
|
||||
Gen._coro_wake_ptr = saved_coro_state['wake_ptr']
|
||||
Gen._coro_exc_ptr = saved_coro_state['exc_ptr']
|
||||
|
||||
# ------------------------------------------------------------------
|
||||
# 帧结构体与局部变量收集
|
||||
@@ -224,6 +226,7 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
ir.IntType(32), # 0: state
|
||||
ir.IntType(32), # 1: done
|
||||
ir.IntType(32), # 2: ret
|
||||
ir.IntType(32), # 3: exc(异常码,0=无异常)
|
||||
]
|
||||
slot_vars: list[str] = []
|
||||
for pname, pty in params:
|
||||
@@ -339,12 +342,12 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
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)
|
||||
for i in range(3):
|
||||
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}')
|
||||
Gen._store(zero32, slot_ptr)
|
||||
# 参数存入帧槽(3 + i)
|
||||
# 参数存入帧槽(4 + i)
|
||||
for i in range(len(params)):
|
||||
slot_ptr = Gen.builder.gep(frame_ptr, [zero32, ir.Constant(ir.IntType(32), 3 + i)], name=f'param{i}_slot')
|
||||
slot_ptr = Gen.builder.gep(frame_ptr, [zero32, ir.Constant(ir.IntType(32), 4 + 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)
|
||||
@@ -378,7 +381,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), 3 + idx)],
|
||||
[zero32, ir.Constant(ir.IntType(32), 4 + idx)],
|
||||
name=f'{var}_slot',
|
||||
)
|
||||
local_slot_ptrs[var] = slot_ptr
|
||||
@@ -389,6 +392,8 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
Gen._coro_state_ptr = state_ptr
|
||||
Gen._coro_done_ptr = done_ptr
|
||||
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
|
||||
Gen._coro_exit_bb = exit_bb
|
||||
Gen._coro_frame_ptr = frame_arg
|
||||
switch_instr: Any = Gen.builder.switch(state_val, exit_bb)
|
||||
@@ -421,6 +426,9 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
if isinstance(stmt, ast.Return):
|
||||
self._HandleCoroReturn(stmt, Gen)
|
||||
continue
|
||||
if isinstance(stmt, ast.Raise):
|
||||
self._HandleCoroRaiseLlvm(stmt, Gen)
|
||||
continue
|
||||
if (isinstance(stmt, ast.AnnAssign)
|
||||
and isinstance(stmt.target, ast.Name)
|
||||
and isinstance(stmt.value, ast.Await)):
|
||||
@@ -548,7 +556,10 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
|
||||
def _HandleCoroAwaitCommon(self, target: str, await_node: ast.Await, Gen: LlvmCodeGenerator) -> None:
|
||||
"""await 顶层翻译:设置目标槽后调用 _HandleAwaitLlvm(生成子帧/resume/挂起)。"""
|
||||
Gen._coro_await_slot_ptr = Gen.variables.get(target)
|
||||
if target == '__ret__':
|
||||
Gen._coro_await_slot_ptr = getattr(Gen, '_coro_ret_field_ptr', None)
|
||||
else:
|
||||
Gen._coro_await_slot_ptr = Gen.variables.get(target)
|
||||
# 校验 await 目标:async 函数调用 或 coro_sleep(ms)
|
||||
call: Any = await_node.value
|
||||
if isinstance(call, ast.Call) and self._IsCoroSleepCall(call):
|
||||
@@ -616,9 +627,6 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
state_ptr: ir.Value | None = getattr(Gen, '_coro_state_ptr', None)
|
||||
if state_ptr is not None:
|
||||
Gen._store(ir.Constant(ir.IntType(32), state_no), state_ptr)
|
||||
ret_field_ptr: ir.Value | None = getattr(Gen, '_coro_ret_field_ptr', None)
|
||||
if ret_field_ptr is not None:
|
||||
Gen._store(zero32, ret_field_ptr)
|
||||
exit_bb: ir.Block | None = getattr(Gen, '_coro_exit_bb', None)
|
||||
if exit_bb is not None:
|
||||
Gen.builder.branch(exit_bb)
|
||||
@@ -652,6 +660,60 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
Gen.builder.call(free_fn, [raw])
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
|
||||
def _HandleCoroRaiseLlvm(self, stmt: ast.Raise, Gen: LlvmCodeGenerator) -> None:
|
||||
"""协程内 raise:异常码存帧 exc 槽,done=1,终止(异常由 await/coro_exception 传播)。"""
|
||||
exc_code: ir.Value = ir.Constant(ir.IntType(32), 1)
|
||||
if stmt.exc is not None:
|
||||
v: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(stmt.exc)
|
||||
if v is not None:
|
||||
if isinstance(v.type, ir.IntType):
|
||||
if v.type.width < 32:
|
||||
exc_code = Gen.builder.zext(v, ir.IntType(32), name='zext_exc')
|
||||
elif v.type.width > 32:
|
||||
exc_code = Gen.builder.trunc(v, ir.IntType(32), name='trunc_exc')
|
||||
else:
|
||||
exc_code = v
|
||||
elif isinstance(v.type, ir.PointerType):
|
||||
exc_code = Gen.builder.ptrtoint(v, ir.IntType(32), name='exc_ptr2int')
|
||||
exc_ptr: ir.Value | None = getattr(Gen, '_coro_exc_ptr', None)
|
||||
if exc_ptr is not None:
|
||||
Gen._store(exc_code, exc_ptr)
|
||||
done_ptr_r: ir.Value | None = getattr(Gen, '_coro_done_ptr', None)
|
||||
if done_ptr_r is not None:
|
||||
Gen._store(ir.Constant(ir.IntType(32), 1), done_ptr_r)
|
||||
exit_bb: ir.Block | None = getattr(Gen, '_coro_exit_bb', None)
|
||||
if exit_bb is not None:
|
||||
Gen.builder.branch(exit_bb)
|
||||
|
||||
def _HandleCoroExceptionLlvm(self, Node: ast.Call, Gen: LlvmCodeGenerator) -> ir.Value:
|
||||
"""coro.coro_exception(帧):返回帧 exc 槽(异常码,0=无异常)。"""
|
||||
if not Node.args:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
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.IntType(32), 0)
|
||||
frame_ty: ir.IdentifiedStructType | None = getattr(Gen, '_coro_frame_types', {}).get(async_name)
|
||||
if not frame_ty:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
frame_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(arg)
|
||||
if frame_val is None:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
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.IntType(32), 0)
|
||||
exc_ptr: ir.Value = Gen.builder.gep(
|
||||
frame_ptr,
|
||||
[ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), 3)],
|
||||
name='coro_exc_ptr',
|
||||
)
|
||||
return Gen._load(exc_ptr, name='coro_exc')
|
||||
|
||||
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:
|
||||
@@ -706,7 +768,29 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
name='child_ret_ptr',
|
||||
)
|
||||
child_ret: ir.Value = Gen._load(child_ret_ptr, name='child_ret')
|
||||
# 存父帧局部变量槽
|
||||
# M4: 子协程异常传播——子帧 exc != 0 时父协程带异常终止
|
||||
child_exc_ptr: ir.Value = Gen.builder.gep(
|
||||
child,
|
||||
[zero32, ir.Constant(ir.IntType(32), 3)],
|
||||
name='child_exc_ptr',
|
||||
)
|
||||
child_exc: ir.Value = Gen._load(child_exc_ptr, name='child_exc')
|
||||
normal_bb: ir.Block = Gen.func.append_basic_block('coro_ok')
|
||||
exc_bb: ir.Block = Gen.func.append_basic_block('coro_exc')
|
||||
exc_cond: ir.Value = Gen.builder.icmp_signed('==', child_exc, zero32, name='child_exc_ok')
|
||||
Gen.builder.cbranch(exc_cond, normal_bb, exc_bb)
|
||||
Gen.builder.position_at_start(exc_bb)
|
||||
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)
|
||||
parent_done_ptr: ir.Value | None = getattr(Gen, '_coro_done_ptr', None)
|
||||
if parent_done_ptr is not None:
|
||||
Gen._store(ir.Constant(ir.IntType(32), 1), parent_done_ptr)
|
||||
exit_bb_ref: ir.Block | None = getattr(Gen, '_coro_exit_bb', None)
|
||||
if exit_bb_ref is not None:
|
||||
Gen.builder.branch(exit_bb_ref)
|
||||
# 正常路径:存父帧局部变量槽 + 挂起
|
||||
Gen.builder.position_at_start(normal_bb)
|
||||
slot: ir.Value | None = getattr(Gen, '_coro_await_slot_ptr', None)
|
||||
if slot is not None:
|
||||
Gen._store(child_ret, slot)
|
||||
@@ -720,9 +804,6 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
state_ptr: ir.Value | None = getattr(Gen, '_coro_state_ptr', None)
|
||||
if state_ptr is not None:
|
||||
Gen._store(ir.Constant(ir.IntType(32), state_no), state_ptr)
|
||||
ret_field_ptr: ir.Value | None = getattr(Gen, '_coro_ret_field_ptr', None)
|
||||
if ret_field_ptr is not None:
|
||||
Gen._store(zero32, ret_field_ptr)
|
||||
exit_bb: ir.Block | None = getattr(Gen, '_coro_exit_bb', None)
|
||||
if exit_bb is not None:
|
||||
Gen.builder.branch(exit_bb)
|
||||
@@ -730,6 +811,16 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
return child_ret
|
||||
|
||||
def _HandleCoroReturn(self, stmt: ast.Return, Gen: LlvmCodeGenerator) -> None:
|
||||
# return await x:await 直接存父帧 ret 槽(挂起前),恢复块仅完成协程
|
||||
if stmt.value is not None and isinstance(stmt.value, ast.Await):
|
||||
self._HandleCoroAwaitCommon('__ret__', stmt.value, Gen)
|
||||
done_ptr_r: ir.Value | None = getattr(Gen, '_coro_done_ptr', None)
|
||||
if done_ptr_r is not None:
|
||||
Gen._store(ir.Constant(ir.IntType(32), 1), done_ptr_r)
|
||||
exit_bb_r: ir.Block | None = getattr(Gen, '_coro_exit_bb', None)
|
||||
if exit_bb_r is not None:
|
||||
Gen.builder.branch(exit_bb_r)
|
||||
return
|
||||
val: ir.Value | None = None
|
||||
if stmt.value:
|
||||
val = self.Trans.ExprHandler.HandleExprLlvm(stmt.value)
|
||||
@@ -918,6 +1009,70 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
# coro.coro_run(帧) 内联翻译
|
||||
# ------------------------------------------------------------------
|
||||
|
||||
def _HandleCoroGatherLlvm(self, Node: ast.Call, Gen: LlvmCodeGenerator) -> ir.Value:
|
||||
"""coro.coro_gather(帧...):并发推进全部协程到完成(含 coro_sleep 轮询),返回完成数。"""
|
||||
zero32: ir.Constant = ir.Constant(ir.IntType(32), 0)
|
||||
count: int = 0
|
||||
for arg in Node.args:
|
||||
async_name: str | None = None
|
||||
if isinstance(arg, ast.Name):
|
||||
async_name = getattr(Gen, '_coro_var_async', {}).get(arg.id)
|
||||
if not async_name:
|
||||
continue
|
||||
frame_ty: ir.IdentifiedStructType | None = getattr(Gen, '_coro_frame_types', {}).get(async_name)
|
||||
resume_fn: ir.Function | None = Gen._get_function(f'resume_{async_name}')
|
||||
if not frame_ty or not resume_fn:
|
||||
continue
|
||||
frame_val: ir.Value | None = self.Trans.ExprHandler.HandleExprLlvm(arg)
|
||||
if frame_val is None:
|
||||
continue
|
||||
if isinstance(frame_val.type, ir.PointerType):
|
||||
frame_ptr: ir.Value = Gen.builder.bitcast(frame_val, ir.PointerType(frame_ty), name='gather_frame')
|
||||
elif isinstance(frame_val.type, ir.IntType):
|
||||
frame_ptr = Gen.builder.inttoptr(frame_val, ir.PointerType(frame_ty), name='gather_frame')
|
||||
else:
|
||||
continue
|
||||
loop_bb: ir.Block = Gen.func.append_basic_block('gather_loop')
|
||||
check_bb: ir.Block = Gen.func.append_basic_block('gather_wcheck')
|
||||
after_bb: ir.Block = Gen.func.append_basic_block('gather_after')
|
||||
Gen.builder.branch(loop_bb)
|
||||
Gen.builder.position_at_start(loop_bb)
|
||||
status: ir.Value = Gen.builder.call(resume_fn, [frame_ptr], name=f'gather_resume_{async_name}')
|
||||
done_cond: ir.Value = Gen.builder.icmp_signed('!=', status, zero32, name='gather_done_cond')
|
||||
Gen.builder.cbranch(done_cond, after_bb, check_bb)
|
||||
# SUSPEND:coro_sleep 唤醒轮询
|
||||
Gen.builder.position_at_start(check_bb)
|
||||
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')
|
||||
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')
|
||||
wake_ptr: ir.Value = Gen.builder.gep(
|
||||
frame_ptr,
|
||||
[ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), wake_idx)],
|
||||
name='gather_wake_ptr',
|
||||
)
|
||||
wake_val: ir.Value = Gen._load(wake_ptr, name='gather_wake')
|
||||
now_fn: ir.Function = self._GetWinFunc('GetTickCount64', Gen, ir.IntType(64))
|
||||
now_val: ir.Value = Gen.builder.call(now_fn, [], name='gather_tick_now')
|
||||
not_wake: ir.Value = Gen.builder.icmp_signed('==', wake_val, ir.Constant(ir.IntType(64), 0), name='gather_wake_zero')
|
||||
due: ir.Value = Gen.builder.icmp_unsigned('>=', now_val, wake_val, name='gather_wake_due')
|
||||
sleep_cond: ir.Value = Gen.builder.or_(not_wake, due, name='gather_continue_cond')
|
||||
Gen.builder.cbranch(sleep_cond, wdue_bb, wsleep_bb)
|
||||
Gen.builder.position_at_start(wsleep_bb)
|
||||
sleep_fn: ir.Function = self._GetWinFunc('Sleep', Gen, ir.VoidType(), [ir.IntType(32)])
|
||||
Gen.builder.call(sleep_fn, [ir.Constant(ir.IntType(32), 1)])
|
||||
Gen.builder.branch(loop_bb)
|
||||
Gen.builder.position_at_start(wdue_bb)
|
||||
Gen.builder.branch(loop_bb)
|
||||
else:
|
||||
Gen.builder.branch(loop_bb)
|
||||
Gen.builder.position_at_start(after_bb)
|
||||
count += 1
|
||||
return ir.Constant(ir.IntType(32), count)
|
||||
|
||||
def _HandleCoroRunLlvm(self, Node: ast.Call, Gen: LlvmCodeGenerator) -> ir.Value:
|
||||
if not Node.args:
|
||||
return ir.Constant(ir.IntType(32), 0)
|
||||
@@ -943,8 +1098,6 @@ class AsyncFunctionHandle(BaseHandle):
|
||||
loop_bb: ir.Block = Gen.func.append_basic_block('coro_loop')
|
||||
after_bb: ir.Block = Gen.func.append_basic_block('coro_after')
|
||||
check_bb: ir.Block = Gen.func.append_basic_block('coro_wcheck')
|
||||
wake_wait_bb: ir.Block = Gen.func.append_basic_block('coro_wsleep')
|
||||
wake_due_bb: ir.Block = Gen.func.append_basic_block('coro_wdue')
|
||||
Gen.builder.branch(loop_bb)
|
||||
Gen.builder.position_at_start(loop_bb)
|
||||
status: ir.Value = Gen.builder.call(resume_fn, [frame_ptr], name=f'resume_{async_name}')
|
||||
@@ -955,8 +1108,10 @@ 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 = 3 + slot_vars.index('__coro_wake_us')
|
||||
wake_idx = 4 + 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')
|
||||
wake_ptr: ir.Value = Gen.builder.gep(
|
||||
frame_ptr,
|
||||
[ir.Constant(ir.IntType(32), 0), ir.Constant(ir.IntType(32), wake_idx)],
|
||||
|
||||
@@ -282,6 +282,14 @@ class ExprCallHandle(BaseHandle):
|
||||
if isinstance(Node.func, ast.Attribute) and Node.func.attr == 'coro_destroy':
|
||||
if isinstance(Node.func.value, ast.Name) and self.Trans.AsyncHandler._IsCoroModule(Node.func.value.id):
|
||||
return self.Trans.AsyncHandler._HandleCoroDestroyLlvm(Node, Gen)
|
||||
# 协程:coro.coro_exception(帧) 内联翻译为帧 exc 槽读取
|
||||
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_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):
|
||||
return self.Trans.AsyncHandler._HandleCoroGatherLlvm(Node, Gen)
|
||||
FuncAttr: str | None = None
|
||||
ModulePath: str | None = None
|
||||
if isinstance(Node.func, ast.Name):
|
||||
|
||||
Reference in new issue
Block a user