fix(cdefine): stub 读取对负浮点字面量/浮点强转包裹剥壳后再注册 - 修 X: double = -100.0 走整型提取 fatal
This commit is contained in:
1 parent
5460d78ff1
commit
d06e665ebd
1 file changed
+46
-9
@@ -2090,17 +2090,36 @@ def _vpi_register_typedef_closure(pool: memhub.MemBuddy*, import_mods: str, temp
|
||||
if aa_r.target.kind() != ast.ASTKind.Name: continue
|
||||
cdef_t: ast.Name* = ast.Name*(aa_r.target)
|
||||
if cdef_t.id is None: continue
|
||||
if aa_r.value.kind() == ast.ASTKind.Constant:
|
||||
cn_v: ast.Constant* = ast.Constant*(aa_r.value)
|
||||
# 与定义端同口径:剥掉 `float(...)`/`double(...)` 包裹与负浮点字面量
|
||||
# `UnaryOp(USub, Constant(float))`;否则 `X: double = -100.0` 既不注册
|
||||
# 浮点(静默丢失),又可能被误当整型去走常驻提取。
|
||||
vnode_r: ast.AST* = aa_r.value
|
||||
neg_r: int = 0
|
||||
if vnode_r.kind() == ast.ASTKind.Call:
|
||||
cl_r: ast.Call* = ast.Call*(vnode_r)
|
||||
if cl_r.args is not None and len(cl_r.args) > 0:
|
||||
fa_r: ast.AST* = cl_r.args.get(0)
|
||||
if fa_r is not None and fa_r.kind() == ast.ASTKind.Constant: vnode_r = fa_r
|
||||
if vnode_r.kind() == ast.ASTKind.UnaryOp:
|
||||
uu_r: ast.UnaryOp* = ast.UnaryOp*(vnode_r)
|
||||
if uu_r.op == ast.OpKind.USub and uu_r.operand is not None and uu_r.operand.kind() == ast.ASTKind.Constant:
|
||||
ic_r: ast.Constant* = ast.Constant*(uu_r.operand)
|
||||
if ic_r.const_kind == ast.CONST_FLOAT:
|
||||
vnode_r = uu_r.operand
|
||||
neg_r = 1
|
||||
if vnode_r.kind() == ast.ASTKind.Constant:
|
||||
cn_v: ast.Constant* = ast.Constant*(vnode_r)
|
||||
if cn_v.const_kind == ast.CONST_FLOAT:
|
||||
fv_r: double = cn_v.float_val
|
||||
if neg_r != 0: fv_r = -fv_r
|
||||
# 浮点宽度同样由声明注解裁决(与定义方同一套),
|
||||
# 否则 `define PI: float = ...` 的使用方会把 f32 当 double
|
||||
GenApi.register_cdefine_double(pool, cdef_t.id, cn_v.float_val, GenApi.cdefine_decl_float_bits(pool, aa_r.annotation))
|
||||
GenApi.register_cdefine_double(pool, cdef_t.id, fv_r, GenApi.cdefine_decl_float_bits(pool, aa_r.annotation))
|
||||
elif cn_v.const_kind == ast.CONST_INT:
|
||||
cdef_val: int64 = GenApi.extract_cdefine_int_value(aa_r.value)
|
||||
cdef_val: int64 = GenApi.extract_cdefine_int_value(vnode_r)
|
||||
# 位宽与定义方同一套裁决(注解 → 右侧强转 → 值的最小可存宽度),
|
||||
# 否则使用方拿 bits=0 只能兜底,跨模块位宽会与定义方不一致
|
||||
GenApi.register_cdefine_constant(pool, cdef_t.id, cdef_val, GenApi.cdefine_decl_bits(pool, aa_r.annotation, aa_r.value))
|
||||
GenApi.register_cdefine_constant(pool, cdef_t.id, cdef_val, GenApi.cdefine_decl_bits(pool, aa_r.annotation, vnode_r))
|
||||
# recurse into child imports (cycle guarded by the visited marks)
|
||||
if sub_imports[0] != '\0': _vpi_register_typedef_closure(pool, sub_imports, temp_dir, depth + 1)
|
||||
stdlib.free(sub_imports)
|
||||
@@ -2412,24 +2431,42 @@ def _ParseVpiIntoModuleImpl(pool: memhub.MemBuddy*, mod: mlirlite.LLVMModule*, v
|
||||
if cdef_tgt.id is not None:
|
||||
# Skip string CDefines (version numbers etc.): extract_cdefine_int_value
|
||||
# fails fast on string constants, and count refs only need integer CDefines.
|
||||
# 与定义端 `_register_cdefine_from_value` 同口径:先剥掉 `float(...)`/`double(...)`
|
||||
# 强转包裹与负浮点字面量的 `UnaryOp(USub, Constant(float))`,否则
|
||||
# `X: double = -100.0` 会被判成"非 float"而落到整型提取 ⇒ fatal。
|
||||
vnode: ast.AST* = aa.value
|
||||
cdef_neg_f: int = 0
|
||||
if vnode.kind() == ast.ASTKind.Call:
|
||||
cl_w2: ast.Call* = ast.Call*(vnode)
|
||||
if cl_w2.args is not None and len(cl_w2.args) > 0:
|
||||
fa2: ast.AST* = cl_w2.args.get(0)
|
||||
if fa2 is not None and fa2.kind() == ast.ASTKind.Constant: vnode = fa2
|
||||
if vnode.kind() == ast.ASTKind.UnaryOp:
|
||||
uu2: ast.UnaryOp* = ast.UnaryOp*(vnode)
|
||||
if uu2.op == ast.OpKind.USub and uu2.operand is not None and uu2.operand.kind() == ast.ASTKind.Constant:
|
||||
ic2: ast.Constant* = ast.Constant*(uu2.operand)
|
||||
if ic2.const_kind == ast.CONST_FLOAT:
|
||||
vnode = uu2.operand
|
||||
cdef_neg_f = 1
|
||||
cdef_is_str: int = 0
|
||||
cdef_is_float: int = 0
|
||||
cdef_float_val: double = 0.0
|
||||
if aa.value.kind() == ast.ASTKind.Constant:
|
||||
cn_v: ast.Constant* = ast.Constant*(aa.value)
|
||||
if vnode.kind() == ast.ASTKind.Constant:
|
||||
cn_v: ast.Constant* = ast.Constant*(vnode)
|
||||
if cn_v.const_kind == ast.CONST_STR: cdef_is_str = 1
|
||||
elif cn_v.const_kind == ast.CONST_FLOAT:
|
||||
cdef_is_float = 1
|
||||
cdef_float_val = cn_v.float_val
|
||||
if cdef_neg_f != 0: cdef_float_val = -cdef_float_val
|
||||
if cdef_is_str == 0 and cdef_is_float != 0:
|
||||
# Float CDefine (e.g. FRAGMENTATION_THRESHOLD: t.CDefine = 0.7): register via
|
||||
# register_cdefine_double (integer extraction would fail fast).
|
||||
# 注解声明 float 时带上 f32 种类(与定义方同一套裁决)。
|
||||
GenApi.register_cdefine_double(pool, cdef_tgt.id, cdef_float_val, GenApi.cdefine_decl_float_bits(pool, aa.annotation))
|
||||
elif cdef_is_str == 0:
|
||||
cdef_val: int64 = GenApi.extract_cdefine_int_value(aa.value)
|
||||
cdef_val: int64 = GenApi.extract_cdefine_int_value(vnode)
|
||||
# 位宽与定义方同一套裁决(注解 → 右侧强转 → 值的最小可存宽度)
|
||||
GenApi.register_cdefine_constant(pool, cdef_tgt.id, cdef_val, GenApi.cdefine_decl_bits(pool, aa.annotation, aa.value))
|
||||
GenApi.register_cdefine_constant(pool, cdef_tgt.id, cdef_val, GenApi.cdefine_decl_bits(pool, aa.annotation, vnode))
|
||||
else:
|
||||
_inject_global_variable_declare(pool, mod, aa, trans, stub_imported_modules, stub_from_imports, i32_ty, i8_ptr_ty, src_sha1)
|
||||
continue
|
||||
|
||||
Reference in new issue
Block a user