refactor(gen): R12/R13 同步——下标 while 循环改 for range、去 c.Set

与 includes 同步执行两批源改写:R12 把「i: int = 0 与 while i < N: … i += 1」形式的计数循环改写为「for i in range(N):」;R13 把 c.Set(*p, v) 迁移为 *p = v、c.Set(a, b) 迁移为 a = b(c.Set 是正在退化的路径)。

验证:bootstrap 三重重编 SUCCESS(无 vast_c 解析回退);全量 77/77 顺序回归通过(WebTest 首轮网络超时,单独重跑通过)。
This commit is contained in:
TermiNexus committed 2026-10-05 15:33:58 +08:00
1 parent a7b8118ce8
commit fb53f88893
25 files changed
+133 -345

No files matched your search

+12 -36
View File
@@ -940,12 +940,10 @@ def link_objs_to_exe(obj_paths: str, obj_paths_len: sizet, linker_cmd: str, link
dt2len: sizet = dj - ds2 dt2len: sizet = dj - ds2
if dt2len == dtlen: if dt2len == dtlen:
deq: int = 1 deq: int = 1
dk: sizet = 0 for dk in range(dtlen):
while dk < dtlen:
if dedup[ds2 + dk] != obj_paths[dstart + dk]: if dedup[ds2 + dk] != obj_paths[dstart + dk]:
deq = 0 deq = 0
break break
dk += 1
if deq != 0: if deq != 0:
ddup = 1 ddup = 1
break break
@@ -1304,18 +1302,14 @@ def _tb_quoted_after(mb: memhub.MemBuddy*, s: str, key: str) -> str:
def _tb_dir_lookup(dirs: bytes, count: int, idx: int) -> str: def _tb_dir_lookup(dirs: bytes, count: int, idx: int) -> str:
i: int = 0 for i in range(count):
while i < count:
if int(_tb_rd_u32(dirs, sizet(i) * TB_DIR_SIZE)) == idx: return rawptr(_tb_rd_u64(dirs, sizet(i) * TB_DIR_SIZE + 8)) if int(_tb_rd_u32(dirs, sizet(i) * TB_DIR_SIZE)) == idx: return rawptr(_tb_rd_u64(dirs, sizet(i) * TB_DIR_SIZE + 8))
i += 1
return None return None
def _tb_file_rec(files: bytes, count: int, idx: int) -> int: def _tb_file_rec(files: bytes, count: int, idx: int) -> int:
i: int = 0 for i in range(count):
while i < count:
if int(_tb_rd_u32(files, sizet(i) * TB_FILE_SIZE)) == idx: return i if int(_tb_rd_u32(files, sizet(i) * TB_FILE_SIZE)) == idx: return i
i += 1
return -1 return -1
@@ -1407,11 +1401,9 @@ def _tb_func_name_for(fbuf: bytes, fcount: int, rva: uint64) -> str:
def _tb_intern(p: TbPool*, s: str) -> uint64: def _tb_intern(p: TbPool*, s: str) -> uint64:
"""Intern s into the pool (linear scan; keeps offset 0 as the empty sentinel).""" """Intern s into the pool (linear scan; keeps offset 0 as the empty sentinel)."""
if p is None or s is None: return 0 if p is None or s is None: return 0
k: int = 0 for k in range(p.OffCount):
while k < p.OffCount:
o: uint64 = _tb_rd_u64(p.Offs, sizet(k) * 8) o: uint64 = _tb_rd_u64(p.Offs, sizet(k) * 8)
if string.strcmp(p.Pool + sizet(o), s) == 0: return o if string.strcmp(p.Pool + sizet(o), s) == 0: return o
k += 1
off: uint64 = uint64(p.PoolLen) off: uint64 = uint64(p.PoolLen)
n: sizet = string.strlen(s) n: sizet = string.strlen(s)
string.memcpy(p.Pool + sizet(off), s, n) string.memcpy(p.Pool + sizet(off), s, n)
@@ -1456,8 +1448,7 @@ def _tb_read_pe_layout(mb: memhub.MemBuddy*, exe_path: str) -> TbPeLayout*:
min_rva: uint64 = 0xFFFFFFFF min_rva: uint64 = 0xFFFFFFFF
found_text: int = 0 found_text: int = 0
have_sec: int = 0 have_sec: int = 0
si: uint64 = 0 for si in range(nsec):
while si < nsec:
base: sizet = sec_off + sizet(si) * 40 base: sizet = sec_off + sizet(si) * 40
if uint64(base) + 40 > uint64(got): break if uint64(base) + 40 > uint64(got): break
va: uint64 = uint64(_tb_rd_u32(head, base + 12)) va: uint64 = uint64(_tb_rd_u32(head, base + 12))
@@ -1466,7 +1457,6 @@ def _tb_read_pe_layout(mb: memhub.MemBuddy*, exe_path: str) -> TbPeLayout*:
if _tb_cc(head, base) == 46 and _tb_cc(head, base + 1) == 116 and _tb_cc(head, base + 2) == 101 and _tb_cc(head, base + 3) == 120 and _tb_cc(head, base + 4) == 116: if _tb_cc(head, base) == 46 and _tb_cc(head, base + 1) == 116 and _tb_cc(head, base + 2) == 101 and _tb_cc(head, base + 3) == 120 and _tb_cc(head, base + 4) == 116:
text_rva = va text_rva = va
found_text = 1 found_text = 1
si += 1
if found_text == 0 and have_sec != 0 and min_rva != 0xFFFFFFFF: text_rva = min_rva if found_text == 0 and have_sec != 0 and min_rva != 0xFFFFFFFF: text_rva = min_rva
lay.ImageBase = img_base lay.ImageBase = img_base
lay.SizeOfImage = size_img lay.SizeOfImage = size_img
@@ -1752,8 +1742,7 @@ def _tb_grp_get(grp: bytes, cap: int, caller: str, callee: str, do_insert: int)
if grp is None or cap <= 0 or caller is None or callee is None: return -1 if grp is None or cap <= 0 or caller is None or callee is None: return -1
mask: uint64 = uint64(cap - 1) mask: uint64 = uint64(cap - 1)
hv: uint64 = (_tb_strhash(caller) * 0x100000001B3 + _tb_strhash(callee)) & mask hv: uint64 = (_tb_strhash(caller) * 0x100000001B3 + _tb_strhash(callee)) & mask
i: int = 0 for i in range(cap):
while i < cap:
slot: int = int((hv + uint64(i)) & mask) slot: int = int((hv + uint64(i)) & mask)
off: sizet = sizet(slot) * TB_GRP_SIZE off: sizet = sizet(slot) * TB_GRP_SIZE
if uint64(_tb_rd_u32(grp, off + TB_GRP_OFF_USED)) == 0: if uint64(_tb_rd_u32(grp, off + TB_GRP_OFF_USED)) == 0:
@@ -1768,7 +1757,6 @@ def _tb_grp_get(grp: bytes, cap: int, caller: str, callee: str, do_insert: int)
sc: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLER)) sc: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLER))
sk: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLEE)) sk: str = rawptr(_tb_rd_u64(grp, off + TB_GRP_OFF_CALLEE))
if sc is not None and sk is not None and string.strcmp(sc, caller) == 0 and string.strcmp(sk, callee) == 0: return slot if sc is not None and sk is not None and string.strcmp(sc, caller) == 0 and string.strcmp(sk, callee) == 0: return slot
i += 1
return -1 return -1
@@ -1910,13 +1898,11 @@ def _tb_parse_vpcall_file(mb: memhub.MemBuddy*, path: str, cp: TbCallParse*) ->
def _tb_load_vpcalls(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int: def _tb_load_vpcalls(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int:
if _tb_vpcall_buf is None or _tb_vpcall_n <= 0: return 0 if _tb_vpcall_buf is None or _tb_vpcall_n <= 0: return 0
k: int = 0 for k in range(_tb_vpcall_n):
while k < _tb_vpcall_n:
slot: str* = (str*)(uint64(_tb_vpcall_buf) + sizet(k) * 8) slot: str* = (str*)(uint64(_tb_vpcall_buf) + sizet(k) * 8)
path: str = slot[0] path: str = slot[0]
if path is not None: if path is not None:
if _tb_parse_vpcall_file(mb, path, cp) != 0: return 1 if _tb_parse_vpcall_file(mb, path, cp) != 0: return 1
k += 1
return 0 return 0
@@ -1929,8 +1915,7 @@ def _tb_build_groups(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int:
VLogger.error("--traceback: 调用点分组表分配失败,终止编译", "TRACEBACK") VLogger.error("--traceback: 调用点分组表分配失败,终止编译", "TRACEBACK")
return 1 return 1
string.memset(cp.Grp, 0, sizet(cp.GrpCap) * TB_GRP_SIZE) string.memset(cp.Grp, 0, sizet(cp.GrpCap) * TB_GRP_SIZE)
i: int = 0 for i in range(cp.CrN):
while i < cp.CrN:
off: sizet = sizet(i) * TB_CR_SIZE off: sizet = sizet(i) * TB_CR_SIZE
caller: str = rawptr(_tb_rd_u64(cp.Cr, off + TB_CR_OFF_CALLER)) caller: str = rawptr(_tb_rd_u64(cp.Cr, off + TB_CR_OFF_CALLER))
callee: str = rawptr(_tb_rd_u64(cp.Cr, off + TB_CR_OFF_CALLEE)) callee: str = rawptr(_tb_rd_u64(cp.Cr, off + TB_CR_OFF_CALLEE))
@@ -1948,7 +1933,6 @@ def _tb_build_groups(mb: memhub.MemBuddy*, cp: TbCallParse*) -> int:
_tb_wr_u32(cp.Cr, toff + TB_CR_OFF_NEXT, uint64(i)) _tb_wr_u32(cp.Cr, toff + TB_CR_OFF_NEXT, uint64(i))
_tb_wr_u32(cp.Cr, off + TB_CR_OFF_NEXT, uint64(TB_IDX_NONE)) _tb_wr_u32(cp.Cr, off + TB_CR_OFF_NEXT, uint64(TB_IDX_NONE))
_tb_wr_u32(cp.Grp, goff + TB_GRP_OFF_TAIL, uint64(i)) _tb_wr_u32(cp.Grp, goff + TB_GRP_OFF_TAIL, uint64(i))
i += 1
return 0 return 0
@@ -1972,15 +1956,13 @@ def _tb_emit_call_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo
def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, addr: uint64, sym: str) -> int: def _tb_emit_entry_row(mb: memhub.MemBuddy*, d: TbDump*, cp: TbCallParse*, img_lo: uint64, addr: uint64, sym: str) -> int:
"""Emit a fallback function-entry row for an objdump label sym (file/line from the F record).""" """Emit a fallback function-entry row for an objdump label sym (file/line from the F record)."""
if sym is None or cp.Fr is None or cp.FrN <= 0 or addr < img_lo: return 0 if sym is None or cp.Fr is None or cp.FrN <= 0 or addr < img_lo: return 0
i: int = 0 for i in range(cp.FrN):
while i < cp.FrN:
off: sizet = sizet(i) * TB_FR_SIZE off: sizet = sizet(i) * TB_FR_SIZE
s: str = rawptr(_tb_rd_u64(cp.Fr, off + TB_FR_OFF_SYM)) s: str = rawptr(_tb_rd_u64(cp.Fr, off + TB_FR_OFF_SYM))
if s is not None and string.strcmp(s, sym) == 0: if s is not None and string.strcmp(s, sym) == 0:
file: str = rawptr(_tb_rd_u64(cp.Fr, off + TB_FR_OFF_FILE)) file: str = rawptr(_tb_rd_u64(cp.Fr, off + TB_FR_OFF_FILE))
dl: int = int(_tb_rd_u32(cp.Fr, off + TB_FR_OFF_DEFLINE)) dl: int = int(_tb_rd_u32(cp.Fr, off + TB_FR_OFF_DEFLINE))
return _tb_emit_row(mb, d, addr, file, dl, sym) return _tb_emit_row(mb, d, addr, file, dl, sym)
i += 1
return 0 return 0
@@ -2298,8 +2280,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
if ro is None: if ro is None:
VLogger.error("--traceback: 记录偏移缓冲分配失败,终止编译", "TRACEBACK") VLogger.error("--traceback: 记录偏移缓冲分配失败,终止编译", "TRACEBACK")
return 1 return 1
i = 0 for i in range(uniq):
while i < uniq:
pth2: str = rawptr(_tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE)) pth2: str = rawptr(_tb_rd_u64(d.RowBuf, sizet(i) * TB_ROW_SIZE + TB_ROW_OFF_FILE))
foff: uint64 = _tb_intern(p, pth2) foff: uint64 = _tb_intern(p, pth2)
noff: uint64 = 0 noff: uint64 = 0
@@ -2311,7 +2292,6 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
if nm2 is not None: noff = _tb_intern(p, nm2) if nm2 is not None: noff = _tb_intern(p, nm2)
_tb_wr_u32(ro, sizet(i) * 8, foff) _tb_wr_u32(ro, sizet(i) * 8, foff)
_tb_wr_u32(ro, sizet(i) * 8 + 4, noff) _tb_wr_u32(ro, sizet(i) * 8 + 4, noff)
i += 1
# ---- 5) self-checks (mirror the runtime LoadMapFile validation) ---- # ---- 5) self-checks (mirror the runtime LoadMapFile validation) ----
prev_rva: uint64 = 0 prev_rva: uint64 = 0
@@ -2335,13 +2315,11 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
return 1 return 1
# file_off must be >= 1: offset 0 is the empty-string sentinel and the runtime # file_off must be >= 1: offset 0 is the empty-string sentinel and the runtime
# rejects a whole map whose record file_off is 0. # rejects a whole map whose record file_off is 0.
ci = 0 for ci in range(uniq):
while ci < uniq:
fo: uint64 = uint64(_tb_rd_u32(ro, sizet(ci) * 8)) fo: uint64 = uint64(_tb_rd_u32(ro, sizet(ci) * 8))
if fo == 0: if fo == 0:
VLogger.error("--traceback 自检失败:存在 file_off==0 的记录(空路径,运行期会拒绝该旁文件),终止编译", "TRACEBACK") VLogger.error("--traceback 自检失败:存在 file_off==0 的记录(空路径,运行期会拒绝该旁文件),终止编译", "TRACEBACK")
return 1 return 1
ci += 1
# ---- 6) serialise and write <exe>.stackmap ---- # ---- 6) serialise and write <exe>.stackmap ----
total: sizet = 20 + sizet(uniq) * 20 + sizet(p.PoolLen) total: sizet = 20 + sizet(uniq) * 20 + sizet(p.PoolLen)
@@ -2357,8 +2335,7 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
_tb_wr_u32(out, 8, uint64(uniq)) _tb_wr_u32(out, 8, uint64(uniq))
_tb_wr_u32(out, 12, uint64(p.OffCount)) _tb_wr_u32(out, 12, uint64(p.OffCount))
_tb_wr_u32(out, 16, uint64(p.PoolLen)) _tb_wr_u32(out, 16, uint64(p.PoolLen))
ri2: int = 0 for ri2 in range(uniq):
while ri2 < uniq:
roff2: sizet = 20 + sizet(ri2) * 20 roff2: sizet = 20 + sizet(ri2) * 20
rv3: uint64 = _tb_rd_u64(d.RowBuf, sizet(ri2) * TB_ROW_SIZE) rv3: uint64 = _tb_rd_u64(d.RowBuf, sizet(ri2) * TB_ROW_SIZE)
ln3: uint64 = uint64(_tb_rd_u32(d.RowBuf, sizet(ri2) * TB_ROW_SIZE + TB_ROW_OFF_LINE)) ln3: uint64 = uint64(_tb_rd_u32(d.RowBuf, sizet(ri2) * TB_ROW_SIZE + TB_ROW_OFF_LINE))
@@ -2366,7 +2343,6 @@ def WriteStackMap(mb: memhub.MemBuddy*, exe_path: str) -> int:
_tb_wr_u32(out, roff2 + 8, uint64(_tb_rd_u32(ro, sizet(ri2) * 8))) _tb_wr_u32(out, roff2 + 8, uint64(_tb_rd_u32(ro, sizet(ri2) * 8)))
_tb_wr_u32(out, roff2 + 12, ln3) _tb_wr_u32(out, roff2 + 12, ln3)
_tb_wr_u32(out, roff2 + 16, uint64(_tb_rd_u32(ro, sizet(ri2) * 8 + 4))) _tb_wr_u32(out, roff2 + 16, uint64(_tb_rd_u32(ro, sizet(ri2) * 8 + 4)))
ri2 += 1
string.memcpy(out + 20 + sizet(uniq) * 20, p.Pool, sizet(p.PoolLen)) string.memcpy(out + 20 + sizet(uniq) * 20, p.Pool, sizet(p.PoolLen))
map_len: sizet = string.strlen(exe_path) + 16 map_len: sizet = string.strlen(exe_path) + 16
+2 -6
View File
@@ -267,8 +267,7 @@ def _normalize_path(path: str) -> str:
seg_start: sizet = 0 seg_start: sizet = 0
out_len: sizet = 0 out_len: sizet = 0
has_seg: int = 0 has_seg: int = 0
i: sizet = 0 for i in range(plen + 1):
while i <= plen:
ch: char = '\0' ch: char = '\0'
if i < plen: ch = path[i] if i < plen: ch = path[i]
if ch == '/' or ch == '\\' or ch == '\0': if ch == '/' or ch == '\\' or ch == '\0':
@@ -313,7 +312,6 @@ def _normalize_path(path: str) -> str:
jj += 1 jj += 1
has_seg = 1 has_seg = 1
seg_start = i + 1 seg_start = i + 1
i += 1
if has_seg == 0: if has_seg == 0:
# All segments consumed (e.g. ./..): return current dir # All segments consumed (e.g. ./..): return current dir
return "./" return "./"
@@ -577,8 +575,7 @@ def slice_subdir(sha1: str, level: int) -> str:
buf: str = _mbuddy.alloc(buf_len) buf: str = _mbuddy.alloc(buf_len)
if buf is None: return None if buf is None: return None
pos: int = 0 pos: int = 0
i: int = 0 for i in range(level):
while i < level:
if i > 0: if i > 0:
buf[pos] = '/' buf[pos] = '/'
pos += 1 pos += 1
@@ -586,6 +583,5 @@ def slice_subdir(sha1: str, level: int) -> str:
buf[pos] = sha1[idx] buf[pos] = sha1[idx]
buf[pos + 1] = sha1[idx + 1] buf[pos + 1] = sha1[idx + 1]
pos += 2 pos += 2
i += 1
buf[pos] = '\0' buf[pos] = '\0'
return buf return buf
+14 -38
View File
@@ -98,7 +98,7 @@ def _lookup_cdefine_for_pyi(name: str) -> int64:
global _g_pyi_cdefine_found global _g_pyi_cdefine_found
# Look up this file's CDefine cache first (globals are empty during vpi gen) # Look up this file's CDefine cache first (globals are empty during vpi gen)
if _g_pyi_cdef_names is not None and _g_pyi_cdef_vals is not None: if _g_pyi_cdef_names is not None and _g_pyi_cdef_vals is not None:
# Bound loop by _g_pyi_cdef_count; never len()/.get on i8** (len falls back # Bound loop by _g_pyi_cdef_count; never len()/.get on i8** (len falls back
# to strlen, .get misdispatches to HashTable.get) -- index via t.CPtr(base + i*8). # to strlen, .get misdispatches to HashTable.get) -- index via t.CPtr(base + i*8).
pn: sizet = sizet(_g_pyi_cdef_count) pn: sizet = sizet(_g_pyi_cdef_count)
for pi in range(pn): for pi in range(pn):
@@ -160,10 +160,8 @@ def _PyiEmit(buf: bytes, buf_size: sizet, pos: sizet, text: str) -> sizet:
# _PyiIndent - append level*4 spaces to buf at pos # _PyiIndent - append level*4 spaces to buf at pos
def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, level: int) -> sizet: def _PyiIndent(buf: bytes, buf_size: sizet, pos: sizet, level: int) -> sizet:
"""Append level*4 spaces to buf at pos and return the new pos""" """Append level*4 spaces to buf at pos and return the new pos"""
i: int = 0 for i in range(level):
while i < level:
pos = _PyiEmit(buf, buf_size, pos, " ") pos = _PyiEmit(buf, buf_size, pos, " ")
i += 1
return pos return pos
@@ -249,8 +247,7 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
cmps_ct: list[ast.AST*]* = cmp_t.comparators cmps_ct: list[ast.AST*]* = cmp_t.comparators
if ops_ct is not None: if ops_ct is not None:
on_ct: sizet = len(ops_ct) on_ct: sizet = len(ops_ct)
oi_ct: sizet = 0 for oi_ct in range(on_ct):
while oi_ct < on_ct:
oid_ct: int = ops_ct.get(oi_ct) oid_ct: int = ops_ct.get(oi_ct)
if oid_ct == ast.OpKind.Eq: pos = _PyiEmit(buf, buf_size, pos, " == ") if oid_ct == ast.OpKind.Eq: pos = _PyiEmit(buf, buf_size, pos, " == ")
elif oid_ct == ast.OpKind.Ne: pos = _PyiEmit(buf, buf_size, pos, " != ") elif oid_ct == ast.OpKind.Ne: pos = _PyiEmit(buf, buf_size, pos, " != ")
@@ -262,7 +259,6 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
# TPC indexes comparators[i] by ops; guard the length here so a # TPC indexes comparators[i] by ops; guard the length here so a
# malformed AST (unequal ops/comparators) cannot overrun. # malformed AST (unequal ops/comparators) cannot overrun.
if cmps_ct is not None and oi_ct < len(cmps_ct): pos = _PyiTypeStr(buf, buf_size, pos, cmps_ct.get(oi_ct), depth + 1) if cmps_ct is not None and oi_ct < len(cmps_ct): pos = _PyiTypeStr(buf, buf_size, pos, cmps_ct.get(oi_ct), depth + 1)
oi_ct += 1
return pos return pos
# BoolOp: boolean ops (ENABLED and MAX_SIZE > 0 / A or B). # BoolOp: boolean ops (ENABLED and MAX_SIZE > 0 / A or B).
@@ -272,13 +268,11 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
vals_bt: list[ast.AST*]* = bool_t.values vals_bt: list[ast.AST*]* = bool_t.values
if vals_bt is not None: if vals_bt is not None:
vn_bt: sizet = len(vals_bt) vn_bt: sizet = len(vals_bt)
vi_bt: sizet = 0 for vi_bt in range(vn_bt):
while vi_bt < vn_bt:
if vi_bt > 0: if vi_bt > 0:
if bool_t.op == ast.OpKind.Or: pos = _PyiEmit(buf, buf_size, pos, " or ") if bool_t.op == ast.OpKind.Or: pos = _PyiEmit(buf, buf_size, pos, " or ")
else: pos = _PyiEmit(buf, buf_size, pos, " and ") else: pos = _PyiEmit(buf, buf_size, pos, " and ")
pos = _PyiTypeStr(buf, buf_size, pos, vals_bt.get(vi_bt), depth + 1) pos = _PyiTypeStr(buf, buf_size, pos, vals_bt.get(vi_bt), depth + 1)
vi_bt += 1
return pos return pos
# Constant: string forward refs (e.g. 'MyClass'), None or numeric constants # Constant: string forward refs (e.g. 'MyClass'), None or numeric constants
@@ -309,12 +303,10 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
if lst.elts is not None: if lst.elts is not None:
lst_elts: list[ast.AST*]* = lst.elts lst_elts: list[ast.AST*]* = lst.elts
ln: sizet = len(lst_elts) ln: sizet = len(lst_elts)
li: sizet = 0 for li in range(ln):
while li < ln:
if li > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if li > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
le: ast.AST* = lst_elts.get(li) le: ast.AST* = lst_elts.get(li)
pos = _PyiTypeStr(buf, buf_size, pos, le, depth + 1) pos = _PyiTypeStr(buf, buf_size, pos, le, depth + 1)
li += 1
pos = _PyiEmit(buf, buf_size, pos, "]") pos = _PyiEmit(buf, buf_size, pos, "]")
return pos return pos
@@ -324,12 +316,10 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
if tup.elts is not None: if tup.elts is not None:
tup_elts: list[ast.AST*]* = tup.elts tup_elts: list[ast.AST*]* = tup.elts
tn: sizet = len(tup_elts) tn: sizet = len(tup_elts)
ti: sizet = 0 for ti in range(tn):
while ti < tn:
if ti > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if ti > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
el: ast.AST* = tup_elts.get(ti) el: ast.AST* = tup_elts.get(ti)
pos = _PyiTypeStr(buf, buf_size, pos, el, depth + 1) pos = _PyiTypeStr(buf, buf_size, pos, el, depth + 1)
ti += 1
return pos return pos
# Call: call expression (used by decorators such as @t.NoVTable()) # Call: call expression (used by decorators such as @t.NoVTable())
@@ -340,12 +330,10 @@ def _PyiTypeStr(buf: bytes, buf_size: sizet, pos: sizet, annot: ast.AST*, depth:
if cl.args is not None: if cl.args is not None:
cl_args: list[ast.AST*]* = cl.args cl_args: list[ast.AST*]* = cl.args
can: sizet = len(cl_args) can: sizet = len(cl_args)
cai: sizet = 0 for cai in range(can):
while cai < can:
if cai > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if cai > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
ca: ast.AST* = cl_args.get(cai) ca: ast.AST* = cl_args.get(cai)
pos = _PyiTypeStr(buf, buf_size, pos, ca, depth + 1) pos = _PyiTypeStr(buf, buf_size, pos, ca, depth + 1)
cai += 1
pos = _PyiEmit(buf, buf_size, pos, ")") pos = _PyiEmit(buf, buf_size, pos, ")")
return pos return pos
@@ -437,15 +425,13 @@ def _PyiFunction(buf: bytes, buf_size: sizet, pos: sizet, fn: ast.FunctionDef*,
if fn.decorator_list is not None: if fn.decorator_list is not None:
fn_decorator_list: list[ast.AST*]* = fn.decorator_list fn_decorator_list: list[ast.AST*]* = fn.decorator_list
dn: sizet = len(fn_decorator_list) dn: sizet = len(fn_decorator_list)
di: sizet = 0 for di in range(dn):
while di < dn:
dec: ast.AST* = fn_decorator_list.get(di) dec: ast.AST* = fn_decorator_list.get(di)
if dec is not None: if dec is not None:
pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiIndent(buf, buf_size, pos, indent_level)
pos = _PyiEmit(buf, buf_size, pos, "@") pos = _PyiEmit(buf, buf_size, pos, "@")
pos = _PyiTypeStr(buf, buf_size, pos, dec) pos = _PyiTypeStr(buf, buf_size, pos, dec)
pos = _PyiEmit(buf, buf_size, pos, "\n") pos = _PyiEmit(buf, buf_size, pos, "\n")
di += 1
pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiIndent(buf, buf_size, pos, indent_level)
pos = _PyiEmit(buf, buf_size, pos, "def ") pos = _PyiEmit(buf, buf_size, pos, "def ")
@@ -521,15 +507,13 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, inden
if cls.decorator_list is not None: if cls.decorator_list is not None:
cls_decorator_list: list[ast.AST*]* = cls.decorator_list cls_decorator_list: list[ast.AST*]* = cls.decorator_list
dcn: sizet = len(cls_decorator_list) dcn: sizet = len(cls_decorator_list)
dci: sizet = 0 for dci in range(dcn):
while dci < dcn:
ddec: ast.AST* = cls_decorator_list.get(dci) ddec: ast.AST* = cls_decorator_list.get(dci)
if ddec is not None: if ddec is not None:
pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiIndent(buf, buf_size, pos, indent_level)
pos = _PyiEmit(buf, buf_size, pos, "@") pos = _PyiEmit(buf, buf_size, pos, "@")
pos = _PyiTypeStr(buf, buf_size, pos, ddec) pos = _PyiTypeStr(buf, buf_size, pos, ddec)
pos = _PyiEmit(buf, buf_size, pos, "\n") pos = _PyiEmit(buf, buf_size, pos, "\n")
dci += 1
pos = _PyiIndent(buf, buf_size, pos, indent_level) pos = _PyiIndent(buf, buf_size, pos, indent_level)
pos = _PyiEmit(buf, buf_size, pos, "class ") pos = _PyiEmit(buf, buf_size, pos, "class ")
@@ -543,12 +527,10 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, inden
tpn: sizet = len(cls_type_params) tpn: sizet = len(cls_type_params)
if tpn > 0: if tpn > 0:
pos = _PyiEmit(buf, buf_size, pos, "[") pos = _PyiEmit(buf, buf_size, pos, "[")
tpi: sizet = 0 for tpi in range(tpn):
while tpi < tpn:
if tpi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if tpi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
tpname: str = cls_type_params.get(tpi) tpname: str = cls_type_params.get(tpi)
if tpname is not None: pos = _PyiEmit(buf, buf_size, pos, tpname) if tpname is not None: pos = _PyiEmit(buf, buf_size, pos, tpname)
tpi += 1
pos = _PyiEmit(buf, buf_size, pos, "]") pos = _PyiEmit(buf, buf_size, pos, "]")
# Base classes # Base classes
@@ -557,12 +539,10 @@ def _PyiClass(buf: bytes, buf_size: sizet, pos: sizet, cls: ast.ClassDef*, inden
bn: sizet = len(cls_bases) bn: sizet = len(cls_bases)
if bn > 0: if bn > 0:
pos = _PyiEmit(buf, buf_size, pos, "(") pos = _PyiEmit(buf, buf_size, pos, "(")
bi: sizet = 0 for bi in range(bn):
while bi < bn:
if bi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if bi > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
base: ast.AST* = cls_bases.get(bi) base: ast.AST* = cls_bases.get(bi)
pos = _PyiTypeStr(buf, buf_size, pos, base) pos = _PyiTypeStr(buf, buf_size, pos, base)
bi += 1
pos = _PyiEmit(buf, buf_size, pos, ")") pos = _PyiEmit(buf, buf_size, pos, ")")
pos = _PyiEmit(buf, buf_size, pos, ":\n") pos = _PyiEmit(buf, buf_size, pos, ":\n")
@@ -736,8 +716,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf
if imp2.names is not None: if imp2.names is not None:
imp2_names: list[ast.AST*]* = imp2.names imp2_names: list[ast.AST*]* = imp2.names
an2: sizet = len(imp2_names) an2: sizet = len(imp2_names)
ai2: sizet = 0 for ai2 in range(an2):
while ai2 < an2:
if ai2 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if ai2 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
al2: ast.Alias* = ast.Alias*(imp2_names.get(ai2)) al2: ast.Alias* = ast.Alias*(imp2_names.get(ai2))
# fail-fast: never silently write "import , ". Import names are the # fail-fast: never silently write "import , ". Import names are the
@@ -750,7 +729,6 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf
if al2.asname is not None and string.strlen(al2.asname) > 0: if al2.asname is not None and string.strlen(al2.asname) > 0:
pos = _PyiEmit(buf, buf_size, pos, " as ") pos = _PyiEmit(buf, buf_size, pos, " as ")
pos = _PyiEmit(buf, buf_size, pos, al2.asname) pos = _PyiEmit(buf, buf_size, pos, al2.asname)
ai2 += 1
pos = _PyiEmit(buf, buf_size, pos, "\n") pos = _PyiEmit(buf, buf_size, pos, "\n")
# ImportFrom statement # ImportFrom statement
@@ -770,8 +748,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf
if ifr.names is not None: if ifr.names is not None:
ifr_names: list[ast.AST*]* = ifr.names ifr_names: list[ast.AST*]* = ifr.names
an3: sizet = len(ifr_names) an3: sizet = len(ifr_names)
ai3: sizet = 0 for ai3 in range(an3):
while ai3 < an3:
if ai3 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ") if ai3 > 0: pos = _PyiEmit(buf, buf_size, pos, ", ")
al3: ast.Alias* = ast.Alias*(ifr_names.get(ai3)) al3: ast.Alias* = ast.Alias*(ifr_names.get(ai3))
# fail-fast: same as Import (report the two causes separately). # fail-fast: same as Import (report the two causes separately).
@@ -783,7 +760,6 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf
if al3.asname is not None and string.strlen(al3.asname) > 0: if al3.asname is not None and string.strlen(al3.asname) > 0:
pos = _PyiEmit(buf, buf_size, pos, " as ") pos = _PyiEmit(buf, buf_size, pos, " as ")
pos = _PyiEmit(buf, buf_size, pos, al3.asname) pos = _PyiEmit(buf, buf_size, pos, al3.asname)
ai3 += 1
pos = _PyiEmit(buf, buf_size, pos, "\n") pos = _PyiEmit(buf, buf_size, pos, "\n")
# Function definition (_PyiFunction already ends with a newline) # Function definition (_PyiFunction already ends with a newline)
@@ -827,7 +803,7 @@ def _GeneratePyiFromAst(mb: memhub.MemBuddy*, tree: ast.AST*, rel_path: str, buf
viperlib.snprintf(num_buf, 32, " = %lld", cv.int_val) viperlib.snprintf(num_buf, 32, " = %lld", cv.int_val)
pos = _PyiEmit(buf, buf_size, pos, num_buf) pos = _PyiEmit(buf, buf_size, pos, num_buf)
elif cv.const_kind == ast.CONST_FLOAT: elif cv.const_kind == ast.CONST_FLOAT:
# Float CDefines (e.g. numpy pi/e) must emit a value or read-back # Float CDefines (e.g. numpy pi/e) must emit a value or read-back
# degrades to a global pointer; %.17g round-trips double exactly. # degrades to a global pointer; %.17g round-trips double exactly.
fbuf_c: bytes = mb.alloc(64) fbuf_c: bytes = mb.alloc(64)
if fbuf_c is not None: if fbuf_c is not None:
+5 -15
View File
@@ -148,8 +148,7 @@ def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, cap: int, key:
h: uint64 = _vpi_idx_hash(key) h: uint64 = _vpi_idx_hash(key)
mask: sizet = sizet(cap - 1) mask: sizet = sizet(cap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(cap):
while i < cap:
slot: sizet* = _vpi_idx_slot(idx_base, si) slot: sizet* = _vpi_idx_slot(idx_base, si)
sv: sizet = slot[0] sv: sizet = slot[0]
if sv == 0: return -1 if sv == 0: return -1
@@ -157,7 +156,6 @@ def _vpi_idx_find(keys: bytes, key_stride: int, idx_base: bytes, cap: int, key:
ek: bytes = keys + se * key_stride ek: bytes = keys + se * key_stride
if string.strcmp(ek, key) == 0: return se if string.strcmp(ek, key) == 0: return se
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return -1 return -1
@@ -167,14 +165,12 @@ def _vpi_idx_insert(idx_base: bytes, cap: int, slot_index: int, key: bytes) -> i
h: uint64 = _vpi_idx_hash(key) h: uint64 = _vpi_idx_hash(key)
mask: sizet = sizet(cap - 1) mask: sizet = sizet(cap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(cap):
while i < cap:
slot: sizet* = _vpi_idx_slot(idx_base, si) slot: sizet* = _vpi_idx_slot(idx_base, si)
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(slot_index + 1) slot[0] = sizet(slot_index + 1)
return 0 return 0
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return 1 return 1
@@ -839,13 +835,11 @@ def _vpi_param_annot_seg_is(src_sha1: str, cls_name: str, method_name: str, seg_
prm: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name) prm: str = _lookup_vpi_param_annots(src_sha1, cls_name, method_name)
if prm is None or prm[0] == '\0': return 0 if prm is None or prm[0] == '\0': return 0
cur: sizet = 0 cur: sizet = 0
seg: int = 0
# locate segment start: skip seg_idx '@'-separated segments # locate segment start: skip seg_idx '@'-separated segments
while seg < seg_idx: for seg in range(seg_idx):
while prm[cur] != '\0' and prm[cur] != '@': cur += 1 while prm[cur] != '\0' and prm[cur] != '@': cur += 1
if prm[cur] == '\0': return 0 if prm[cur] == '\0': return 0
cur += 1 cur += 1
seg += 1
slen: sizet = 0 slen: sizet = 0
while prm[cur + slen] != '\0' and prm[cur + slen] != '@': slen += 1 while prm[cur + slen] != '\0' and prm[cur + slen] != '@': slen += 1
wlen: sizet = string.strlen(want) wlen: sizet = string.strlen(want)
@@ -1053,10 +1047,8 @@ def _resolve_single_vpi_type_str(pool: memhub.MemBuddy*, seg: str) -> mlirlite.L
star_off_ps: sizet = string.strlen(star_buf_ps) star_off_ps: sizet = string.strlen(star_buf_ps)
string.strncpy(star_buf_ps + star_off_ps, seg, star_base_end_ps) string.strncpy(star_buf_ps + star_off_ps, seg, star_base_end_ps)
star_buf_ps[star_off_ps + star_base_end_ps] = '\0' star_buf_ps[star_off_ps + star_base_end_ps] = '\0'
star_k_ps = 0 for star_k_ps in range(star_cnt_ps):
while star_k_ps < star_cnt_ps:
string.strcat(star_buf_ps, "]") string.strcat(star_buf_ps, "]")
star_k_ps += 1
star_ty_ps: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, star_buf_ps) star_ty_ps: mlirlite.LLVMType* = _resolve_single_vpi_type_str(pool, star_buf_ps)
stdlib.free(star_buf_ps) stdlib.free(star_buf_ps)
return star_ty_ps return star_ty_ps
@@ -1307,10 +1299,8 @@ def _resolve_vpi_ret_annot_str(pool: memhub.MemBuddy*, ret_annot: str, i32_ty: m
if cptr_sub_lvl > 0: if cptr_sub_lvl > 0:
if first_ty is None: return cptr_sub_ty if first_ty is None: return cptr_sub_ty
res_ty_cs: mlirlite.LLVMType* = first_ty res_ty_cs: mlirlite.LLVMType* = first_ty
wrap_i_cs: int = 0 for wrap_i_cs in range(cptr_sub_lvl):
while wrap_i_cs < cptr_sub_lvl:
res_ty_cs = mlirlite.Ptr(pool, res_ty_cs) res_ty_cs = mlirlite.Ptr(pool, res_ty_cs)
wrap_i_cs += 1
return res_ty_cs return res_ty_cs
if has_cvoid != 0: if has_cvoid != 0:
# t.CVoid | t.State: State is a decorator marker (ignored), t.CVoid -> void. # t.CVoid | t.State: State is a decorator marker (ignored), t.CVoid -> void.
+2 -6
View File
@@ -416,12 +416,10 @@ def LookupSha1ByAlias(from_imports: str, alias: str) -> str:
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len: if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
# compare local_name == alias # compare local_name == alias
Matched: int = 1 Matched: int = 1
li: sizet = 0 for li in range(alias_len):
while li < alias_len:
if from_imports[ci + li] != alias[li]: if from_imports[ci + li] != alias[li]:
Matched = 0 Matched = 0
break break
li += 1
if Matched == 1: if Matched == 1:
# extract module (from colon+1 to next ':' or space) # extract module (from colon+1 to next ':' or space)
m_start: sizet = colon + 1 m_start: sizet = colon + 1
@@ -459,12 +457,10 @@ def LookupModNameByAlias(from_imports: str, alias: str) -> str:
if colon < total_len and from_imports[colon] == ':' and local_len == alias_len: if colon < total_len and from_imports[colon] == ':' and local_len == alias_len:
# compare local_name == alias # compare local_name == alias
Matched: int = 1 Matched: int = 1
li: sizet = 0 for li in range(alias_len):
while li < alias_len:
if from_imports[ci + li] != alias[li]: if from_imports[ci + li] != alias[li]:
Matched = 0 Matched = 0
break break
li += 1
if Matched == 1: if Matched == 1:
# extract module (from colon+1 to next ':' or space) # extract module (from colon+1 to next ':' or space)
m_start: sizet = colon + 1 m_start: sizet = colon + 1
+1 -3
View File
@@ -721,15 +721,13 @@ novirtual class AssignGenMixin:
n_s: sizet = string.strlen(sv_s) n_s: sizet = string.strlen(sv_s)
if sizet(arr_count) < n_s: if sizet(arr_count) < n_s:
self.Gen.TypeGenErr.fatal_error(list_node, f"字符串字面量长度 {n_s} 超过字符数组声明长度 {arr_count},不允许越界写入", "OverflowError") self.Gen.TypeGenErr.fatal_error(list_node, f"字符串字面量长度 {n_s} 超过字符数组声明长度 {arr_count},不允许越界写入", "OverflowError")
bi_s: sizet = 0 for bi_s in range(n_s):
while bi_s < n_s:
bidx_s: mlirlite.Value* = mlirlite.const_int32(pool, bi_s) bidx_s: mlirlite.Value* = mlirlite.const_int32(pool, bi_s)
bp_s: mlirlite.Value* = mlirlite.build_gep_array(builder, arr_ty, elem_ty, array_alloca, bidx_s) bp_s: mlirlite.Value* = mlirlite.build_gep_array(builder, arr_ty, elem_ty, array_alloca, bidx_s)
if bp_s is None: break if bp_s is None: break
bvv: mlirlite.Value* = mlirlite.const_int32(pool, sv_s[bi_s]) bvv: mlirlite.Value* = mlirlite.const_int32(pool, sv_s[bi_s])
bsv: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, bvv, elem_ty, e0_s) bsv: mlirlite.Value* = self.Gen.ExprGenBase.coerce_to_type(builder, bvv, elem_ty, e0_s)
mlirlite.build_store(builder, bsv, bp_s) mlirlite.build_store(builder, bsv, bp_s)
bi_s += 1
return 0 return 0
# Element count exceeds declared length: fail fast (avoid out-of-range GEP writes) # Element count exceeds declared length: fail fast (avoid out-of-range GEP writes)
+3 -7
View File
@@ -182,12 +182,10 @@ novirtual class CallGenBase:
fl2_od: sizet = fend_od - fstart_od fl2_od: sizet = fend_od - fstart_od
if fl2_od == name_len: if fl2_od == name_len:
fd_eq_od: int = 1 fd_eq_od: int = 1
fdi_od: sizet = 0 for fdi_od in range(fl2_od):
while fdi_od < fl2_od:
if buf[fstart_od + fdi_od] != func_name[fdi_od]: if buf[fstart_od + fdi_od] != func_name[fdi_od]:
fd_eq_od = 0 fd_eq_od = 0
break break
fdi_od += 1
if fd_eq_od != 0: has_own_def = 1 if fd_eq_od != 0: has_own_def = 1
continue continue
# line must start with "from " # line must start with "from "
@@ -455,7 +453,7 @@ novirtual class CallGenBase:
while cur is not None: while cur is not None:
cur_name: str = mlirlite.function_get_name(cur) cur_name: str = mlirlite.function_get_name(cur)
if cur_name is not None: if cur_name is not None:
# fast path: skip strcmp when first chars differ (mangled names start # fast path: skip strcmp when first chars differ (mangled names start
# with sha1 hex, bare names with letters/underscore) # with sha1 hex, bare names with letters/underscore)
if cur_name[0] == name[0] and string.strcmp(cur_name, name) == 0: return cur if cur_name[0] == name[0] and string.strcmp(cur_name, name) == 0: return cur
# use Function.NameLen (computed once) instead of per-node strlen # use Function.NameLen (computed once) instead of per-node strlen
@@ -760,10 +758,8 @@ novirtual class CallGenBase:
stdlib.free(nm_buf) stdlib.free(nm_buf)
if nm_ty is not None: if nm_ty is not None:
nm_wrap: mlirlite.LLVMType* = nm_ty nm_wrap: mlirlite.LLVMType* = nm_ty
nm_i: int = 0 for nm_i in range(nm_star):
while nm_i < nm_star:
nm_wrap = mlirlite.Ptr(pool, nm_wrap) nm_wrap = mlirlite.Ptr(pool, nm_wrap)
nm_i += 1
return nm_wrap return nm_wrap
# contains "*" -> generic i8* (i8*, i32*, { i32, i8 }*, unregistered %name*) # contains "*" -> generic i8* (i8*, i32*, { i32, i8 }*, unregistered %name*)
+5 -11
View File
@@ -744,7 +744,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
if base_pfx_g != 0: base_clean_g = base_buf_g + sizet(base_pfx_g) if base_pfx_g != 0: base_clean_g = base_buf_g + sizet(base_pfx_g)
spec_name_g: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, base_clean_g, ta_list_g) spec_name_g: str = self.Gen.ClassGenGeneric._specialize_generic_class(trans, base_clean_g, ta_list_g)
if spec_name_g is not None: if spec_name_g is not None:
# Re-lookup the specialized function after specialization; # Re-lookup the specialized function after specialization;
# find_func_in_module matches both bare and tpl-prefixed names. # find_func_in_module matches both bare and tpl-prefixed names.
spec_lk_g: str = pool.alloc(string.strlen(class_name) + string.strlen(method_name) + 2) spec_lk_g: str = pool.alloc(string.strlen(class_name) + string.strlen(method_name) + 2)
if spec_lk_g is not None: if spec_lk_g is not None:
@@ -871,7 +871,7 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
kwc: sizet = 0 kwc: sizet = 0
if kw_calls is not None: kwc = len(kw_calls) if kw_calls is not None: kwc = len(kw_calls)
# Multi-inheritance this-adjust (byte-offset): delta = field offset in the # Multi-inheritance this-adjust (byte-offset): delta = field offset in the
# subclass minus in the parent layout; delta>0 GEPs and bitcasts to the parent. # subclass minus in the parent layout; delta>0 GEPs and bitcasts to the parent.
self_arg: mlirlite.Value* = obj_ptr self_arg: mlirlite.Value* = obj_ptr
if mc_anc is not None and string.strcmp(mc_anc, class_name) != 0: if mc_anc is not None and string.strcmp(mc_anc, class_name) != 0:
@@ -887,15 +887,13 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
# fields, so this needs no byte adjust; pass it through unchanged. # fields, so this needs no byte adjust; pass it through unchanged.
if anc_entry_th is not None and anc_entry_th.FieldCount > 0: if anc_entry_th is not None and anc_entry_th.FieldCount > 0:
anc_first_name_th: str = None anc_first_name_th: str = None
afi_th: int = 0 for afi_th in range(anc_entry_th.FieldCount):
while afi_th < anc_entry_th.FieldCount:
afe_th: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(anc_entry_th, afi_th) afe_th: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(anc_entry_th, afi_th)
if afe_th is not None: if afe_th is not None:
afn_th: str = self.Gen.StructGen.get_field_name_ptr(afe_th) afn_th: str = self.Gen.StructGen.get_field_name_ptr(afe_th)
if afn_th is not None and string.strcmp(afn_th, "__vtable__") != 0: if afn_th is not None and string.strcmp(afn_th, "__vtable__") != 0:
anc_first_name_th = afn_th anc_first_name_th = afn_th
break break
afi_th += 1
if anc_first_name_th is not None: if anc_first_name_th is not None:
sub_entry_th: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(class_name) sub_entry_th: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(class_name)
if sub_entry_th is not None: if sub_entry_th is not None:
@@ -1442,15 +1440,13 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
anc_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(anc) anc_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(anc)
if anc_entry_sp is not None and anc_entry_sp.FieldCount > 0: if anc_entry_sp is not None and anc_entry_sp.FieldCount > 0:
first_name_sp: str = None first_name_sp: str = None
afi_sp: int = 0 for afi_sp in range(anc_entry_sp.FieldCount):
while afi_sp < anc_entry_sp.FieldCount:
afe_sp: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(anc_entry_sp, afi_sp) afe_sp: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(anc_entry_sp, afi_sp)
if afe_sp is not None: if afe_sp is not None:
afn_sp: str = self.Gen.StructGen.get_field_name_ptr(afe_sp) afn_sp: str = self.Gen.StructGen.get_field_name_ptr(afe_sp)
if afn_sp is not None and string.strcmp(afn_sp, "__vtable__") != 0: if afn_sp is not None and string.strcmp(afn_sp, "__vtable__") != 0:
first_name_sp = afn_sp first_name_sp = afn_sp
break break
afi_sp += 1
if first_name_sp is not None: if first_name_sp is not None:
sub_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(cur_class) sub_entry_sp: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(cur_class)
if sub_entry_sp is not None: if sub_entry_sp is not None:
@@ -1563,12 +1559,10 @@ novirtual class CallGenCall(CallGenBase.CallGenBase):
e: GenTypes.StructEntry* = self.Gen.StructGen._get_struct_entry(j) e: GenTypes.StructEntry* = self.Gen.StructGen._get_struct_entry(j)
if e is not None and e.Name is not None: if e is not None and e.Name is not None:
pc: int = self.Gen.StructGen.get_parent_count(e.Name) pc: int = self.Gen.StructGen.get_parent_count(e.Name)
pj: int = 0 for pj in range(pc):
while pj < pc:
pn: str = self.Gen.StructGen.get_parent_name_at(e.Name, pj) pn: str = self.Gen.StructGen.get_parent_name_at(e.Name, pj)
if pn is not None: if pn is not None:
if string.strcmp(pn, class_name) == 0: return 1 if string.strcmp(pn, class_name) == 0: return 1
pj += 1
j += 1 j += 1
return 0 return 0
+5 -7
View File
@@ -170,7 +170,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase):
# in translate_constant, else coercing an inttoptr char value as a pointer crashes). # in translate_constant, else coercing an inttoptr char value as a pointer crashes).
fe: GenTypes.FieldEntry* = None fe: GenTypes.FieldEntry* = None
if ctor_entry is not None: if ctor_entry is not None:
# Field 0 is __vtable__ (vtable pointer placeholder): ctor args must skip it, # Field 0 is __vtable__ (vtable pointer placeholder): ctor args must skip it,
# else an arg overwrites the vtable slot and isinstance/dispatch break. # else an arg overwrites the vtable slot and isinstance/dispatch break.
target_idx: int = 0 target_idx: int = 0
for fi in range(ctor_entry.FieldCount): for fi in range(ctor_entry.FieldCount):
@@ -494,7 +494,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase):
if val_bits == 1: if val_bits == 1:
# i1 is a boolean (from icmp/fcmp) with unsigned semantics; must zext # i1 is a boolean (from icmp/fcmp) with unsigned semantics; must zext
return mlirlite.build_zext(builder, val, target_ty) return mlirlite.build_zext(builder, val, target_ty)
# Unify the widening direction (same source as coerce_to_type's _zext_or_sext_val): # Unify the widening direction (same source as coerce_to_type's _zext_or_sext_val):
# i1/i8 -> zext; unsigned source -> zext; else sext (keeps the source's signedness). # i1/i8 -> zext; unsigned source -> zext; else sext (keeps the source's signedness).
if self.Gen.ExprGenBase._zext_or_sext_val(pool, val, src_node, trans) != 0: return mlirlite.build_zext(builder, val, target_ty) if self.Gen.ExprGenBase._zext_or_sext_val(pool, val, src_node, trans) != 0: return mlirlite.build_zext(builder, val, target_ty)
return mlirlite.build_sext(builder, val, target_ty) return mlirlite.build_sext(builder, val, target_ty)
@@ -558,7 +558,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase):
tn = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports) tn = self.Gen.TypeGenResolve._norm_type_arg_name(pool, tn_raw, from_imports)
if tn is not None: result.append(tn) if tn is not None: result.append(tn)
return result return result
# Generic-class ctor helper list[str](pool, 8): reuse translate_list_literal's flow (alloca, # Generic-class ctor helper list[str](pool, 8): reuse translate_list_literal's flow (alloca,
# arg array, __new__ -> __before_init__ -> __init__). Must not go through the normal call path. # arg array, __new__ -> __before_init__ -> __init__). Must not go through the normal call path.
# _ptr_layer_type_arg - add the pointer layer (`*`) to inferred type args so the ctor side # _ptr_layer_type_arg - add the pointer layer (`*`) to inferred type args so the ctor side
@@ -784,7 +784,7 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase):
tmp: mlirlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, struct_ty) tmp: mlirlite.Value* = self.Gen.VarGen._alloca_at_entry(builder, struct_ty)
if tmp is None: return None if tmp is None: return None
# Translate args into a pointer array (extra_args[slot]): positional args -> slots # Translate args into a pointer array (extra_args[slot]): positional args -> slots
# 0..can-1; keywords -> slot by __init__ param name. Positional wins; order must not be assumed. # 0..can-1; keywords -> slot by __init__ param name. Positional wins; order must not be assumed.
cargs: list[ast.AST*]* = cl.args cargs: list[ast.AST*]* = cl.args
can: sizet = 0 can: sizet = 0
@@ -840,12 +840,10 @@ novirtual class CallGenCtor(CallGenBase.CallGenBase):
if slot_kw > arg_max_filled: arg_max_filled = slot_kw if slot_kw > arg_max_filled: arg_max_filled = slot_kw
# Slots must be contiguous (0..arg_max_filled all filled): a hole means a param # Slots must be contiguous (0..arg_max_filled all filled): a hole means a param
# got neither positional nor keyword arg. Never pass the hole as 0; fail-fast. # got neither positional nor keyword arg. Never pass the hole as 0; fail-fast.
ci_hole: int = 0 for ci_hole in range(arg_max_filled + 1):
while ci_hole <= arg_max_filled:
if arg_filled[sizet(ci_hole)] == 0: if arg_filled[sizet(ci_hole)] == 0:
self.Gen.TypeGenErr.fatal_error(cl, f"泛型类 '{tmpl_name}' 的关键字构造缺少前置形参(第 {ci_hole + 1} 个实参位置既无位置实参也无关键字实参)", "TypeError") self.Gen.TypeGenErr.fatal_error(cl, f"泛型类 '{tmpl_name}' 的关键字构造缺少前置形参(第 {ci_hole + 1} 个实参位置既无位置实参也无关键字实参)", "TypeError")
break break
ci_hole += 1
arg_count: int = 0 arg_count: int = 0
if arg_max_filled >= 0: arg_count = arg_max_filled + 1 if arg_max_filled >= 0: arg_count = arg_max_filled + 1
+1 -3
View File
@@ -171,8 +171,7 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase):
head: mlirlite.Value* = None head: mlirlite.Value* = None
tail: mlirlite.Value* = None tail: mlirlite.Value* = None
fp: mlirlite.Param* = mlirlite.function_get_param_head(func) fp: mlirlite.Param* = mlirlite.function_get_param_head(func)
ai: sizet = 0 for ai in range(can):
while ai < can:
arg: ast.AST* = cargs.get(ai) arg: ast.AST* = cargs.get(ai)
fpty: mlirlite.LLVMType* = None fpty: mlirlite.LLVMType* = None
if fp is not None: fpty = mlirlite.param_get_ty(fp) if fp is not None: fpty = mlirlite.param_get_ty(fp)
@@ -185,7 +184,6 @@ novirtual class CallGenDispatch(CallGenBase.CallGenBase):
else: tail.Next = av else: tail.Next = av
tail = av tail = av
if fp is not None: fp = mlirlite.param_get_next(fp) if fp is not None: fp = mlirlite.param_get_next(fp)
ai += 1
# build_call's second arg is the callee name string (not Function*); passing a Function* # build_call's second arg is the callee name string (not Function*); passing a Function*
# reads its first field as a string and emits illegal IR. Use the looked-up symbol name. # reads its first field as a string and emits illegal IR. Use the looked-up symbol name.
return mlirlite.build_call(builder, spec_name, head, int(can), ret_ty, 0) return mlirlite.build_call(builder, spec_name, head, int(can), ret_ty, 0)
+3 -7
View File
@@ -65,8 +65,7 @@ def _gfn_idx_find(funcs: GenTypes.FuncEntry*, idx_base: sizet*, cap: int, name:
mask: sizet = sizet(cap - 1) mask: sizet = sizet(cap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
entry_size: sizet = GenTypes.FuncEntry.__sizeof__() entry_size: sizet = GenTypes.FuncEntry.__sizeof__()
i: int = 0 for i in range(cap):
while i < cap:
slot: sizet* = _gfn_idx_slot(idx_base, si) slot: sizet* = _gfn_idx_slot(idx_base, si)
sv: sizet = slot[0] sv: sizet = slot[0]
if sv == 0: return -1 if sv == 0: return -1
@@ -76,7 +75,6 @@ def _gfn_idx_find(funcs: GenTypes.FuncEntry*, idx_base: sizet*, cap: int, name:
if entry is not None and entry.Name is not None: if entry is not None and entry.Name is not None:
if string.strcmp(entry.Name, name) == 0: return se if string.strcmp(entry.Name, name) == 0: return se
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return -1 return -1
@@ -86,14 +84,12 @@ def _gfn_idx_insert(idx_base: sizet*, cap: int, slot_index: int, name: str) -> i
h: uint64 = _gfn_hash(name) h: uint64 = _gfn_hash(name)
mask: sizet = sizet(cap - 1) mask: sizet = sizet(cap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(cap):
while i < cap:
slot: sizet* = _gfn_idx_slot(idx_base, si) slot: sizet* = _gfn_idx_slot(idx_base, si)
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(slot_index + 1) slot[0] = sizet(slot_index + 1)
return 0 return 0
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return 1 return 1
@@ -936,7 +932,7 @@ novirtual class CallGenLeafKit(CallGenCBuiltin.CallGenCBuiltin):
return 0 return 0
# _build_func_spec: build the full-signature TypeSpec (Kind=TS_FUNC) from a function after all # _build_func_spec: build the full-signature TypeSpec (Kind=TS_FUNC) from a function after all
# params are added; unlike SpecFromLLVMType's Func branch it carries func.IsVarArg. # params are added; unlike SpecFromLLVMType's Func branch it carries func.IsVarArg.
def _build_func_spec(self, func: mlirlite.Function*) -> TSpec.TypeSpec*: def _build_func_spec(self, func: mlirlite.Function*) -> TSpec.TypeSpec*:
"""Build the full-signature TypeSpec from a function; returns None on failure""" """Build the full-signature TypeSpec from a function; returns None on failure"""
+3 -5
View File
@@ -116,13 +116,11 @@ novirtual class CallGenProp(CallGenBase.CallGenBase):
n_av: sizet = string.strlen(annot_val) n_av: sizet = string.strlen(annot_val)
last_dot_av: sizet = n_av last_dot_av: sizet = n_av
depth_av: int = 0 depth_av: int = 0
ai_av: sizet = 0 for ai_av in range(n_av):
while ai_av < n_av:
ch_av: int = annot_val[ai_av] ch_av: int = annot_val[ai_av]
if ch_av == '[': depth_av += 1 if ch_av == '[': depth_av += 1
elif ch_av == ']': depth_av -= 1 elif ch_av == ']': depth_av -= 1
elif ch_av == '.' and depth_av == 0: last_dot_av = ai_av elif ch_av == '.' and depth_av == 0: last_dot_av = ai_av
ai_av += 1
if last_dot_av < n_av: return annot_val + last_dot_av + 1 if last_dot_av < n_av: return annot_val + last_dot_av + 1
return annot_val return annot_val
return None return None
@@ -263,7 +261,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase):
pfx: int = GenApi.sha1_prefix_len(name) pfx: int = GenApi.sha1_prefix_len(name)
return name + pfx if pfx != 0 else name return name + pfx if pfx != 0 else name
# _resolve_generic_receiver_name - resolve the receiver's actual generic specialization name (IR truth). # _resolve_generic_receiver_name - resolve the receiver's actual generic specialization name (IR truth).
# Strip the sha1 prefix, take the base before '['; bare generic base => fail-fast (D25), else None. # Strip the sha1 prefix, take the base before '['; bare generic base => fail-fast (D25), else None.
def _resolve_generic_receiver_name(self, pool: memhub.MemBuddy*, struct_ty: mlirlite.LLVMType*, method_name: str, cl: ast.Call*) -> str: def _resolve_generic_receiver_name(self, pool: memhub.MemBuddy*, struct_ty: mlirlite.LLVMType*, method_name: str, cl: ast.Call*) -> str:
"""Return the actual generic specialization name (sha1 stripped) or None; a bare generic base fails fast""" """Return the actual generic specialization name (sha1 stripped) or None; a bare generic base fails fast"""
@@ -287,7 +285,7 @@ novirtual class CallGenProp(CallGenBase.CallGenBase):
self.Gen.TypeGenErr.fatal_error(cl, f"方法 '{method_name}' 的接收者实际结构体类型是裸泛型基类 " f"'{short_nm}*'(丢失类型实参),元素类型未知;" f"禁止静默按默认元素类型处理(元素按 i32 处理会截断指针)," f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError") self.Gen.TypeGenErr.fatal_error(cl, f"方法 '{method_name}' 的接收者实际结构体类型是裸泛型基类 " f"'{short_nm}*'(丢失类型实参),元素类型未知;" f"禁止静默按默认元素类型处理(元素按 i32 处理会截断指针)," f"请让该变量的注解/类型带上实参(如 list[ast.AST*])", "TypeError")
return None return None
# _is_list_builtin_receiver - test list builtin methods from the receiver's actual type. # _is_list_builtin_receiver - test list builtin methods from the receiver's actual type.
# Prefer the actual LLVM struct name (sha1 stripped); fall back to the annotation/registered name. # Prefer the actual LLVM struct name (sha1 stripped); fall back to the annotation/registered name.
def _is_list_builtin_receiver(self, pool: memhub.MemBuddy*, recv_val: mlirlite.Value*, fallback_name: str, method_name: str, cl: ast.Call*) -> int: def _is_list_builtin_receiver(self, pool: memhub.MemBuddy*, recv_val: mlirlite.Value*, fallback_name: str, method_name: str, cl: ast.Call*) -> int:
"""Test list builtin methods from the receiver's actual type (fall back to the annotation name if unavailable)""" """Test list builtin methods from the receiver's actual type (fall back to the annotation name if unavailable)"""
+3 -5
View File
@@ -198,7 +198,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
# these objects are referenced at runtime, so emit a linkonce_odr definition with null init. # these objects are referenced at runtime, so emit a linkonce_odr definition with null init.
is_t_type_obj: int = 0 is_t_type_obj: int = 0
if string.strcmp(mod_path_w, "t") == 0: is_t_type_obj = self._is_t_type_object_name(at.attr) if string.strcmp(mod_path_w, "t") == 0: is_t_type_obj = self._is_t_type_object_name(at.attr)
# a class name is not a module-level global: registered classes/structs/REnums are always # a class name is not a module-level global: registered classes/structs/REnums are always
# handled by the class/REnum paths, never manufactured into an external global here. # handled by the class/REnum paths, never manufactured into an external global here.
if is_t_type_obj == 0 and self.Gen.StructGen.find_struct(at.attr) is not None: return None if is_t_type_obj == 0 and self.Gen.StructGen.find_struct(at.attr) is not None: return None
# fallback declaration name: t type objects (t.py uncompiled, no sha1) keep the bare # fallback declaration name: t type objects (t.py uncompiled, no sha1) keep the bare
@@ -600,7 +600,7 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
if alias_fe is not None and alias_fe.Ty is not None: if alias_fe is not None and alias_fe.Ty is not None:
alias_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, struct_ty, alias_fe.Ty, obj_ptr, alias_idx) alias_ptr: mlirlite.Value* = mlirlite.build_gep_struct(builder, struct_ty, alias_fe.Ty, obj_ptr, alias_idx)
if alias_ptr is not None: if alias_ptr is not None:
# REnum variant field read by its declared type (matching match binding): the slot is i32/i64, # REnum variant field read by its declared type (matching match binding): the slot is i32/i64,
# so bitcast the slot address then load the declared type (no info loss) to avoid an int→ptr error. # so bitcast the slot address then load the declared type (no info loss) to avoid an int→ptr error.
decl_ty_rn: mlirlite.LLVMType* = self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(renum_se.Name, at.attr) decl_ty_rn: mlirlite.LLVMType* = self.Gen.ClassGenEnum._lookup_renum_field_alias_ty(renum_se.Name, at.attr)
if decl_ty_rn is not None: if decl_ty_rn is not None:
@@ -878,11 +878,9 @@ novirtual class ExprGenAttr(ExprGenBase.ExprGenBase):
if bare is None: return None if bare is None: return None
st: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare) st: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare)
if st is None: return None if st is None: return None
fi: int = 0 for fi in range(st.FieldCount):
while fi < st.FieldCount:
fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st, fi) fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st, fi)
if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at.attr) == 0: return fe_u if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at.attr) == 0: return fe_u
fi += 1
return None return None
def attr_field_pointee_is_volatile(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> int: def attr_field_pointee_is_volatile(self, pool: memhub.MemBuddy*, trans: HT.Translator*, attr_node: ast.AST*) -> int:
+6 -14
View File
@@ -22,7 +22,7 @@ import lib.Stub.StubMerger.StubMergerStore as StubMergerStore
novirtual class ExprGenCdef(ExprGenBase.ExprGenBase): novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
"""Cross-module CDefine lookup""" """Cross-module CDefine lookup"""
# _build_source_path_from_sha1: build a source .vp/.py path from SHA1 via the StubMerger # _build_source_path_from_sha1: build a source .vp/.py path from SHA1 via the StubMerger
# global store (.vpi missing -> source .py); "lib/..." -> SourceDir, else IncludesDir. # global store (.vpi missing -> source .py); "lib/..." -> SourceDir, else IncludesDir.
def _build_source_path_from_sha1(self, sha1: str) -> str: def _build_source_path_from_sha1(self, sha1: str) -> str:
"""Build a source .py path from a SHA1 via the global store""" """Build a source .py path from a SHA1 via the global store"""
@@ -49,7 +49,7 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
ridx: sizet = sizet(idx_s) * MAX_RPL ridx: sizet = sizet(idx_s) * MAX_RPL
rel_path: str = rel_arr_ptr + ridx rel_path: str = rel_arr_ptr + ridx
if rel_path[0] == '\0': return None if rel_path[0] == '\0': return None
# choose base dir: 1) stored includes root IncDir (absolute, supports multiple dirs); # choose base dir: 1) stored includes root IncDir (absolute, supports multiple dirs);
# 2) prefix heuristic: "lib/" -> SourceDir, "includes/" -> IncludesDir, else SourceDir then IncludesDir. # 2) prefix heuristic: "lib/" -> SourceDir, "includes/" -> IncludesDir, else SourceDir then IncludesDir.
base_dir: str = None base_dir: str = None
rel_used: str = rel_path rel_used: str = rel_path
@@ -175,19 +175,15 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
if im_nlen > 0 and im_nlen < 256: if im_nlen > 0 and im_nlen < 256:
im_buf: str = pool.alloc(im_nlen + 1) im_buf: str = pool.alloc(im_nlen + 1)
if im_buf is not None: if im_buf is not None:
mk: sizet = 0 for mk in range(im_nlen):
while mk < im_nlen:
im_buf[mk] = imported_modules[im_start + mk] im_buf[mk] = imported_modules[im_start + mk]
mk += 1
im_buf[im_nlen] = '\0' im_buf[im_nlen] = '\0'
sub_fi: str = pool.alloc(im_nlen + 3) sub_fi: str = pool.alloc(im_nlen + 3)
if sub_fi is not None: if sub_fi is not None:
sub_fi[0] = '*' sub_fi[0] = '*'
sub_fi[1] = ':' sub_fi[1] = ':'
mk2: sizet = 0 for mk2 in range(im_nlen):
while mk2 < im_nlen:
sub_fi[2 + mk2] = im_buf[mk2] sub_fi[2 + mk2] = im_buf[mk2]
mk2 += 1
sub_fi[2 + im_nlen] = '\0' sub_fi[2 + im_nlen] = '\0'
sub_val: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi, None, depth + 1, node) sub_val: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi, None, depth + 1, node)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0: return sub_val if self.Gen.TypeGenCDef.is_cdefine_found() != 0: return sub_val
@@ -752,19 +748,15 @@ novirtual class ExprGenCdef(ExprGenBase.ExprGenBase):
if im2_nlen > 0 and im2_nlen < 256: if im2_nlen > 0 and im2_nlen < 256:
im2_buf: str = pool.alloc(im2_nlen + 1) im2_buf: str = pool.alloc(im2_nlen + 1)
if im2_buf is not None: if im2_buf is not None:
mk3: sizet = 0 for mk3 in range(im2_nlen):
while mk3 < im2_nlen:
im2_buf[mk3] = imported_modules[im2_start + mk3] im2_buf[mk3] = imported_modules[im2_start + mk3]
mk3 += 1
im2_buf[im2_nlen] = '\0' im2_buf[im2_nlen] = '\0'
sub_fi2: str = pool.alloc(im2_nlen + 3) sub_fi2: str = pool.alloc(im2_nlen + 3)
if sub_fi2 is not None: if sub_fi2 is not None:
sub_fi2[0] = '*' sub_fi2[0] = '*'
sub_fi2[1] = ':' sub_fi2[1] = ':'
mk4: sizet = 0 for mk4 in range(im2_nlen):
while mk4 < im2_nlen:
sub_fi2[2 + mk4] = im2_buf[mk4] sub_fi2[2 + mk4] = im2_buf[mk4]
mk4 += 1
sub_fi2[2 + im2_nlen] = '\0' sub_fi2[2 + im2_nlen] = '\0'
sub_val2: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi2, None, depth + 1, node) sub_val2: int64 = self._lookup_cross_module_cdefine(pool, name, sub_fi2, None, depth + 1, node)
if self.Gen.TypeGenCDef.is_cdefine_found() != 0: if self.Gen.TypeGenCDef.is_cdefine_found() != 0:
+1 -3
View File
@@ -219,8 +219,7 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
if bare_u is not None: if bare_u is not None:
st_u: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare_u) st_u: GenTypes.StructEntry* = self.Gen.StructGen.find_struct(bare_u)
if st_u is not None: if st_u is not None:
fi_u: int = 0 for fi_u in range(st_u.FieldCount):
while fi_u < st_u.FieldCount:
fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st_u, fi_u) fe_u: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(st_u, fi_u)
if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at_u.attr) == 0: if fe_u is not None and fe_u.Name is not None and string.strcmp(fe_u.Name, at_u.attr) == 0:
# [S4 read] An explicit unsigned field Spec wins # [S4 read] An explicit unsigned field Spec wins
@@ -229,7 +228,6 @@ novirtual class ExprGenOps(ExprGenBase.ExprGenBase):
if fcn_u is not None: if fcn_u is not None:
if self._annot_str_unsigned(fcn_u) != 0: return 1 if self._annot_str_unsigned(fcn_u) != 0: return 1
break break
fi_u += 1
return 0 return 0
return 0 return 0
def _node_type_signed(self, pool: memhub.MemBuddy*, node: ast.AST*, trans: HT.Translator* = None) -> int: def _node_type_signed(self, pool: memhub.MemBuddy*, node: ast.AST*, trans: HT.Translator* = None) -> int:
+6 -18
View File
@@ -179,8 +179,7 @@ novirtual class ImportsGenMixin:
if name is None: return 0 if name is None: return 0
if StubMergerStore.LookupSha1ByModName(name) is None: return 0 if StubMergerStore.LookupSha1ByModName(name) is None: return 0
nl: sizet = string.strlen(name) nl: sizet = string.strlen(name)
dot_pos: sizet = 0 for dot_pos in range(nl):
while dot_pos < nl:
if name[dot_pos] == '.': if name[dot_pos] == '.':
pfx: str = stdlib.malloc(dot_pos + 1) pfx: str = stdlib.malloc(dot_pos + 1)
if pfx is not None: if pfx is not None:
@@ -189,7 +188,6 @@ novirtual class ImportsGenMixin:
hit: int = self.is_module_imported(imported_modules, pfx) hit: int = self.is_module_imported(imported_modules, pfx)
stdlib.free(pfx) stdlib.free(pfx)
if hit != 0: return 1 if hit != 0: return 1
dot_pos += 1
return 0 return 0
# Add a from-import name mapping # Add a from-import name mapping
@@ -240,12 +238,10 @@ novirtual class ImportsGenMixin:
# Compare the name # Compare the name
if entry_name_len == name_len: if entry_name_len == name_len:
Matched: int = 1 Matched: int = 1
ei: sizet = 0 for ei in range(name_len):
while ei < name_len:
if cur[ci + ei] != local_name[ei]: if cur[ci + ei] != local_name[ei]:
Matched = 0 Matched = 0
break break
ei += 1
if Matched == 1: if Matched == 1:
# Match found; check for a third field (the original name) # Match found; check for a third field (the original name)
pos: sizet = colon1 + 1 pos: sizet = colon1 + 1
@@ -309,12 +305,10 @@ novirtual class ImportsGenMixin:
# Compare the name # Compare the name
elif entry_name_len == name_len: elif entry_name_len == name_len:
Matched: int = 1 Matched: int = 1
ei: sizet = 0 for ei in range(name_len):
while ei < name_len:
if cur[ci + ei] != name[ei]: if cur[ci + ei] != name[ei]:
Matched = 0 Matched = 0
break break
ei += 1
if Matched == 1: if Matched == 1:
mod_start2: sizet = colon_pos + 1 mod_start2: sizet = colon_pos + 1
mod_end2: sizet = mod_start2 mod_end2: sizet = mod_start2
@@ -395,12 +389,10 @@ novirtual class ImportsGenMixin:
pkg_len: sizet = string.strlen(pkg) pkg_len: sizet = string.strlen(pkg)
last_dot: sizet = 0 last_dot: sizet = 0
found: int = 0 found: int = 0
i: sizet = 0 for i in range(pkg_len):
while i < pkg_len:
if pkg[i] == '.': if pkg[i] == '.':
last_dot = i last_dot = i
found = 1 found = 1
i += 1
if found == 0: if found == 0:
# No more parents (the relative level exceeds the package depth): fall back to # No more parents (the relative level exceeds the package depth): fall back to
# the original module; a later import SHA1 check reports "module not found". # the original module; a later import SHA1 check reports "module not found".
@@ -443,13 +435,11 @@ novirtual class ImportsGenMixin:
# Find the last / or \ # Find the last / or \
last_sep: sizet = 0 last_sep: sizet = 0
found: int = 0 found: int = 0
i: sizet = 0 for i in range(rlen):
while i < rlen:
ch: char = rel_path[i] ch: char = rel_path[i]
if ch == '/' or ch == '\\': if ch == '/' or ch == '\\':
last_sep = i last_sep = i
found = 1 found = 1
i += 1
if found == 0: if found == 0:
# No directory separator -> top-level file, no package # No directory separator -> top-level file, no package
return None return None
@@ -457,12 +447,10 @@ novirtual class ImportsGenMixin:
dir_len: sizet = last_sep dir_len: sizet = last_sep
buf: str = pool.alloc(dir_len + 1) buf: str = pool.alloc(dir_len + 1)
if buf is None: return None if buf is None: return None
j: sizet = 0 for j in range(dir_len):
while j < dir_len:
ch2: char = rel_path[j] ch2: char = rel_path[j]
if ch2 == '/' or ch2 == '\\': buf[j] = '.' if ch2 == '/' or ch2 == '\\': buf[j] = '.'
else: buf[j] = ch2 else: buf[j] = ch2
j += 1
buf[dir_len] = '\0' buf[dir_len] = '\0'
return buf return buf
+3 -9
View File
@@ -55,12 +55,10 @@ def _struct_ty_hash(tyval: uint64) -> uint64:
"""Hash a Ty pointer value with 32-bit FNV-1a over its 8 bytes.""" """Hash a Ty pointer value with 32-bit FNV-1a over its 8 bytes."""
h: uint64 = uint64(FNV32_OFFSET) h: uint64 = uint64(FNV32_OFFSET)
v: uint64 = tyval v: uint64 = tyval
j: int = 0 for j in range(8):
while j < 8:
h = (h ^ (v & uint64(255))) * uint64(FNV32_PRIME) h = (h ^ (v & uint64(255))) * uint64(FNV32_PRIME)
h = h & uint64(FNV32_MASK) h = h & uint64(FNV32_MASK)
v = v >> 8 v = v >> 8
j += 1
return h return h
@@ -331,14 +329,12 @@ novirtual class StructGenMixin:
h: uint64 = _struct_name_hash(name) h: uint64 = _struct_name_hash(name)
mask: sizet = sizet(self.StructIdxCap - 1) mask: sizet = sizet(self.StructIdxCap - 1)
idx: sizet = sizet(h) & mask idx: sizet = sizet(h) & mask
i: int = 0 for i in range(self.StructIdxCap):
while i < self.StructIdxCap:
slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8))
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(ei + 1) slot[0] = sizet(ei + 1)
return 0 return 0
idx = (idx + 1) & mask idx = (idx + 1) & mask
i += 1
return 1 return 1
def _struct_type_idx_insert(self, ei: int, tyval: uint64) -> int: def _struct_type_idx_insert(self, ei: int, tyval: uint64) -> int:
@@ -348,14 +344,12 @@ novirtual class StructGenMixin:
h: uint64 = _struct_ty_hash(tyval) h: uint64 = _struct_ty_hash(tyval)
mask: sizet = sizet(self.StructIdxCap - 1) mask: sizet = sizet(self.StructIdxCap - 1)
idx: sizet = sizet(h) & mask idx: sizet = sizet(h) & mask
i: int = 0 for i in range(self.StructIdxCap):
while i < self.StructIdxCap:
slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8)) slot: sizet* = (sizet*)(uint64(base) + uint64(idx * 8))
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(ei + 1) slot[0] = sizet(ei + 1)
return 0 return 0
idx = (idx + 1) & mask idx = (idx + 1) & mask
i += 1
return 1 return 1
def _struct_idx_add(self, ei: int, entry: GenTypes.StructEntry*) -> None: def _struct_idx_add(self, ei: int, entry: GenTypes.StructEntry*) -> None:
+4 -12
View File
@@ -529,11 +529,9 @@ novirtual class Translator:
"""Return 1 if name is a registered Project macro variable.""" """Return 1 if name is a registered Project macro variable."""
if name is None or proj_vars is None: return 0 if name is None or proj_vars is None: return 0
n: sizet = len(proj_vars) n: sizet = len(proj_vars)
i: sizet = 0 for i in range(n):
while i < n:
s: str = proj_vars.get(i) s: str = proj_vars.get(i)
if s is not None and string.strcmp(s, name) == 0: return 1 if s is not None and string.strcmp(s, name) == 0: return 1
i += 1
return 0 return 0
def _vb_is_project_ctor(self, value: ast.AST*, alias: str, ctor: str) -> int: def _vb_is_project_ctor(self, value: ast.AST*, alias: str, ctor: str) -> int:
@@ -631,26 +629,22 @@ novirtual class Translator:
if kd == ast.ASTKind.Import: if kd == ast.ASTKind.Import:
names: list[ast.AST*]* = ast.Import*(child).names names: list[ast.AST*]* = ast.Import*(child).names
if names is not None: if names is not None:
ni: sizet = 0 for ni in range(len(names)):
while ni < len(names):
al: ast.Alias* = ast.Alias*(names.get(ni)) al: ast.Alias* = ast.Alias*(names.get(ni))
if al is not None and al.name is not None: if al is not None and al.name is not None:
if string.strcmp(al.name, "viperbuild") == 0: if string.strcmp(al.name, "viperbuild") == 0:
if al.asname is not None: alias = al.asname if al.asname is not None: alias = al.asname
else: alias = "viperbuild" else: alias = "viperbuild"
ni += 1
elif kd == ast.ASTKind.ImportFrom: elif kd == ast.ASTKind.ImportFrom:
ifr: ast.ImportFrom* = ast.ImportFrom*(child) ifr: ast.ImportFrom* = ast.ImportFrom*(child)
if ifr is not None and ifr.level == 0 and ifr.names is not None: if ifr is not None and ifr.level == 0 and ifr.names is not None:
if ifr.module is not None and string.strcmp(ifr.module, "viperbuild") == 0: if ifr.module is not None and string.strcmp(ifr.module, "viperbuild") == 0:
ni: sizet = 0 for ni in range(len(ifr.names)):
while ni < len(ifr.names):
al: ast.Alias* = ast.Alias*(ifr.names.get(ni)) al: ast.Alias* = ast.Alias*(ifr.names.get(ni))
if al is not None and al.name is not None: if al is not None and al.name is not None:
if string.strcmp(al.name, "Project") == 0: if string.strcmp(al.name, "Project") == 0:
if al.asname is not None: ctor = al.asname if al.asname is not None: ctor = al.asname
else: ctor = "Project" else: ctor = "Project"
ni += 1
ci += 1 ci += 1
if alias is None and ctor is None: return 0 if alias is None and ctor is None: return 0
# (2) Filter: register Project macro variables, then drop the related statements # (2) Filter: register Project macro variables, then drop the related statements
@@ -658,13 +652,11 @@ novirtual class Translator:
kept: list[ast.AST*]* = list[ast.AST*](pool, 8) kept: list[ast.AST*]* = list[ast.AST*](pool, 8)
if proj_vars is None or kept is None: return 0 if proj_vars is None or kept is None: return 0
erased: int = 0 erased: int = 0
ci = 0 for ci in range(cn):
while ci < cn:
child = ch.get(ci) child = ch.get(ci)
if child is not None: if child is not None:
if self._vb_is_macro_stmt(child, alias, ctor, proj_vars) != 0: erased = 1 if self._vb_is_macro_stmt(child, alias, ctor, proj_vars) != 0: erased = 1
else: kept.append(child) else: kept.append(child)
ci += 1
if erased != 0: tree.children = kept if erased != 0: tree.children = kept
return erased return erased
+3 -9
View File
@@ -185,8 +185,7 @@ novirtual class TranslatorGenMixin:
elem_ty_str_n: str = pool.alloc(512) elem_ty_str_n: str = pool.alloc(512)
if elem_ty_str_n is None: return None if elem_ty_str_n is None: return None
mlirlite.TypePrint(elem_ty_str_n, 512, elem_ty, pool) mlirlite.TypePrint(elem_ty_str_n, 512, elem_ty, pool)
i_n: sizet = 0 for i_n in range(cnt_total_n):
while i_n < cnt_total_n:
sub_n: str = None sub_n: str = None
if i_n < elts_count: if i_n < elts_count:
en_n: ast.AST* = elts.get(i_n) en_n: ast.AST* = elts.get(i_n)
@@ -206,7 +205,6 @@ novirtual class TranslatorGenMixin:
pos_n += sizet(written_n) pos_n += sizet(written_n)
written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n) written_n = viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "%s%s", elem_ty_str_n, sub_n)
pos_n += sizet(written_n) pos_n += sizet(written_n)
i_n += 1
viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]") viperlib.snprintf(buf_n + pos_n, buf_size_n - pos_n, "]")
return buf_n return buf_n
for zi in range(elts_count): for zi in range(elts_count):
@@ -238,8 +236,7 @@ novirtual class TranslatorGenMixin:
# Write elements up to the declared length arr_count, zero-padding short lists so the # Write elements up to the declared length arr_count, zero-padding short lists so the
# initializer element count always matches the type llc expects. # initializer element count always matches the type llc expects.
i: sizet = 0 for i in range(cnt_total):
while i < cnt_total:
elem_val: int64 = 0 elem_val: int64 = 0
if i < elts_count: if i < elts_count:
elem_node: ast.AST* = elts.get(i) elem_node: ast.AST* = elts.get(i)
@@ -263,7 +260,6 @@ novirtual class TranslatorGenMixin:
pos += sizet(written) pos += sizet(written)
written = viperlib.snprintf(buf + pos, buf_size - pos, "%s %lld", elem_ir_ty, elem_val) written = viperlib.snprintf(buf + pos, buf_size - pos, "%s %lld", elem_ir_ty, elem_val)
pos += sizet(written) pos += sizet(written)
i += 1
# Write the closing "]" suffix # Write the closing "]" suffix
viperlib.snprintf(buf + pos, buf_size - pos, "]") viperlib.snprintf(buf + pos, buf_size - pos, "]")
@@ -286,8 +282,7 @@ novirtual class TranslatorGenMixin:
if buf is None: return None if buf is None: return None
written: int = viperlib.snprintf(buf, buf_size, "[") written: int = viperlib.snprintf(buf, buf_size, "[")
pos: sizet = sizet(written) pos: sizet = sizet(written)
i: sizet = 0 for i in range(sizet(arr_count)):
while i < sizet(arr_count):
if i > 0: if i > 0:
written = viperlib.snprintf(buf + pos, buf_size - pos, ", ") written = viperlib.snprintf(buf + pos, buf_size - pos, ", ")
pos += sizet(written) pos += sizet(written)
@@ -295,7 +290,6 @@ novirtual class TranslatorGenMixin:
if i < slen: bv = int64(str_val[i]) if i < slen: bv = int64(str_val[i])
written = viperlib.snprintf(buf + pos, buf_size - pos, "i8 %lld", bv) written = viperlib.snprintf(buf + pos, buf_size - pos, "i8 %lld", bv)
pos += sizet(written) pos += sizet(written)
i += 1
viperlib.snprintf(buf + pos, buf_size - pos, "]") viperlib.snprintf(buf + pos, buf_size - pos, "]")
return buf return buf
+2 -6
View File
@@ -64,8 +64,7 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
h: uint64 = self._cdef_idx_hash(name) h: uint64 = self._cdef_idx_hash(name)
mask: sizet = sizet(self.CDefineNameIdxCap - 1) mask: sizet = sizet(self.CDefineNameIdxCap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(self.CDefineNameIdxCap):
while i < self.CDefineNameIdxCap:
slot: sizet* = self._cdef_idx_slot(si) slot: sizet* = self._cdef_idx_slot(si)
sv: sizet = slot[0] sv: sizet = slot[0]
if sv == 0: return -1 if sv == 0: return -1
@@ -73,7 +72,6 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
nm: str = self.CDefineNames.get(sizet(se)) nm: str = self.CDefineNames.get(sizet(se))
if nm is not None and string.strcmp(nm, name) == 0: return se if nm is not None and string.strcmp(nm, name) == 0: return se
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return -1 return -1
def _cdef_idx_insert(self, slot_index: int, name: str) -> int: def _cdef_idx_insert(self, slot_index: int, name: str) -> int:
@@ -82,14 +80,12 @@ novirtual class TypeGenCDef(TypeGenBase.TypeGenBase):
h: uint64 = self._cdef_idx_hash(name) h: uint64 = self._cdef_idx_hash(name)
mask: sizet = sizet(self.CDefineNameIdxCap - 1) mask: sizet = sizet(self.CDefineNameIdxCap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(self.CDefineNameIdxCap):
while i < self.CDefineNameIdxCap:
slot: sizet* = self._cdef_idx_slot(si) slot: sizet* = self._cdef_idx_slot(si)
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(slot_index + 1) slot[0] = sizet(slot_index + 1)
return 0 return 0
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return 1 return 1
def _cdef_idx_sync_append(self, name: str) -> None: def _cdef_idx_sync_append(self, name: str) -> None:
+3 -9
View File
@@ -71,8 +71,7 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
h: uint64 = _ctypedef_idx_hash(name) h: uint64 = _ctypedef_idx_hash(name)
mask: sizet = sizet(self.CTypedefNameIdxCap - 1) mask: sizet = sizet(self.CTypedefNameIdxCap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(self.CTypedefNameIdxCap):
while i < self.CTypedefNameIdxCap:
slot: sizet* = self._ctypedef_idx_slot(si) slot: sizet* = self._ctypedef_idx_slot(si)
sv: sizet = slot[0] sv: sizet = slot[0]
if sv == 0: return -1 if sv == 0: return -1
@@ -80,7 +79,6 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
nm: str = self.CTypedefNames.get(sizet(se)) nm: str = self.CTypedefNames.get(sizet(se))
if nm is not None and string.strcmp(nm, name) == 0: return se if nm is not None and string.strcmp(nm, name) == 0: return se
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return -1 return -1
def _ctypedef_idx_insert(self, slot_index: int, name: str) -> int: def _ctypedef_idx_insert(self, slot_index: int, name: str) -> int:
@@ -89,14 +87,12 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
h: uint64 = _ctypedef_idx_hash(name) h: uint64 = _ctypedef_idx_hash(name)
mask: sizet = sizet(self.CTypedefNameIdxCap - 1) mask: sizet = sizet(self.CTypedefNameIdxCap - 1)
si: sizet = sizet(h) & mask si: sizet = sizet(h) & mask
i: int = 0 for i in range(self.CTypedefNameIdxCap):
while i < self.CTypedefNameIdxCap:
slot: sizet* = self._ctypedef_idx_slot(si) slot: sizet* = self._ctypedef_idx_slot(si)
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(slot_index + 1) slot[0] = sizet(slot_index + 1)
return 0 return 0
si = (si + 1) & mask si = (si + 1) & mask
i += 1
return 1 return 1
def _ctypedef_idx_sync_append(self, name: str) -> None: def _ctypedef_idx_sync_append(self, name: str) -> None:
@@ -216,12 +212,10 @@ class TypeGenCType(TypeGenBase.TypeGenBase):
# rules out a match without strlen. # rules out a match without strlen.
if nm[0] != text[start] or string.strlen(nm) != want: continue if nm[0] != text[start] or string.strlen(nm) != want: continue
hit: int = 1 hit: int = 1
k: sizet = 0 for k in range(want):
while k < want:
if nm[k] != text[start + k]: if nm[k] != text[start + k]:
hit = 0 hit = 0
break break
k += 1
if hit != 0: if hit != 0:
ts: str = self.CTypedefTypeStrs.get(i) ts: str = self.CTypedefTypeStrs.get(i)
self.CTypedefFound = 1 self.CTypedefFound = 1
+18 -32
View File
@@ -331,15 +331,13 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
if seg_len == 0: return type_name if seg_len == 0: return type_name
pipe_idx: sizet = seg_len pipe_idx: sizet = seg_len
p_depth: int = 0 p_depth: int = 0
pi: sizet = 0 for pi in range(seg_len):
while pi < seg_len:
ch_p: int = type_name[pi] ch_p: int = type_name[pi]
if ch_p == '[': p_depth += 1 if ch_p == '[': p_depth += 1
elif ch_p == ']': p_depth -= 1 elif ch_p == ']': p_depth -= 1
elif ch_p == '|' and p_depth == 0: elif ch_p == '|' and p_depth == 0:
pipe_idx = pi pipe_idx = pi
break break
pi += 1
if pipe_idx < seg_len: if pipe_idx < seg_len:
left_buf: str = pool.alloc(pipe_idx + 1) left_buf: str = pool.alloc(pipe_idx + 1)
if left_buf is None: return type_name if left_buf is None: return type_name
@@ -376,15 +374,13 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
# normalize each; t.CArray / list keep their count arg verbatim. # normalize each; t.CArray / list keep their count arg verbatim.
lb_idx: sizet = seg_len lb_idx: sizet = seg_len
ld: int = 0 ld: int = 0
li2: sizet = 0 for li2 in range(seg_len):
while li2 < seg_len:
if type_name[li2] == '[': if type_name[li2] == '[':
if ld == 0: if ld == 0:
lb_idx = li2 lb_idx = li2
break break
ld += 1 ld += 1
elif type_name[li2] == ']': ld -= 1 elif type_name[li2] == ']': ld -= 1
li2 += 1
if lb_idx < seg_len and type_name[seg_len - 1] == ']': if lb_idx < seg_len and type_name[seg_len - 1] == ']':
container_g: str = pool.alloc(lb_idx + 1) container_g: str = pool.alloc(lb_idx + 1)
if container_g is not None: if container_g is not None:
@@ -675,12 +671,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
# Check for '|' (BinOp): search only within the valid range [0, seg_len) # Check for '|' (BinOp): search only within the valid range [0, seg_len)
pipe_idx: sizet = seg_len pipe_idx: sizet = seg_len
pi: sizet = 0 for pi in range(seg_len):
while pi < seg_len:
if type_str[pi] == '|': if type_str[pi] == '|':
pipe_idx = pi pipe_idx = pi
break break
pi += 1
if pipe_idx < seg_len: if pipe_idx < seg_len:
# Copy the left segment into its own buffer (trim trailing spaces), preserving the original # Copy the left segment into its own buffer (trim trailing spaces), preserving the original
left_len: sizet = pipe_idx left_len: sizet = pipe_idx
@@ -699,12 +693,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
# Check for '[' (Subscript) like t.Callable[[int], int]; must precede the '.' # Check for '[' (Subscript) like t.Callable[[int], int]; must precede the '.'
# check since it is a Subscript. Parse fully via ast.parse_expression. # check since it is a Subscript. Parse fully via ast.parse_expression.
bracket_idx: sizet = seg_len bracket_idx: sizet = seg_len
bi: sizet = 0 for bi in range(seg_len):
while bi < seg_len:
if type_str[bi] == '[': if type_str[bi] == '[':
bracket_idx = bi bracket_idx = bi
break break
bi += 1
if bracket_idx < seg_len: if bracket_idx < seg_len:
# If the inner part starts with a digit (a "{16hex}.Class" name), the lexer # If the inner part starts with a digit (a "{16hex}.Class" name), the lexer
# mis-scans it as a number; split base+slice manually for a single non-nested arg. # mis-scans it as a number; split base+slice manually for a single non-nested arg.
@@ -759,12 +751,10 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
# Whether the text contains '.' (Attribute): search only within [0, seg_len). # Whether the text contains '.' (Attribute): search only within [0, seg_len).
dot_idx: sizet = seg_len dot_idx: sizet = seg_len
di: sizet = 0 for di in range(seg_len):
while di < seg_len:
if type_str[di] == '.': if type_str[di] == '.':
dot_idx = di dot_idx = di
break break
di += 1
if dot_idx < seg_len: if dot_idx < seg_len:
# Trim trailing spaces of the module-name segment # Trim trailing spaces of the module-name segment
mod_len: sizet = dot_idx mod_len: sizet = dot_idx
@@ -840,17 +830,17 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
lib_ty: mlirlite.LLVMType* = self.resolve_annotation_type(pool, lib_node, imported_modules, from_imports, trans, 1) lib_ty: mlirlite.LLVMType* = self.resolve_annotation_type(pool, lib_node, imported_modules, from_imports, trans, 1)
self.Gen.TypeGenCType.CTypedefResolveDepth -= 1 self.Gen.TypeGenCType.CTypedefResolveDepth -= 1
if lib_ty is not None: return lib_ty if lib_ty is not None: return lib_ty
# Bare Python/C builtin aliases: map_t_type only knows the t.CXxx spelling, so # Bare Python/C builtin aliases: map_t_type only knows the t.CXxx spelling, so
# resolve them here to match resolve_annotation_type's bare-name branch. Without # resolve them here to match resolve_annotation_type's bare-name branch. Without
# this the two-arg form int(x, t.CPtr) misses _tc_h4 and fails fast as "int". # this the two-arg form int(x, t.CPtr) misses _tc_h4 and fails fast as "int".
if string.strcmp(name, "str") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool)) if string.strcmp(name, "str") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool))
if string.strcmp(name, "bytes") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool)) if string.strcmp(name, "bytes") == 0: return mlirlite.Ptr(pool, mlirlite.Int8(pool))
if string.strcmp(name, "int") == 0: return mlirlite.Int32(pool) if string.strcmp(name, "int") == 0: return mlirlite.Int32(pool)
if string.strcmp(name, "char") == 0: return mlirlite.Int8(pool) if string.strcmp(name, "char") == 0: return mlirlite.Int8(pool)
if string.strcmp(name, "bool") == 0: return mlirlite.Int1(pool) if string.strcmp(name, "bool") == 0: return mlirlite.Int1(pool)
if string.strcmp(name, "float") == 0: return mlirlite.Float(pool) if string.strcmp(name, "float") == 0: return mlirlite.Float(pool)
if string.strcmp(name, "double") == 0: return mlirlite.Double(pool) if string.strcmp(name, "double") == 0: return mlirlite.Double(pool)
if string.strcmp(name, "void") == 0: return mlirlite.Void(pool) if string.strcmp(name, "void") == 0: return mlirlite.Void(pool)
return self.map_t_type(pool, name) return self.map_t_type(pool, name)
def get_type_size_bytes(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str) -> int: def get_type_size_bytes(self, pool: memhub.MemBuddy*, name: str, imported_modules: str, from_imports: str) -> int:
"""Return the type size in bytes via resolve_typedef_or_map, or 0 on failure.""" """Return the type size in bytes via resolve_typedef_or_map, or 0 on failure."""
@@ -990,10 +980,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
out_buf[ci] = buf[line_start + name_s + ci] out_buf[ci] = buf[line_start + name_s + ci]
ci += 1 ci += 1
out_buf[name_l] = '\0' out_buf[name_l] = '\0'
ci = 0 for ci in range(vlen):
while ci < vlen:
out_buf[name_l + 1 + ci] = buf[line_start + vs + ci] out_buf[name_l + 1 + ci] = buf[line_start + vs + ci]
ci += 1
out_buf[name_l + 1 + vlen] = '\0' out_buf[name_l + 1 + vlen] = '\0'
return 1 return 1
def _lookup_builtins_typedef(self, pool: memhub.MemBuddy*, name: str) -> str: def _lookup_builtins_typedef(self, pool: memhub.MemBuddy*, name: str) -> str:
@@ -2384,10 +2372,8 @@ novirtual class TypeGenResolve(TypeGenBase.TypeGenBase):
cur_lvl = nxt_lvl cur_lvl = nxt_lvl
# Result = wrap the other side's type in N layers of Ptr # Result = wrap the other side's type in N layers of Ptr
res_ty: mlirlite.LLVMType* = cptr_other_ty res_ty: mlirlite.LLVMType* = cptr_other_ty
li2: int = 0 for li2 in range(cptr_level):
while li2 < cptr_level:
res_ty = mlirlite.Ptr(pool, res_ty) res_ty = mlirlite.Ptr(pool, res_ty)
li2 += 1
return res_ty return res_ty
# No CPtr marker: return the first non-attribute-marker side. Attribute markers # No CPtr marker: return the first non-attribute-marker side. Attribute markers
+6 -18
View File
@@ -185,8 +185,7 @@ def _spec_index_find(arena: TypeSpecArena*, key: str, h: uint64) -> int:
if arena.Index is None or arena.IndexCap <= 0: return -1 if arena.Index is None or arena.IndexCap <= 0: return -1
mask: sizet = sizet(arena.IndexCap - 1) mask: sizet = sizet(arena.IndexCap - 1)
idx: sizet = sizet(h) & mask idx: sizet = sizet(h) & mask
i: int = 0 for i in range(arena.IndexCap):
while i < arena.IndexCap:
slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8)) slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8))
sv: sizet = slot[0] sv: sizet = slot[0]
if sv == 0: return -1 if sv == 0: return -1
@@ -194,7 +193,6 @@ def _spec_index_find(arena: TypeSpecArena*, key: str, h: uint64) -> int:
ek: str = _spec_key_at(arena.Keys, ei) ek: str = _spec_key_at(arena.Keys, ei)
if ek is not None and string.strcmp(ek, key) == 0: return ei if ek is not None and string.strcmp(ek, key) == 0: return ei
idx = (idx + 1) & mask idx = (idx + 1) & mask
i += 1
return -1 return -1
@@ -205,14 +203,12 @@ def _spec_index_insert(arena: TypeSpecArena*, key: str, h: uint64, ei: int) -> i
if arena.Index is None or arena.IndexCap <= 0: return 1 if arena.Index is None or arena.IndexCap <= 0: return 1
mask: sizet = sizet(arena.IndexCap - 1) mask: sizet = sizet(arena.IndexCap - 1)
idx: sizet = sizet(h) & mask idx: sizet = sizet(h) & mask
i: int = 0 for i in range(arena.IndexCap):
while i < arena.IndexCap:
slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8)) slot: sizet* = (sizet*)(uint64(arena.Index) + uint64(idx * 8))
if slot[0] == 0: if slot[0] == 0:
slot[0] = sizet(ei + 1) slot[0] = sizet(ei + 1)
return 0 return 0
idx = (idx + 1) & mask idx = (idx + 1) & mask
i += 1
return 1 return 1
@@ -426,8 +422,7 @@ def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int:
pos: sizet = 0 pos: sizet = 0
pos = _spec_text_append(buf, buf_size, pos, "fn(") pos = _spec_text_append(buf, buf_size, pos, "fn(")
if pos >= buf_size: return 1 if pos >= buf_size: return 1
i: int = 0 for i in range(sp.ParamCount):
while i < sp.ParamCount:
if i > 0: if i > 0:
pos = _spec_text_append(buf, buf_size, pos, ",") pos = _spec_text_append(buf, buf_size, pos, ",")
if pos >= buf_size: return 1 if pos >= buf_size: return 1
@@ -438,7 +433,6 @@ def _spec_to_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int:
if _spec_to_text(param, param_buf, SPEC_TEXT_MAX, depth + 1) != 0: return 1 if _spec_to_text(param, param_buf, SPEC_TEXT_MAX, depth + 1) != 0: return 1
pos = _spec_text_append(buf, buf_size, pos, param_buf) pos = _spec_text_append(buf, buf_size, pos, param_buf)
if pos >= buf_size: return 1 if pos >= buf_size: return 1
i += 1
if sp.IsVarArg == 1: if sp.IsVarArg == 1:
if sp.ParamCount > 0: pos = _spec_text_append(buf, buf_size, pos, ",...") if sp.ParamCount > 0: pos = _spec_text_append(buf, buf_size, pos, ",...")
else: pos = _spec_text_append(buf, buf_size, pos, "...") else: pos = _spec_text_append(buf, buf_size, pos, "...")
@@ -461,14 +455,12 @@ def _spec_text_append(buf: str, buf_size: sizet, pos: sizet, text: str) -> sizet
"""Append text at pos in buf; buf_size sentinel when full, else the new position""" """Append text at pos in buf; buf_size sentinel when full, else the new position"""
if buf is None or text is None: return buf_size if buf is None or text is None: return buf_size
tlen: sizet = string.strlen(text) tlen: sizet = string.strlen(text)
i: sizet = 0 for i in range(tlen):
while i < tlen:
if pos + 1 >= buf_size: if pos + 1 >= buf_size:
buf[pos] = '\0' buf[pos] = '\0'
return buf_size return buf_size
buf[pos] = text[i] buf[pos] = text[i]
pos += 1 pos += 1
i += 1
buf[pos] = '\0' buf[pos] = '\0'
return pos return pos
@@ -626,14 +618,12 @@ def InternSpec(arena: TypeSpecArena*, sp: TypeSpec*) -> TypeSpec*:
return (TypeSpec*)(uint64(slot_e[0])) return (TypeSpec*)(uint64(slot_e[0]))
if arena.Index is None: if arena.Index is None:
# index unavailable: fall back to the linear scan # index unavailable: fall back to the linear scan
i: int = 0 for i in range(arena.Count):
while i < arena.Count:
exist_key: str = _spec_key_at(arena.Keys, i) exist_key: str = _spec_key_at(arena.Keys, i)
if exist_key is not None and string.strcmp(exist_key, key_buf) == 0: if exist_key is not None and string.strcmp(exist_key, key_buf) == 0:
slot_e2: sizet* = (sizet*)(uint64(arena.Specs) + uint64(i * 8)) slot_e2: sizet* = (sizet*)(uint64(arena.Specs) + uint64(i * 8))
if slot_e2 is None: return None if slot_e2 is None: return None
return (TypeSpec*)(uint64(slot_e2[0])) return (TypeSpec*)(uint64(slot_e2[0]))
i += 1
# Miss: append. Table full = fail-fast (never return None, which would silently # Miss: append. Table full = fail-fast (never return None, which would silently
# lose type info up the call chain and corrupt signedness -> zext/sext direction). # lose type info up the call chain and corrupt signedness -> zext/sext direction).
if arena.Count >= arena.Cap: if arena.Count >= arena.Cap:
@@ -881,14 +871,12 @@ def _spec_llvm_text(sp: TypeSpec*, buf: str, buf_size: sizet, depth: int) -> int
if sp.Kind == TS_FUNC: if sp.Kind == TS_FUNC:
if _spec_llvm_text(sp.Ret, buf, buf_size, depth + 1) != 0: return 1 if _spec_llvm_text(sp.Ret, buf, buf_size, depth + 1) != 0: return 1
if _spec_llvm_append(buf, buf_size, " (") != 0: return 1 if _spec_llvm_append(buf, buf_size, " (") != 0: return 1
i: int = 0 for i in range(sp.ParamCount):
while i < sp.ParamCount:
if i > 0: if i > 0:
if _spec_llvm_append(buf, buf_size, ", ") != 0: return 1 if _spec_llvm_append(buf, buf_size, ", ") != 0: return 1
ps: TypeSpec* = _spec_param_at(sp, i) ps: TypeSpec* = _spec_param_at(sp, i)
if ps is None: return 1 if ps is None: return 1
if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0: return 1 if _spec_llvm_text(ps, buf, buf_size, depth + 1) != 0: return 1
i += 1
# vararg suffix (unique to this Spec convention, see above) # vararg suffix (unique to this Spec convention, see above)
if sp.IsVarArg == 1: if sp.IsVarArg == 1:
if sp.ParamCount > 0: if sp.ParamCount > 0:
+3 -9
View File
@@ -1377,11 +1377,9 @@ def _repl_sig_to_text(tag: int, bits: int, pc: int) -> str:
"""Render ReplSigResult + ReplSigTags/Bits as "(P1, P2) -> R" (PermPool buffer).""" """Render ReplSigResult + ReplSigTags/Bits as "(P1, P2) -> R" (PermPool buffer)."""
if ReplSigText is None: return "(?)" if ReplSigText is None: return "(?)"
pos: int = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, 0, "(") pos: int = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, 0, "(")
i: int = 0 for i in range(pc):
while i < pc:
if i > 0: pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ", ") if i > 0: pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ", ")
pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(ReplSigTags[i]), int(ReplSigBits[i]))) pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(ReplSigTags[i]), int(ReplSigBits[i])))
i += 1
pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ") -> ") pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, ") -> ")
pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(tag, bits)) pos = _repl_cat_str(ReplSigText, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(tag, bits))
if pos < 0: return "(?)" if pos < 0: return "(?)"
@@ -1428,12 +1426,10 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int:
sig_same: int = 1 sig_same: int = 1
if old.RetTag != ReplSigResult.RetTag or old.RetBits != ReplSigResult.RetBits or old.ParamCount != ReplSigResult.ParamCount: sig_same = 0 if old.RetTag != ReplSigResult.RetTag or old.RetBits != ReplSigResult.RetBits or old.ParamCount != ReplSigResult.ParamCount: sig_same = 0
if sig_same != 0: if sig_same != 0:
pi: int = 0 for pi in range(old.ParamCount):
while pi < old.ParamCount:
if int(old.ParamTags[pi]) != int(ReplSigTags[pi]) or int(old.ParamBits[pi]) != int(ReplSigBits[pi]): if int(old.ParamTags[pi]) != int(ReplSigTags[pi]) or int(old.ParamBits[pi]) != int(ReplSigBits[pi]):
sig_same = 0 sig_same = 0
break break
pi += 1
if sig_same == 0: if sig_same == 0:
stdio.printf("M3: 会话函数 '%s' 重定义签名不一致(旧 %s,新 %s)\n" " M3 允许同签名覆盖(只换地址);换签名会让先前片段里已编好的" "调用点按旧 ABI 调新代码 —— 该片段整体不执行,请换名字\n", nm, _repl_entry_sig_text(old), _repl_sig_to_text(ReplSigResult.RetTag, ReplSigResult.RetBits, ReplSigResult.ParamCount)) stdio.printf("M3: 会话函数 '%s' 重定义签名不一致(旧 %s,新 %s)\n" " M3 允许同签名覆盖(只换地址);换签名会让先前片段里已编好的" "调用点按旧 ABI 调新代码 —— 该片段整体不执行,请换名字\n", nm, _repl_entry_sig_text(old), _repl_sig_to_text(ReplSigResult.RetTag, ReplSigResult.RetBits, ReplSigResult.ParamCount))
return 1 return 1
@@ -1447,11 +1443,9 @@ def _repl_precheck_session_funcs(mod: mlirlite.LLVMModule*) -> int:
def _repl_entry_sig_text(e: rawptr[GenTypes.ReplFuncEntry]) -> str: def _repl_entry_sig_text(e: rawptr[GenTypes.ReplFuncEntry]) -> str:
if e is None or ReplSigText2 is None: return "(?)" if e is None or ReplSigText2 is None: return "(?)"
pos: int = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, 0, "(") pos: int = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, 0, "(")
i: int = 0 for i in range(e.ParamCount):
while i < e.ParamCount:
if i > 0: pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ", ") if i > 0: pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ", ")
pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(e.ParamTags[i]), int(e.ParamBits[i]))) pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(int(e.ParamTags[i]), int(e.ParamBits[i])))
i += 1
pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ") -> ") pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, ") -> ")
pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(e.RetTag, e.RetBits)) pos = _repl_cat_str(ReplSigText2, _REPL_SIG_TEXT_CAP, pos, _repl_tag_text(e.RetTag, e.RetBits))
if pos < 0: return "(?)" if pos < 0: return "(?)"
+19 -57
View File
@@ -131,11 +131,9 @@ def _BaseNameOf(path: str) -> str:
if path is None: return None if path is None: return None
n: sizet = string.strlen(path) n: sizet = string.strlen(path)
start: sizet = 0 start: sizet = 0
i: sizet = 0 for i in range(n):
while i < n:
ch: char = path[i] ch: char = path[i]
if ch == '/' or ch == '\\': start = i + 1 if ch == '/' or ch == '\\': start = i + 1
i += 1
return _DupStd(path + start) return _DupStd(path + start)
@@ -168,12 +166,10 @@ def _FindInList(names: list[str]*, name: str) -> int:
"""Linear-search names for name; return its index, or -1 if not found.""" """Linear-search names for name; return its index, or -1 if not found."""
if names is None or name is None: return -1 if names is None or name is None: return -1
n: sizet = names.__len__() n: sizet = names.__len__()
i: sizet = 0 for i in range(n):
while i < n:
s: str = names.get(i) s: str = names.get(i)
if s is not None: if s is not None:
if string.strcmp(s, name) == 0: return int(i) if string.strcmp(s, name) == 0: return int(i)
i += 1
return -1 return -1
@@ -203,8 +199,7 @@ def _SplitInto(out: list[str]*, joined: str) -> int:
n: sizet = string.strlen(joined) n: sizet = string.strlen(joined)
if n == 0: return 1 if n == 0: return 1
start: sizet = 0 start: sizet = 0
i: sizet = 0 for i in range(n + 1):
while i <= n:
if i == n or joined[i] == char(VB_SEP_CODE): if i == n or joined[i] == char(VB_SEP_CODE):
seg: str = stdlib.malloc(i - start + 1) seg: str = stdlib.malloc(i - start + 1)
if seg is None: return 0 if seg is None: return 0
@@ -213,7 +208,6 @@ def _SplitInto(out: list[str]*, joined: str) -> int:
out.append(_DupScratch(seg)) out.append(_DupScratch(seg))
stdlib.free(seg) stdlib.free(seg)
start = i + 1 start = i + 1
i += 1
return 1 return 1
@@ -233,8 +227,7 @@ def _JoinSep(lst: list[str]*) -> str:
buf: str = _scratch.alloc(total + 1) buf: str = _scratch.alloc(total + 1)
if buf is None: return None if buf is None: return None
pos: sizet = 0 pos: sizet = 0
i = 0 for i in range(n):
while i < n:
s = lst.get(i) s = lst.get(i)
if s is not None: if s is not None:
sl: sizet = string.strlen(s) sl: sizet = string.strlen(s)
@@ -243,7 +236,6 @@ def _JoinSep(lst: list[str]*) -> str:
pos += 1 pos += 1
string.strcpy(buf + pos, s) string.strcpy(buf + pos, s)
pos += sl pos += sl
i += 1
buf[pos] = '\0' buf[pos] = '\0'
return buf return buf
@@ -263,8 +255,7 @@ def _JoinSpace(lst: list[str]*) -> str:
buf: str = stdlib.malloc(total + 1) buf: str = stdlib.malloc(total + 1)
if buf is None: return None if buf is None: return None
pos: sizet = 0 pos: sizet = 0
i = 0 for i in range(n):
while i < n:
s = lst.get(i) s = lst.get(i)
if s is not None: if s is not None:
sl: sizet = string.strlen(s) sl: sizet = string.strlen(s)
@@ -273,7 +264,6 @@ def _JoinSpace(lst: list[str]*) -> str:
pos += 1 pos += 1
string.strcpy(buf + pos, s) string.strcpy(buf + pos, s)
pos += sl pos += sl
i += 1
buf[pos] = '\0' buf[pos] = '\0'
return buf return buf
@@ -284,12 +274,10 @@ def _FirstSpaceTok(joined: str) -> str:
n: sizet = string.strlen(joined) n: sizet = string.strlen(joined)
if n == 0: return None if n == 0: return None
sp: sizet = n sp: sizet = n
i: sizet = 0 for i in range(n):
while i < n:
if joined[i] == ' ': if joined[i] == ' ':
sp = i sp = i
break break
i += 1
seg: str = stdlib.malloc(sp + 1) seg: str = stdlib.malloc(sp + 1)
if seg is None: return None if seg is None: return None
string.strncpy(seg, joined, sp) string.strncpy(seg, joined, sp)
@@ -349,8 +337,7 @@ def _EvalList(node: ast.AST*, out: list[str]*) -> int:
lst: ast.List* = ast.List*(node) lst: ast.List* = ast.List*(node)
if lst is None or lst.elts is None: return 0 if lst is None or lst.elts is None: return 0
n: sizet = lst.elts.__len__() n: sizet = lst.elts.__len__()
i: sizet = 0 for i in range(n):
while i < n:
e: ast.AST* = lst.elts.get(i) e: ast.AST* = lst.elts.get(i)
if e is None: return 0 if e is None: return 0
if e.kind() == ast.ASTKind.Starred: if e.kind() == ast.ASTKind.Starred:
@@ -360,7 +347,6 @@ def _EvalList(node: ast.AST*, out: list[str]*) -> int:
else: else:
if _EvalStr(e) == 0: return 0 if _EvalStr(e) == 0: return 0
out.append(_DupScratch(_g_out_str)) out.append(_DupScratch(_g_out_str))
i += 1
return 1 return 1
if k == ast.ASTKind.BinOp: if k == ast.ASTKind.BinOp:
bop: ast.BinOp* = ast.BinOp*(node) bop: ast.BinOp* = ast.BinOp*(node)
@@ -423,8 +409,7 @@ def _HandleImport(stmt: ast.Import*) -> int:
global _alias, _saw_viperbuild global _alias, _saw_viperbuild
if stmt is None or stmt.names is None: return 0 if stmt is None or stmt.names is None: return 0
n: sizet = stmt.names.__len__() n: sizet = stmt.names.__len__()
i: sizet = 0 for i in range(n):
while i < n:
al: ast.Alias* = ast.Alias*(stmt.names.get(i)) al: ast.Alias* = ast.Alias*(stmt.names.get(i))
if al is not None and al.name is not None: if al is not None and al.name is not None:
if string.strcmp(al.name, "viperbuild") == 0: if string.strcmp(al.name, "viperbuild") == 0:
@@ -432,7 +417,6 @@ def _HandleImport(stmt: ast.Import*) -> int:
if al.asname is not None: _alias = _DupScratch(al.asname) if al.asname is not None: _alias = _DupScratch(al.asname)
else: _alias = _DupScratch("viperbuild") else: _alias = _DupScratch("viperbuild")
else: _AddPending(al.name) else: _AddPending(al.name)
i += 1
return 0 return 0
@@ -450,14 +434,12 @@ def _HandleImportFrom(stmt: ast.ImportFrom*) -> int:
_saw_viperbuild = 1 _saw_viperbuild = 1
if stmt.names is None: return 0 if stmt.names is None: return 0
n: sizet = stmt.names.__len__() n: sizet = stmt.names.__len__()
i: sizet = 0 for i in range(n):
while i < n:
al: ast.Alias* = ast.Alias*(stmt.names.get(i)) al: ast.Alias* = ast.Alias*(stmt.names.get(i))
if al is not None and al.name is not None: if al is not None and al.name is not None:
if string.strcmp(al.name, "Project") == 0: if string.strcmp(al.name, "Project") == 0:
if al.asname is not None: _ctor_name = _DupScratch(al.asname) if al.asname is not None: _ctor_name = _DupScratch(al.asname)
else: _ctor_name = _DupScratch("Project") else: _ctor_name = _DupScratch("Project")
i += 1
return 0 return 0
@@ -505,8 +487,7 @@ def _ApplyCtorArgs(cl: ast.Call*) -> int:
_c_version = _DupStd(_g_out_str) _c_version = _DupStd(_g_out_str)
if cl.keywords is None: return 0 if cl.keywords is None: return 0
n: sizet = cl.keywords.__len__() n: sizet = cl.keywords.__len__()
i: sizet = 0 for i in range(n):
while i < n:
kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i))
if kw is not None and kw.arg is not None and kw.value is not None: if kw is not None and kw.arg is not None and kw.value is not None:
if string.strcmp(kw.arg, "name") == 0: if string.strcmp(kw.arg, "name") == 0:
@@ -522,7 +503,6 @@ def _ApplyCtorArgs(cl: ast.Call*) -> int:
else: else:
VLogger.error(f"viperbuild: Project(...) 不支持的关键字 {kw.arg}", "viperbuild") VLogger.error(f"viperbuild: Project(...) 不支持的关键字 {kw.arg}", "viperbuild")
return 1 return 1
i += 1
return 0 return 0
@@ -660,12 +640,10 @@ def _HandleConfigCall(cl: ast.Call*) -> int:
"""Handle a proj.config(kw=...) call.""" """Handle a proj.config(kw=...) call."""
if cl is None or cl.keywords is None: return 0 if cl is None or cl.keywords is None: return 0
n: sizet = cl.keywords.__len__() n: sizet = cl.keywords.__len__()
i: sizet = 0 for i in range(n):
while i < n:
kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i))
if kw is not None and kw.arg is not None and kw.value is not None: if kw is not None and kw.arg is not None and kw.value is not None:
if _SetField(kw.arg, kw.value) != 0: return 1 if _SetField(kw.arg, kw.value) != 0: return 1
i += 1
return 0 return 0
@@ -679,8 +657,7 @@ def _HandleBuildCall(cl: ast.Call*) -> int:
_c_has_build = 1 _c_has_build = 1
if cl.keywords is None: return 0 if cl.keywords is None: return 0
n: sizet = cl.keywords.__len__() n: sizet = cl.keywords.__len__()
i: sizet = 0 for i in range(n):
while i < n:
kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i))
if kw is not None and kw.arg is not None and kw.value is not None: if kw is not None and kw.arg is not None and kw.value is not None:
if string.strcmp(kw.arg, "triple") == 0: if string.strcmp(kw.arg, "triple") == 0:
@@ -702,7 +679,6 @@ def _HandleBuildCall(cl: ast.Call*) -> int:
else: else:
VLogger.error(f"viperbuild: build(...) 不支持的关键字 {kw.arg}", "viperbuild") VLogger.error(f"viperbuild: build(...) 不支持的关键字 {kw.arg}", "viperbuild")
return 1 return 1
i += 1
return 0 return 0
@@ -711,18 +687,14 @@ def _CallArgsHaveProjRef(cl: ast.Call*) -> int:
if cl is None: return 0 if cl is None: return 0
if cl.args is not None: if cl.args is not None:
n: sizet = cl.args.__len__() n: sizet = cl.args.__len__()
i: sizet = 0 for i in range(n):
while i < n:
if _IsProjRef(cl.args.get(i)) != 0: return 1 if _IsProjRef(cl.args.get(i)) != 0: return 1
i += 1
if cl.keywords is not None: if cl.keywords is not None:
n = cl.keywords.__len__() n = cl.keywords.__len__()
i = 0 for i in range(n):
while i < n:
kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i)) kw: ast.Keyword* = ast.Keyword*(cl.keywords.get(i))
if kw is not None and kw.value is not None: if kw is not None and kw.value is not None:
if _IsProjRef(kw.value) != 0: return 1 if _IsProjRef(kw.value) != 0: return 1
i += 1
return 0 return 0
@@ -803,8 +775,7 @@ def _ScanFile(pool: memhub.MemBuddy*, path: str) -> int:
rc: int = 0 rc: int = 0
if body is not None: if body is not None:
cn: sizet = len(body) cn: sizet = len(body)
ci: sizet = 0 for ci in range(cn):
while ci < cn:
child: ast.AST* = body.get(ci) child: ast.AST* = body.get(ci)
if child is not None: if child is not None:
kd: int = child.kind() kd: int = child.kind()
@@ -814,7 +785,6 @@ def _ScanFile(pool: memhub.MemBuddy*, path: str) -> int:
elif kd == ast.ASTKind.AnnAssign: rc = _HandleAnnAssign(ast.AnnAssign*(child)) elif kd == ast.ASTKind.AnnAssign: rc = _HandleAnnAssign(ast.AnnAssign*(child))
elif kd == ast.ASTKind.Expr: rc = _HandleExprStmt(ast.Expr*(child)) elif kd == ast.ASTKind.Expr: rc = _HandleExprStmt(ast.Expr*(child))
if rc != 0: break if rc != 0: break
ci += 1
pool.reset_to(mark) pool.reset_to(mark)
stdlib.free(src_buf) stdlib.free(src_buf)
@@ -883,13 +853,11 @@ def _RunBfs(pool: memhub.MemBuddy*, entry_path: str) -> int:
if rc == 1: return 1 if rc == 1: return 1
# Resolve module names collected from this file # Resolve module names collected from this file
pn: sizet = _pending.__len__() pn: sizet = _pending.__len__()
pi: sizet = 0 for pi in range(pn):
while pi < pn:
mod: str = _pending.get(pi) mod: str = _pending.get(pi)
if mod is not None: if mod is not None:
dep: str = _ResolveModuleToFile(mod) dep: str = _ResolveModuleToFile(mod)
if dep is not None: _Enqueue(dep) if dep is not None: _Enqueue(dep)
pi += 1
return 0 return 0
@@ -939,10 +907,8 @@ def _ProbeIncludes() -> str:
k: int = 0 k: int = 0
while k <= 3: while k <= 3:
base: str = _DupStd(exe_dir) base: str = _DupStd(exe_dir)
j: int = 0 for j in range(k):
while j < k:
base = _Join2(base, "..") base = _Join2(base, "..")
j += 1
cand: str = _Join2(base, "includes") cand: str = _Join2(base, "includes")
if _IsDir(cand) != 0: return cand if _IsDir(cand) != 0: return cand
k += 1 k += 1
@@ -955,12 +921,10 @@ def _DeriveOutputFromEntry(entry_path: str) -> str:
if base is None: return "app.exe" if base is None: return "app.exe"
n: sizet = string.strlen(base) n: sizet = string.strlen(base)
cut: sizet = n cut: sizet = n
i: sizet = 0 for i in range(n):
while i < n:
if base[i] == '.': if base[i] == '.':
cut = i cut = i
break break
i += 1
head: str = stdlib.malloc(cut + 5) head: str = stdlib.malloc(cut + 5)
if head is None: return "app.exe" if head is None: return "app.exe"
string.strncpy(head, base, cut) string.strncpy(head, base, cut)
@@ -1047,12 +1011,10 @@ def _SplitToolCmd(joined: str, which: int) -> None:
if joined is None: return if joined is None: return
n: sizet = string.strlen(joined) n: sizet = string.strlen(joined)
sp: sizet = n sp: sizet = n
i: sizet = 0 for i in range(n):
while i < n:
if joined[i] == ' ': if joined[i] == ' ':
sp = i sp = i
break break
i += 1
cmd: str = stdlib.malloc(sp + 1) cmd: str = stdlib.malloc(sp + 1)
if cmd is not None: if cmd is not None:
string.strncpy(cmd, joined, sp) string.strncpy(cmd, joined, sp)