fix(flow): 函数体入口清空 break/continue 目标与 match-case 标记
- FuncGenDef.translate_function_def:进函数体前保存并清空 _break_bb / _continue_bb / _in_match_case,退出恢复 - FuncGenMixin:嵌套函数体与 lambda 体两处同样处理——原实现下嵌套函数体内的 break/continue 会继承外层函数的跳转目标(跨函数 br,非法 IR)
This commit is contained in:
1 parent
fb4175736f
commit
d633a5786f
2 files changed
+33
No files matched your search
@@ -892,10 +892,18 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
# 返回注解上下文([C①] 裸名泛型构造的类型实参回退来源之一):
|
||||
# 进入函数体前记录本函数返回注解,退出时恢复外层函数的值
|
||||
old_ret_annot: ast.AST* = trans.CurFuncRetAnnot
|
||||
# break/continue 目标与 match-case 标记:新函数作用域必须清空(见下方赋值),
|
||||
# 否则嵌套函数体内的 break/continue 会继承外层函数(甚至跨函数)的 br 目标
|
||||
old_break_bb: rawptr[llvmlite.BasicBlock] = trans._break_bb
|
||||
old_continue_bb: rawptr[llvmlite.BasicBlock] = trans._continue_bb
|
||||
old_inmc: int = trans._in_match_case
|
||||
|
||||
trans._cur_func = func
|
||||
trans._cur_builder = func_builder
|
||||
trans.CurFuncRetAnnot = fd.returns
|
||||
trans._break_bb = None
|
||||
trans._continue_bb = None
|
||||
trans._in_match_case = 0
|
||||
# 清空 global/nonlocal 名称集合(新函数作用域)
|
||||
GenApi.clear_scope_names(trans)
|
||||
# 重置链内 nonlocal 堆预建标志(每函数只建一次;多嵌套函数定义
|
||||
@@ -1040,6 +1048,9 @@ novirtual class FuncGenDef(CallGenBase.CallGenBase):
|
||||
self.Gen.VarGen.exit_scope(trans.SymTab)
|
||||
trans._cur_func = old_func
|
||||
trans._cur_builder = old_builder
|
||||
trans._break_bb = old_break_bb
|
||||
trans._continue_bb = old_continue_bb
|
||||
trans._in_match_case = old_inmc
|
||||
trans._global_name_count = old_global_count
|
||||
trans._nonlocal_name_count = old_nonlocal_count
|
||||
trans._closure_env_count = old_env_count
|
||||
|
||||
@@ -181,6 +181,11 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
old_global_count: int = trans._global_name_count
|
||||
old_nonlocal_count: int = trans._nonlocal_name_count
|
||||
old_env_count: int = trans._closure_env_count
|
||||
# break/continue 目标与 match-case 标记:新函数作用域必须清空(见下方赋值),
|
||||
# 否则嵌套函数体内的 break/continue 会继承外层函数的跳转目标(跨函数 br)
|
||||
old_break_bb: rawptr[llvmlite.BasicBlock] = trans._break_bb
|
||||
old_continue_bb: rawptr[llvmlite.BasicBlock] = trans._continue_bb
|
||||
old_inmc: int = trans._in_match_case
|
||||
# nonlocal 集合独立缓冲:嵌套函数注册 nonlocal 写入共享缓冲 [0] 会
|
||||
# 覆盖父函数集合(ClosureTest2 Test 7 不同变量场景:level2 的 b 覆盖
|
||||
# level1 的 a → level1 env[0] 存错)。嵌套函数用独立缓冲,翻译完恢复。
|
||||
@@ -192,6 +197,9 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
trans._cur_builder = func_builder
|
||||
trans._cur_func_name = func_name
|
||||
GenApi.clear_scope_names(trans)
|
||||
trans._break_bb = None
|
||||
trans._continue_bb = None
|
||||
trans._in_match_case = 0
|
||||
# 嵌套函数独立 nonlocal 缓冲(避免覆盖父函数集合)
|
||||
trans._nonlocal_names = stdlib.malloc(HT.MAX_GLOBAL_NAMES * 8)
|
||||
trans._nonlocal_types = stdlib.malloc(HT.MAX_GLOBAL_NAMES * 8)
|
||||
@@ -254,6 +262,9 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self.Gen.VarGen.exit_scope(trans.SymTab)
|
||||
trans._cur_func = old_func
|
||||
trans._cur_builder = old_builder
|
||||
trans._break_bb = old_break_bb
|
||||
trans._continue_bb = old_continue_bb
|
||||
trans._in_match_case = old_inmc
|
||||
if dbg_pushed_n != 0:
|
||||
DebugInfoGen.PopFunction(func_builder)
|
||||
# NOTE: _nonlocal_names 和 _nonlocal_name_count 仍为嵌套函数的值
|
||||
@@ -1148,10 +1159,18 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
old_global_count: int = trans._global_name_count
|
||||
old_nonlocal_count: int = trans._nonlocal_name_count
|
||||
old_env_count: int = trans._closure_env_count
|
||||
# break/continue 目标与 match-case 标记:新函数作用域必须清空(见下方赋值),
|
||||
# 否则 lambda 体内的 break/continue 会继承外层函数的跳转目标(跨函数 br)
|
||||
old_break_bb: rawptr[llvmlite.BasicBlock] = trans._break_bb
|
||||
old_continue_bb: rawptr[llvmlite.BasicBlock] = trans._continue_bb
|
||||
old_inmc: int = trans._in_match_case
|
||||
trans._cur_func = func
|
||||
trans._cur_builder = func_builder
|
||||
trans._cur_func_name = mangled_promoted
|
||||
GenApi.clear_scope_names(trans)
|
||||
trans._break_bb = None
|
||||
trans._continue_bb = None
|
||||
trans._in_match_case = 0
|
||||
|
||||
# 9. 捕获变量:从 env 堆槽加载值到局部 alloca
|
||||
for ci in range(cap_count):
|
||||
@@ -1216,6 +1235,9 @@ novirtual class FuncGenMixin(CallGenBase.CallGenBase):
|
||||
self.Gen.VarGen.exit_scope(trans.SymTab)
|
||||
trans._cur_func = old_func
|
||||
trans._cur_builder = old_builder
|
||||
trans._break_bb = old_break_bb
|
||||
trans._continue_bb = old_continue_bb
|
||||
trans._in_match_case = old_inmc
|
||||
trans._cur_func_name = old_func_name
|
||||
trans._global_name_count = old_global_count
|
||||
trans._nonlocal_name_count = old_nonlocal_count
|
||||
|
||||
Reference in new issue
Block a user