refactor(includes): R12 下标 while 循环改 for range,R13 c.Set 迁移为赋值
R12(wiki/新规范 L27-39):把「i: int = 0 与 while i < N: … i += 1」形式的下标循环改写为「for i in range(N):」。保守判定:仅当条件为裸 NAME < EXPR、循环体无 continue、NAME 在体内无其它赋值、无嵌套重绑定、循环后同层不再引用 NAME 时才改写。共 269 处 / 48 文件。 R13:c.Set 是正在退化的路径——c.Set(*p, v) 期望写作 *p = v,c.Set(a, b) 等于 a = b。本次把 includes 内 45 处 c.Set 全部迁移为赋值,includes 已无 c.Set 调用。 验证:bootstrap 三重重编 SUCCESS(无 vast_c 解析回退);全量 77/77 顺序回归通过;ZlibTest 内部断言 79 passed / 0 failed。
This commit is contained in:
1 parent
3e1ed0992b
commit
27121f56a7
27 files changed
+208
-534
No files matched your search
@@ -202,8 +202,7 @@ class dict:
|
||||
"""Convert dict instance to JsonValue object (JSON_OBJECT).
|
||||
Automatically select corresponding JSON value type according to Variant tag."""
|
||||
obj: json.JsonValue* = json.object(pool)
|
||||
i: sizet = 0
|
||||
while i < self.__count__:
|
||||
for i in range(self.__count__):
|
||||
key_ptr: str* = str*(self.__keys__ + i * 8)
|
||||
vtype_ptr: int* = int*(self.__values__ + i * _VARIANT_SIZE)
|
||||
val_ptr: str* = str*(self.__values__ + i * _VARIANT_SIZE + 8)
|
||||
@@ -232,7 +231,6 @@ class dict:
|
||||
ip: int* = int*(vp)
|
||||
jv.int_val = ip[0]
|
||||
json.object_set(pool, obj, key_ptr[0], jv)
|
||||
i += 1
|
||||
return obj
|
||||
|
||||
def from_json(self, pool: memhub.MemManager*, root: json.JsonValue*):
|
||||
|
||||
+6
-18
@@ -191,46 +191,38 @@ class ArgumentParser:
|
||||
|
||||
def _find_long(self, token: str) -> int:
|
||||
"""Exact match for long option name"""
|
||||
i: int = 0
|
||||
while i < self._arg_count:
|
||||
for i in range(self._arg_count):
|
||||
arg: Argument* = self._get_arg(i)
|
||||
if string.strcmp(arg.name, token) == 0:
|
||||
return i
|
||||
i += 1
|
||||
return -1
|
||||
|
||||
def _find_long_prefix(self, token: str) -> int:
|
||||
"""Match prefix for --name=value syntax"""
|
||||
i: int = 0
|
||||
while i < self._arg_count:
|
||||
for i in range(self._arg_count):
|
||||
arg: Argument* = self._get_arg(i)
|
||||
name_len: int = string.strlen(arg.name)
|
||||
if string.strncmp(token, arg.name, name_len) == 0:
|
||||
if token[name_len] == '=':
|
||||
return i
|
||||
i += 1
|
||||
return -1
|
||||
|
||||
def _find_short(self, token: str) -> int:
|
||||
i: int = 0
|
||||
while i < self._arg_count:
|
||||
for i in range(self._arg_count):
|
||||
arg: Argument* = self._get_arg(i)
|
||||
if arg.short_name is not None:
|
||||
if string.strcmp(arg.short_name, token) == 0:
|
||||
return i
|
||||
i += 1
|
||||
return -1
|
||||
|
||||
def _find_positional(self, pos_idx: int) -> int:
|
||||
count: int = 0
|
||||
i: int = 0
|
||||
while i < self._arg_count:
|
||||
for i in range(self._arg_count):
|
||||
arg: Argument* = self._get_arg(i)
|
||||
if arg.is_positional:
|
||||
if count == pos_idx:
|
||||
return i
|
||||
count += 1
|
||||
i += 1
|
||||
return -1
|
||||
|
||||
def _store_value(self, args: ParsedArgs*,
|
||||
@@ -391,15 +383,13 @@ class ArgumentParser:
|
||||
idx += 1
|
||||
|
||||
# Validate required arguments
|
||||
i = 0
|
||||
while i < self._arg_count:
|
||||
for i in range(self._arg_count):
|
||||
arg = self._get_arg(i)
|
||||
if arg.required:
|
||||
if not args.has(arg.dest):
|
||||
stdio.printf("error: missing required argument '%s'\n", arg.name)
|
||||
release(args)
|
||||
return None
|
||||
i += 1
|
||||
|
||||
return args
|
||||
|
||||
@@ -419,8 +409,7 @@ class ArgumentParser:
|
||||
stdio.printf(" %-20s %s\n", arg.name, ht)
|
||||
i += 1
|
||||
stdio.printf("\noptional arguments:\n")
|
||||
i = 0
|
||||
while i < self._arg_count:
|
||||
for i in range(self._arg_count):
|
||||
arg = self._get_arg(i)
|
||||
if not arg.is_positional:
|
||||
ht: str = arg.help_text
|
||||
@@ -430,7 +419,6 @@ class ArgumentParser:
|
||||
stdio.printf(" %s, %-18s %s\n", arg.short_name, arg.name, ht)
|
||||
else:
|
||||
stdio.printf(" %-22s %s\n", arg.name, ht)
|
||||
i += 1
|
||||
|
||||
def print_usage(self):
|
||||
"""Print brief usage summary"""
|
||||
|
||||
+1
-3
@@ -1004,12 +1004,10 @@ def _read_operator(lx: rawptr[Lexer]):
|
||||
if cur.length <= int(remaining):
|
||||
# Compare cur.name with src[pos:pos+cur.length]
|
||||
Matched: int = 1
|
||||
i: sizet = 0
|
||||
while i < sizet(cur.length):
|
||||
for i in range(sizet(cur.length)):
|
||||
if lx.src[lx.pos + i] != cur.name[i]:
|
||||
Matched = 0
|
||||
break
|
||||
i += 1
|
||||
if Matched != 0:
|
||||
if cur.length > best_len:
|
||||
best_len = cur.length
|
||||
|
||||
+11
-33
@@ -635,10 +635,8 @@ def _ParseVirtualModified(ps: rawptr[Parser], parent: rawptr[AST]):
|
||||
return
|
||||
if ps.pending_decorators is not None:
|
||||
dn: sizet = len(ps.pending_decorators)
|
||||
di: sizet = 0
|
||||
while di < dn:
|
||||
for di in range(dn):
|
||||
merged.append(ps.pending_decorators.get(di))
|
||||
di += 1
|
||||
merged.append(marker)
|
||||
ps.pending_decorators = merged
|
||||
stmt: rawptr[AST] = None
|
||||
@@ -719,10 +717,8 @@ def _ParseInlineModified(ps: rawptr[Parser], parent: rawptr[AST]):
|
||||
return
|
||||
if ps.pending_decorators is not None:
|
||||
dn: sizet = len(ps.pending_decorators)
|
||||
di: sizet = 0
|
||||
while di < dn:
|
||||
for di in range(dn):
|
||||
merged.append(ps.pending_decorators.get(di))
|
||||
di += 1
|
||||
merged.append(marker)
|
||||
ps.pending_decorators = merged
|
||||
stmt: rawptr[AST] = _parse_funcdef(ps, 0)
|
||||
@@ -840,10 +836,8 @@ def _ParseStaticModified(ps: rawptr[Parser], parent: rawptr[AST]) -> int:
|
||||
return 1
|
||||
if ps.pending_decorators is not None:
|
||||
dn: sizet = len(ps.pending_decorators)
|
||||
di: sizet = 0
|
||||
while di < dn:
|
||||
for di in range(dn):
|
||||
merged.append(ps.pending_decorators.get(di))
|
||||
di += 1
|
||||
merged.append(marker)
|
||||
ps.pending_decorators = merged
|
||||
stmt: rawptr[AST] = _parse_funcdef(ps, 0)
|
||||
@@ -1012,12 +1006,10 @@ def _dbg_lookup_lit_val(ptr: uint64) -> double:
|
||||
_g_dbg_lit_found = 0
|
||||
if _g_dbg_pts is None or _g_dbg_vals is None:
|
||||
return 0.0
|
||||
i: sizet = 0
|
||||
while i < _g_dbg_cnt:
|
||||
for i in range(_g_dbg_cnt):
|
||||
if _g_dbg_pts[i] == ptr:
|
||||
_g_dbg_lit_found = 1
|
||||
return _g_dbg_vals[i]
|
||||
i += 1
|
||||
return 0.0
|
||||
|
||||
|
||||
@@ -1107,11 +1099,9 @@ def _fix_store_ctx(node: rawptr[AST]):
|
||||
tp_elts = ls.elts
|
||||
if tp_elts is not None:
|
||||
n: sizet = tp_elts.__len__()
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
cur: rawptr[AST] = tp_elts.get(i)
|
||||
_fix_store_ctx(cur)
|
||||
i += 1
|
||||
elif k == ASTKind.Starred:
|
||||
st2: rawptr[Starred] = (rawptr[Starred])(node)
|
||||
_fix_store_ctx(st2.value)
|
||||
@@ -2642,13 +2632,11 @@ def _parse_type_ann(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
ac: Call* = Call*(ac_node)
|
||||
if ac.args is not None:
|
||||
acn: sizet = len(ac.args)
|
||||
aci: sizet = 0
|
||||
while aci < acn:
|
||||
for aci in range(acn):
|
||||
mk: rawptr[AST] = _MakeTAttrMarker(ps, ac.args.get(aci))
|
||||
if mk is not None:
|
||||
mods.append(mk)
|
||||
mod_count += 1
|
||||
aci += 1
|
||||
continue
|
||||
mods.append(_MakeDescriptorMarker(ps))
|
||||
mod_count += 1
|
||||
@@ -2710,13 +2698,11 @@ def _parse_type_ann(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
_advance(ps)
|
||||
ptr_level += 1
|
||||
# 嵌套构造 rawptr[base](n 层)
|
||||
li_an: int = 0
|
||||
while li_an < ptr_level:
|
||||
for li_an in range(ptr_level):
|
||||
cptr_an: rawptr[AST] = Attribute(ps.pool,
|
||||
Name(ps.pool, "t", ASTCtx.Load),
|
||||
"CPtr", ASTCtx.Load)
|
||||
base = BinOp(ps.pool, base, OpKind.BitOr, cptr_an)
|
||||
li_an += 1
|
||||
# 描述符最后粘贴:与 TPC 文本展开同形(见 _PrependDescriptorMarkers)
|
||||
if mod_count > 0:
|
||||
base = _PrependDescriptorMarkers(ps, base, mods, mod_count)
|
||||
@@ -3750,8 +3736,7 @@ def _convert_enum_bare_members(ps: rawptr[Parser], node: rawptr[ClassDef]):
|
||||
# 与 AST.append(base.vp:358 `self.children = list[rawptr[AST]](...)`)逐字同形。
|
||||
node.children = list[rawptr[AST]](ps.pool, 8)
|
||||
out: rawptr[list[rawptr[AST]]] = node.children
|
||||
i: sizet = 0
|
||||
while i < cn:
|
||||
for i in range(cn):
|
||||
stmt: rawptr[AST] = children.get(i)
|
||||
handled: int = 0
|
||||
if stmt is not None and stmt.kind() == ASTKind.Expr:
|
||||
@@ -3783,7 +3768,6 @@ def _convert_enum_bare_members(ps: rawptr[Parser], node: rawptr[ClassDef]):
|
||||
handled = 1
|
||||
if handled == 0 and stmt is not None:
|
||||
out.append(stmt)
|
||||
i += 1
|
||||
|
||||
|
||||
def _parse_define_const(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
@@ -4170,10 +4154,8 @@ def _parse_structdef(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
if merged is not None:
|
||||
if dec_list is not None:
|
||||
dn_s: sizet = len(dec_list)
|
||||
di_s: sizet = 0
|
||||
while di_s < dn_s:
|
||||
for di_s in range(dn_s):
|
||||
merged.append(dec_list.get(di_s))
|
||||
di_s += 1
|
||||
merged.append(marker)
|
||||
node: rawptr[ClassDef] = ClassDef(ps.pool, name, bases, keywords, merged, type_params)
|
||||
# owner_is_class=1:与 class 同口径(类体期间 ps.in_class_body=1)
|
||||
@@ -4182,8 +4164,7 @@ def _parse_structdef(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
chk: rawptr[list[rawptr[AST]]] = node.children
|
||||
if chk is not None:
|
||||
cn_s: sizet = len(chk)
|
||||
ci_s: sizet = 0
|
||||
while ci_s < cn_s:
|
||||
for ci_s in range(cn_s):
|
||||
it_s: rawptr[AST] = chk.get(ci_s)
|
||||
if it_s is not None and it_s.kind() == ASTKind.FunctionDef:
|
||||
fd_s: rawptr[FunctionDef] = (rawptr[FunctionDef])(it_s)
|
||||
@@ -4196,7 +4177,6 @@ def _parse_structdef(ps: rawptr[Parser]) -> rawptr[AST]:
|
||||
"若确实需要方法与虚表,请把该类型写成 class。")
|
||||
ps.error_count += 1
|
||||
break
|
||||
ci_s += 1
|
||||
_set_pos(node, lineno, col, 0, 0)
|
||||
return node
|
||||
|
||||
@@ -4802,12 +4782,10 @@ def _DesugarMagicAttribute(ps: rawptr[Parser], expr: AST*) -> AST*:
|
||||
return expr
|
||||
if cl.args is not None:
|
||||
an: sizet = len(cl.args)
|
||||
ai: sizet = 0
|
||||
while ai < an:
|
||||
for ai in range(an):
|
||||
mk: AST* = _MakeTAttrMarker(ps, cl.args.get(ai))
|
||||
if mk is not None:
|
||||
new_args.append(mk)
|
||||
ai += 1
|
||||
new_call: AST* = Call(ps.pool, c_func, new_args, None)
|
||||
_set_pos(new_call, cl.lineno, cl.col_offset, 0, 0)
|
||||
return new_call
|
||||
|
||||
+3
-9
@@ -291,8 +291,7 @@ def _kw_index_put(entry: rawptr[KwEntry]):
|
||||
h: uint64 = _kw_hash_str(entry.name)
|
||||
mask: sizet = sizet(_KW_IDX_CAP - 1)
|
||||
idx: sizet = sizet(h) & mask
|
||||
i: int = 0
|
||||
while i < _KW_IDX_CAP:
|
||||
for i in range(_KW_IDX_CAP):
|
||||
slot: sizet* = (sizet*)(t.CPtr(uint64(_kw_index) + uint64(idx * 8)))
|
||||
cur_s: sizet = slot[0]
|
||||
if cur_s == 0:
|
||||
@@ -302,7 +301,6 @@ def _kw_index_put(entry: rawptr[KwEntry]):
|
||||
if string.strcmp(cur.name, entry.name) == 0:
|
||||
return
|
||||
idx = (idx + 1) & mask
|
||||
i += 1
|
||||
|
||||
|
||||
def _kw_intern(pool: rawptr[memhub.MemManager], name: str, kw_id: int):
|
||||
@@ -337,8 +335,7 @@ def _kw_lookup(name: str) -> int:
|
||||
h: uint64 = _kw_hash_str(name)
|
||||
mask: sizet = sizet(_KW_IDX_CAP - 1)
|
||||
idx: sizet = sizet(h) & mask
|
||||
i: int = 0
|
||||
while i < _KW_IDX_CAP:
|
||||
for i in range(_KW_IDX_CAP):
|
||||
slot: sizet* = (sizet*)(t.CPtr(uint64(_kw_index) + uint64(idx * 8)))
|
||||
cur_s: sizet = slot[0]
|
||||
if cur_s == 0:
|
||||
@@ -347,7 +344,6 @@ def _kw_lookup(name: str) -> int:
|
||||
if string.strcmp(cur.name, name) == 0:
|
||||
return cur.kw_id
|
||||
idx = (idx + 1) & mask
|
||||
i += 1
|
||||
return 0
|
||||
cur2: rawptr[KwEntry] = _kw_head
|
||||
while cur2 != None:
|
||||
@@ -557,10 +553,8 @@ def token_set_str(pool: rawptr[memhub.MemManager], tok: rawptr[Token],
|
||||
buf: str = pool.alloc(length + 1)
|
||||
if buf == None:
|
||||
_ast_pool_fatal("token.str_val", length + 1)
|
||||
i: sizet = 0
|
||||
while i < length:
|
||||
for i in range(length):
|
||||
buf[i] = src[start + i]
|
||||
i += 1
|
||||
buf[length] = '\0'
|
||||
tok.str_val = buf
|
||||
|
||||
|
||||
@@ -245,23 +245,19 @@ def _collect(len_arr: int*, cnt: int*,
|
||||
sorted_arr: int*, nsym: int,
|
||||
pos: int*):
|
||||
string.memset(cnt, 0, 17 * 4)
|
||||
s1: int = 0
|
||||
while s1 < nsym:
|
||||
for s1 in range(nsym):
|
||||
if len_arr[s1] != 0:
|
||||
cnt[len_arr[s1]] += 1
|
||||
s1 += 1
|
||||
run: int = 0
|
||||
l5: int = 1
|
||||
while l5 <= 15:
|
||||
pos[l5] = run
|
||||
run += cnt[l5]
|
||||
l5 += 1
|
||||
s2: int = 0
|
||||
while s2 < nsym:
|
||||
for s2 in range(nsym):
|
||||
if len_arr[s2] != 0:
|
||||
sorted_arr[pos[len_arr[s2]]] = s2
|
||||
pos[len_arr[s2]] += 1
|
||||
s2 += 1
|
||||
|
||||
|
||||
def _len_extra(code: int) -> int:
|
||||
@@ -434,8 +430,7 @@ def _gzip_decode(src: t.CPtr, src_len: sizet,
|
||||
if (slen ^ snlen) != 0xFFFF:
|
||||
err = -7
|
||||
break
|
||||
i: sizet = 0
|
||||
while i < sizet(slen):
|
||||
for i in range(sizet(slen)):
|
||||
ch: int = _byte()
|
||||
if ch < 0:
|
||||
err = -8
|
||||
@@ -445,7 +440,6 @@ def _gzip_decode(src: t.CPtr, src_len: sizet,
|
||||
break
|
||||
dout[wpos] = uchar(ch)
|
||||
wpos += 1
|
||||
i += 1
|
||||
if err != 0:
|
||||
break
|
||||
elif btype == 1:
|
||||
@@ -475,14 +469,12 @@ def _gzip_decode(src: t.CPtr, src_len: sizet,
|
||||
err = -11
|
||||
break
|
||||
string.memset(cl_len, 0, 19 * 4)
|
||||
k: int = 0
|
||||
while k < hclen:
|
||||
for k in range(hclen):
|
||||
vv: int = _bits(3)
|
||||
if vv < 0:
|
||||
err = -12
|
||||
break
|
||||
cl_len[cl_order[k]] = vv
|
||||
k += 1
|
||||
if err != 0:
|
||||
break
|
||||
_collect(cl_len, cl_cnt, cl_sorted, 19, pos_tmp)
|
||||
@@ -586,14 +578,12 @@ def _gzip_decode(src: t.CPtr, src_len: sizet,
|
||||
if dist == 0 or dist > wpos:
|
||||
err = -22
|
||||
break
|
||||
ci: sizet = 0
|
||||
while ci < length:
|
||||
for ci in range(length):
|
||||
if wpos >= dst_cap:
|
||||
err = -23
|
||||
break
|
||||
dout[wpos] = dout[wpos - dist]
|
||||
wpos += 1
|
||||
ci += 1
|
||||
if err != 0:
|
||||
break
|
||||
|
||||
|
||||
+2
-6
@@ -104,8 +104,7 @@ class HashTable:
|
||||
mask: sizet = self.__capacity__ - 1
|
||||
idx: sizet = sizet(h) & mask
|
||||
first_tombstone: sizet = self.__capacity__
|
||||
i: sizet = 0
|
||||
while i < self.__capacity__:
|
||||
for i in range(self.__capacity__):
|
||||
sh: uint64 = self._slot_hash(idx)
|
||||
if sh == _HT_EMPTY:
|
||||
if first_tombstone < self.__capacity__:
|
||||
@@ -120,7 +119,6 @@ class HashTable:
|
||||
if string.strcmp(sk, key) == 0:
|
||||
return idx
|
||||
idx = (idx + 1) & mask
|
||||
i += 1
|
||||
if first_tombstone < self.__capacity__:
|
||||
return first_tombstone
|
||||
return self.__capacity__
|
||||
@@ -137,8 +135,7 @@ class HashTable:
|
||||
self.__capacity__ = new_cap
|
||||
self.__count__ = 0
|
||||
self.__tombstones__ = 0
|
||||
i: sizet = 0
|
||||
while i < old_cap:
|
||||
for i in range(old_cap):
|
||||
old_h_ptr: uint64* = t.CPtr(uint64(old_slots) + i * _HT_SLOT_SIZE)
|
||||
h: uint64 = old_h_ptr[0]
|
||||
if h != _HT_EMPTY and h != _HT_TOMBSTONE:
|
||||
@@ -150,7 +147,6 @@ class HashTable:
|
||||
idx: sizet = self._find_slot(k, h)
|
||||
self._set_slot(idx, h, k, v)
|
||||
self.__count__ += 1
|
||||
i += 1
|
||||
|
||||
def __setitem__(self, key: str, val: t.CNeedPtr):
|
||||
"""Insert or update key-value pair. val automatically decays to pointer (t.CNeedPtr: no conversion if already pointer)."""
|
||||
|
||||
+1
-3
@@ -145,10 +145,8 @@ def _parse_number(s: rawptr[ParseState]) -> rawptr[JsonValue]:
|
||||
if buf == None:
|
||||
return null(s.pool)
|
||||
|
||||
i: sizet = 0
|
||||
while i < num_len:
|
||||
for i in range(num_len):
|
||||
buf[i] = s.src[start + i]
|
||||
i += 1
|
||||
buf[num_len] = '\0'
|
||||
|
||||
if is_float:
|
||||
|
||||
@@ -503,22 +503,18 @@ class MemSlab(MemManager):
|
||||
self.block_size = bs
|
||||
|
||||
# Clear bitmap
|
||||
idx: sizet = 0
|
||||
while idx < map_bytes:
|
||||
for idx in range(map_bytes):
|
||||
self.alloc_map[idx] = 0
|
||||
idx += 1
|
||||
|
||||
self.block_count = self.usable_size / bs
|
||||
if self.block_count == 0: return
|
||||
|
||||
# Construct free list: the first 8 bytes of each block store pointer to next block
|
||||
self.free_list = None
|
||||
i: sizet = 0
|
||||
while i < self.block_count:
|
||||
for i in range(self.block_count):
|
||||
block: rawptr = self.usable + i * bs
|
||||
*((uint64*)(block)) = uint64(self.free_list)
|
||||
self.free_list = block
|
||||
i += 1
|
||||
|
||||
def alloc(self, size: sizet) -> rawptr:
|
||||
# Slab mode: allocate one block only if requested size <= block_size
|
||||
@@ -561,14 +557,12 @@ class MemSlab(MemManager):
|
||||
def reset(self) -> int:
|
||||
self.used_count = 0
|
||||
self.free_list = None
|
||||
i: sizet = 0
|
||||
while i < self.block_count:
|
||||
for i in range(self.block_count):
|
||||
block: rawptr = self.usable + i * self.block_size
|
||||
*((uint64*)(block)) = uint64(self.free_list)
|
||||
self.free_list = block
|
||||
if i / 8 < self.alloc_map_size:
|
||||
self.alloc_map[i / 8] = 0
|
||||
i += 1
|
||||
return 1
|
||||
|
||||
|
||||
@@ -1010,17 +1004,13 @@ class MemBuddy(MemManager):
|
||||
# Payload tail 16B (16 bytes before the canary).
|
||||
tail_addr: uint64 = uint64(block) + big - MEMBUDDY_CANARY - 16
|
||||
stdio.printf("[FREEFRAME] 写入者 payload 头16B(=%llu): ", head_addr)
|
||||
bi_h: int = 0
|
||||
while bi_h < 16:
|
||||
for bi_h in range(16):
|
||||
bv_h: uint8 = *((uint8*)(head_addr + uint64(bi_h)))
|
||||
stdio.printf("%02X ", uint32(bv_h))
|
||||
bi_h += 1
|
||||
stdio.printf("| 尾16B(=%llu): ", tail_addr)
|
||||
bi_t: int = 0
|
||||
while bi_t < 16:
|
||||
for bi_t in range(16):
|
||||
bv_t: uint8 = *((uint8*)(tail_addr + uint64(bi_t)))
|
||||
stdio.printf("%02X ", uint32(bv_t))
|
||||
bi_t += 1
|
||||
stdio.printf("\n")
|
||||
if self._det_records is not None:
|
||||
usr_d: uint64 = uint64(block) + MEMBUDDY_HEADER_SIZE
|
||||
@@ -1087,8 +1077,7 @@ class MemBuddy(MemManager):
|
||||
hit_v: sizet = 0
|
||||
in_pool: sizet = 0
|
||||
out_pool: sizet = 0
|
||||
i: sizet = 0
|
||||
while i < nw:
|
||||
for i in range(nw):
|
||||
wv: uint64 = self._ff_word(rawptr(l_addr), int(i) + 1)
|
||||
if wv == lcan:
|
||||
hit_v += 1
|
||||
@@ -1097,7 +1086,6 @@ class MemBuddy(MemManager):
|
||||
in_pool += 1
|
||||
else:
|
||||
out_pool += 1
|
||||
i += 1
|
||||
can_eq_w0: int = 0
|
||||
if lcan == w0:
|
||||
can_eq_w0 = 1
|
||||
@@ -1180,11 +1168,9 @@ class MemBuddy(MemManager):
|
||||
if uint64(block) + bs + 16 <= uint64(self.usable) + self.usable_size:
|
||||
dump_n = 24
|
||||
stdio.printf("[FREEFRAME] canary 起 %d 字节: ", dump_n)
|
||||
bi: int = 0
|
||||
while bi < dump_n:
|
||||
for bi in range(dump_n):
|
||||
bv: uint8 = *((uint8*)(can_addr + uint64(bi)))
|
||||
stdio.printf("%02X ", uint32(bv))
|
||||
bi += 1
|
||||
stdio.printf("\n")
|
||||
# [FREEFRAME] Writer payload head/tail + requested size (same scene as the canary dump:
|
||||
# a broken canary means this block's owner overflowed into the right free block's first word).
|
||||
@@ -1399,12 +1385,10 @@ class MemBuddy(MemManager):
|
||||
# are no longer recorded, so the check is skipped to avoid rejecting valid frees.
|
||||
if self.chk_stack is not None and self.chk_depth < self.chk_cap:
|
||||
alive: int = 0
|
||||
ci: sizet = 0
|
||||
while ci < self.chk_depth:
|
||||
for ci in range(self.chk_depth):
|
||||
if self.chk_stack[ci] == uint64(block):
|
||||
alive = 1
|
||||
break
|
||||
ci += 1
|
||||
if alive == 0:
|
||||
return 0
|
||||
return 1
|
||||
@@ -1510,8 +1494,7 @@ class MemBuddy(MemManager):
|
||||
# Overlap check: the new block's address must not already be an active
|
||||
# record (same block allocated twice = free list corruption).
|
||||
ff_d: uint64 = uint64(1) << 63
|
||||
dup_i: sizet = 0
|
||||
while dup_i < self._det_count:
|
||||
for dup_i in range(self._det_count):
|
||||
drp: uint64 = self._det_records[dup_i * 2]
|
||||
drs: uint64 = self._det_records[dup_i * 2 + 1]
|
||||
if drp == rec_ptr_d and (drs & ff_d) == 0:
|
||||
@@ -1519,7 +1502,6 @@ class MemBuddy(MemManager):
|
||||
uint64(size), dup_i, drs & (ff_d - 1), rec_ptr_d)
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
dup_i += 1
|
||||
if _memdbg_enable != 0:
|
||||
# [MEMDBG] A freshly popped block must not still be on its own free
|
||||
# list (a duplicate put would leave a residual node -> reallocated).
|
||||
@@ -1677,8 +1659,7 @@ class MemBuddy(MemManager):
|
||||
# Read this record's real size (detection fills 0xCD after free, so a later
|
||||
# write-through breaks the fill = use-after-free). Keep the record and set the
|
||||
# free bit; the probe checks the 0xCD fill of still-free blocks.
|
||||
ri: sizet = 0
|
||||
while ri < self._det_count:
|
||||
for ri in range(self._det_count):
|
||||
rp: uint64 = self._det_records[ri * 2]
|
||||
rs: uint64 = self._det_records[ri * 2 + 1]
|
||||
if rp == uint64(ptr) and (rs & (uint64(1) << 63)) == 0:
|
||||
@@ -1686,7 +1667,6 @@ class MemBuddy(MemManager):
|
||||
string.memset(ptr, MEMBUDDY_FILL_PATTERN, rs)
|
||||
self._det_records[ri * 2 + 1] = rs | (uint64(1) << 63)
|
||||
break
|
||||
ri += 1
|
||||
if self._is_valid_ptr(p_eff) != 0:
|
||||
block: rawptr = p_eff - MEMBUDDY_HEADER_SIZE
|
||||
stored: rawptr = rawptr(*((uint64*)(block)))
|
||||
@@ -1878,13 +1858,11 @@ class MemBuddy(MemManager):
|
||||
return 1
|
||||
target: uint64 = uint64(ptr)
|
||||
free_flag: uint64 = uint64(1) << 63
|
||||
i: sizet = 0
|
||||
while i < self._det_count:
|
||||
for i in range(self._det_count):
|
||||
rp: uint64 = self._det_records[i * 2]
|
||||
rs: uint64 = self._det_records[i * 2 + 1]
|
||||
if rp == target and (rs & free_flag) == 0:
|
||||
return 1
|
||||
i += 1
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -1925,19 +1903,15 @@ class MemBuddy(MemManager):
|
||||
if mv != uint16(MEMBUDDY_DET_MARKER):
|
||||
stdio.printf("[DET] 越界写: ptr=%llu size=%llu 后标记=0x%04X(期望 0xCDCD)块内容前16B: ",
|
||||
p, s, uint32(mv))
|
||||
bi3: int = 0
|
||||
while bi3 < 16:
|
||||
for bi3 in range(16):
|
||||
bv3: uint8 = *((uint8*)(p + uint64(bi3)))
|
||||
stdio.printf("%02X ", uint32(bv3))
|
||||
bi3 += 1
|
||||
# Overflow region (24 bytes from ptr+size): 0x00 = written through, 0xCD = not
|
||||
# written, other = written value; shows how far/direction the writer went.
|
||||
stdio.printf("越界区: ")
|
||||
bj3: int = 0
|
||||
while bj3 < 24:
|
||||
for bj3 in range(24):
|
||||
bvj: uint8 = *((uint8*)(p + s + uint64(bj3)))
|
||||
stdio.printf("%02X ", uint32(bvj))
|
||||
bj3 += 1
|
||||
# Record-table context: the 3 records before/after, to infer the phase.
|
||||
stdio.printf("\n记录上下文: ")
|
||||
ci2: int = -3
|
||||
@@ -1951,13 +1925,11 @@ class MemBuddy(MemManager):
|
||||
# Overlap check: a ptr with several records means alloc handed the same block to
|
||||
# different size requests (they overwrite each other).
|
||||
stdio.printf("\n同ptr记录: ")
|
||||
ci3: sizet = 0
|
||||
while ci3 < self._det_count:
|
||||
for ci3 in range(self._det_count):
|
||||
cp3: uint64 = self._det_records[ci3 * 2]
|
||||
cs3: uint64 = self._det_records[ci3 * 2 + 1]
|
||||
if cp3 == p and (cs3 & free_flag) == 0:
|
||||
stdio.printf("[%zu]sz=%llu ", ci3, cs3 & (free_flag - 1))
|
||||
ci3 += 1
|
||||
stdio.printf("\n")
|
||||
stdio.fflush(None)
|
||||
stdlib.exit(1)
|
||||
@@ -2135,14 +2107,12 @@ class MemBuddy(MemManager):
|
||||
win_live, win_bytes_a)
|
||||
stdio.printf("[MEM] 存活块 order 分布(记录在案共 %zu 块;单块=%llu<<order 字节):\n",
|
||||
live, uint64(MEMBUDDY_MIN_BLOCK))
|
||||
oi: int = 0
|
||||
while oi <= max_o:
|
||||
for oi in range(max_o + 1):
|
||||
cnt: uint64 = counts[oi]
|
||||
if cnt != 0:
|
||||
blk: uint64 = uint64(MEMBUDDY_MIN_BLOCK) << oi
|
||||
stdio.printf("[MEM] order=%d 块=%llu 单块=%llu 合计=%llu\n",
|
||||
oi, cnt, blk, cnt * blk)
|
||||
oi += 1
|
||||
if bad != 0:
|
||||
stdio.printf("[MEM] 记录项异常(NULL/越界/块头 order 非法)共 %zu 条;"
|
||||
"抽样 4 条(addr / 块头):\n", bad)
|
||||
|
||||
+6
-18
@@ -780,11 +780,9 @@ def _peep_replace_token(pool: memhub.MemBuddy*,
|
||||
if (cc2 >= 48 and cc2 <= 57) or (cc2 >= 65 and cc2 <= 90) or (cc2 >= 97 and cc2 <= 122) or cc2 == 95:
|
||||
nxt2 = 1
|
||||
if nxt2 == 0:
|
||||
j: sizet = 0
|
||||
while j < rlen:
|
||||
for j in range(rlen):
|
||||
out[oq] = repl[j]
|
||||
oq += 1
|
||||
j += 1
|
||||
i += 1 + tlen
|
||||
continue
|
||||
out[oq] = line_buf[i]
|
||||
@@ -1018,8 +1016,7 @@ def _peephole_opt(func: rawptr[Function], pool: memhub.MemBuddy*):
|
||||
# 第二遍:替换 load 名引用
|
||||
# safe_val 在本槽替换阶段不变,strlen 只求一次(原每行各求一次)
|
||||
safe_len: sizet = string.strlen(safe_val)
|
||||
li2: int = 0
|
||||
while li2 < load_cnt:
|
||||
for li2 in range(load_cnt):
|
||||
slotsp: str* = (str*)(uint64(load_ltoks) + li2 * 8)
|
||||
ltok: str = slotsp[0]
|
||||
if ltok is not None:
|
||||
@@ -1039,7 +1036,6 @@ def _peephole_opt(func: rawptr[Function], pool: memhub.MemBuddy*):
|
||||
lr.Buf = nb2
|
||||
lr = lr.Next
|
||||
blk_r = blk_r.Next
|
||||
li2 += 1
|
||||
# 删除:alloca def / 唯一 store / 全部 load 行
|
||||
blk_d = blk
|
||||
while blk_d is not None:
|
||||
@@ -1286,13 +1282,11 @@ def _MlirAliasLookup(name: str) -> str:
|
||||
"""查别名表,未命中返回 None"""
|
||||
if name is None:
|
||||
return None
|
||||
i: int = 0
|
||||
while i < _MLIR_AliasCount:
|
||||
for i in range(_MLIR_AliasCount):
|
||||
sp: str* = _mlir_slotp(_MLIR_AliasFrom, i)
|
||||
if sp[0] is not None and string.strcmp(sp[0], name) == 0:
|
||||
st: str* = _mlir_slotp(_MLIR_AliasTo, i)
|
||||
return st[0]
|
||||
i += 1
|
||||
return None
|
||||
|
||||
|
||||
@@ -1315,28 +1309,24 @@ def _MlirResolve(name: str) -> str:
|
||||
if name is None:
|
||||
return None
|
||||
cur: str = name
|
||||
g: int = 0
|
||||
while g < 64:
|
||||
for g in range(64):
|
||||
nx: str = _MlirAliasLookup(cur)
|
||||
if nx is None:
|
||||
return cur
|
||||
cur = nx
|
||||
g += 1
|
||||
return cur
|
||||
|
||||
|
||||
def _MlirConstGet(tytext: str, valtext: str) -> str:
|
||||
"""取(或新建)常量的物化名 %cN"""
|
||||
global _MLIR_ConstCount
|
||||
i: int = 0
|
||||
while i < _MLIR_ConstCount:
|
||||
for i in range(_MLIR_ConstCount):
|
||||
sp: str* = _mlir_slotp(_MLIR_ConstTy, i)
|
||||
if sp[0] is not None and string.strcmp(sp[0], tytext) == 0:
|
||||
sv: str* = _mlir_slotp(_MLIR_ConstVal, i)
|
||||
if sv[0] is not None and string.strcmp(sv[0], valtext) == 0:
|
||||
sn: str* = _mlir_slotp(_MLIR_ConstName, i)
|
||||
return sn[0]
|
||||
i += 1
|
||||
if _MLIR_Pass == 2:
|
||||
# pass1 已遍历全部指令行,此处不应出现新常量
|
||||
MlirFail("MLIR 渲染: 发射阶段出现未物化常量(扫描遗漏)")
|
||||
@@ -1451,13 +1441,11 @@ def _MlirEmitOneConst(out: str, outsz: sizet, mt: str, val: str, nm: str):
|
||||
|
||||
def _MlirEmitConsts(out: str, outsz: sizet):
|
||||
"""按登记顺序在 entry 块开头发射全部常量物化 op"""
|
||||
i: int = 0
|
||||
while i < _MLIR_ConstCount:
|
||||
for i in range(_MLIR_ConstCount):
|
||||
st: str* = _mlir_slotp(_MLIR_ConstTy, i)
|
||||
sv: str* = _mlir_slotp(_MLIR_ConstVal, i)
|
||||
sn: str* = _mlir_slotp(_MLIR_ConstName, i)
|
||||
_MlirEmitOneConst(out, outsz, st[0], sv[0], sn[0])
|
||||
i += 1
|
||||
|
||||
|
||||
# ============================================================
|
||||
|
||||
@@ -285,8 +285,7 @@ def create_global_string(pool: memhub.MemBuddy*, mod: rawptr[LLVMModule],
|
||||
pos += 1
|
||||
init_buf[pos] = '"'
|
||||
pos += 1
|
||||
i: sizet = 0
|
||||
while i < slen:
|
||||
for i in range(slen):
|
||||
ch: uint8 = text[i]
|
||||
if ch == 0x22 or ch == 0x5C or ch < 0x20 or ch >= 0x7F:
|
||||
# 需要转义: " → \22, \ → \5c, 非打印字符 → \xx
|
||||
@@ -307,7 +306,6 @@ def create_global_string(pool: memhub.MemBuddy*, mod: rawptr[LLVMModule],
|
||||
else:
|
||||
init_buf[pos] = ch
|
||||
pos += 1
|
||||
i += 1
|
||||
# 末尾 NUL 字节
|
||||
init_buf[pos] = '\\'
|
||||
pos += 1
|
||||
|
||||
@@ -1662,10 +1662,8 @@ def _MlirAppendIndented(dst: str, dst_size: sizet, src: str,
|
||||
return
|
||||
p: str = src
|
||||
while p[0] != '\0':
|
||||
i: int = 0
|
||||
while i < indent:
|
||||
for i in range(indent):
|
||||
_append_cstr(dst, dst_size, " ")
|
||||
i += 1
|
||||
while p[0] != '\0' and p[0] != '\n':
|
||||
cb[0] = p[0]
|
||||
cb[1] = '\0'
|
||||
|
||||
+2
-6
@@ -517,8 +517,7 @@ def MlirNamedTypeRegister(ty: rawptr[LLVMType], is_packed: int):
|
||||
if name is None:
|
||||
return
|
||||
fcount: int = get_struct_fcount(ty)
|
||||
i: int = 0
|
||||
while i < _MlirNamedCount:
|
||||
for i in range(_MlirNamedCount):
|
||||
slot: sizet* = _MlirNamedSlot(i)
|
||||
ex: rawptr[LLVMType] = (rawptr[LLVMType])(slot[0])
|
||||
ex_name: str = get_struct_name(ex)
|
||||
@@ -528,7 +527,6 @@ def MlirNamedTypeRegister(ty: rawptr[LLVMType], is_packed: int):
|
||||
slot[0] = sizet(ty)
|
||||
slot[1] = sizet(is_packed)
|
||||
return
|
||||
i += 1
|
||||
if _MlirNamedCount >= int(_MlirNamedCap):
|
||||
return
|
||||
slot2: sizet* = _MlirNamedSlot(_MlirNamedCount)
|
||||
@@ -541,14 +539,12 @@ def _MlirNamedFindSlot(name: str) -> int:
|
||||
"""按名字回查已登记槽位下标(未登记 / 表未发布 ⇒ -1)"""
|
||||
if name is None or _MlirNamedTys is None:
|
||||
return -1
|
||||
i: int = 0
|
||||
while i < _MlirNamedCount:
|
||||
for i in range(_MlirNamedCount):
|
||||
slot: sizet* = _MlirNamedSlot(i)
|
||||
ty: rawptr[LLVMType] = (rawptr[LLVMType])(slot[0])
|
||||
nm: str = get_struct_name(ty)
|
||||
if nm is not None and string.strcmp(nm, name) == 0:
|
||||
return i
|
||||
i += 1
|
||||
return -1
|
||||
|
||||
|
||||
|
||||
@@ -198,10 +198,8 @@ def _extract_def_name(pool: memhub.MemBuddy*,
|
||||
name_len: int = i
|
||||
name: str = pool.alloc(name_len + 1)
|
||||
if name is None: return None
|
||||
j: int = 0
|
||||
while j < name_len:
|
||||
for j in range(name_len):
|
||||
name[j] = text[j]
|
||||
j += 1
|
||||
name[name_len] = '\0'
|
||||
return name
|
||||
i += 1
|
||||
@@ -286,10 +284,8 @@ def _str_matches_at(text: str, start: int, length: int,
|
||||
# 检查 target 长度
|
||||
target_len: sizet = string.strlen(target)
|
||||
if target_len != length: return 0
|
||||
i: sizet = 0
|
||||
while i < length:
|
||||
for i in range(length):
|
||||
if text[start + i] != target[i]: return 0
|
||||
i += 1
|
||||
return 1
|
||||
|
||||
|
||||
@@ -336,10 +332,8 @@ def verify_function(pool: memhub.MemBuddy*,
|
||||
if blk_ref is not None:
|
||||
# 构造 "%<name>" 字符串
|
||||
blk_ref[0] = '%'
|
||||
k: sizet = 0
|
||||
while k < blk_name_len:
|
||||
for k in range(blk_name_len):
|
||||
blk_ref[k + 1] = blk_iter.Name[k]
|
||||
k += 1
|
||||
blk_ref[blk_name_len + 1] = '\0'
|
||||
_name_table_add(name_table, pool, blk_ref)
|
||||
blk_iter = blk_iter.Next
|
||||
|
||||
+68
-204
@@ -50,73 +50,59 @@ class ndarray[T]:
|
||||
def __add__(self, other: ndarray[T]*) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
result.data[i] = self.data[i] + other.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __sub__(self, other: ndarray[T]*) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
result.data[i] = self.data[i] - other.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __mul__(self, other: ndarray[T]*) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
result.data[i] = self.data[i] * other.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __truediv__(self, other: ndarray[T]*) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
if other.data[i] != T(0):
|
||||
result.data[i] = self.data[i] / other.data[i]
|
||||
else:
|
||||
result.data[i] = T(0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __floordiv__(self, other: ndarray[T]*) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
if other.data[i] != T(0):
|
||||
result.data[i] = math.floor(self.data[i] / other.data[i])
|
||||
else:
|
||||
result.data[i] = T(0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __mod__(self, other: ndarray[T]*) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
if other.data[i] != T(0):
|
||||
result.data[i] = math.fmod(self.data[i], other.data[i])
|
||||
else:
|
||||
result.data[i] = T(0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __neg__(self) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
result.data[i] = -self.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def __len__(self) -> int:
|
||||
@@ -136,10 +122,8 @@ class ndarray[T]:
|
||||
self.pool.free(self)
|
||||
|
||||
def fill(self, val: T):
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
self.data[i] = val
|
||||
i += 1
|
||||
|
||||
def copy(self) -> ndarray[T]*:
|
||||
result: ndarray[T]* = _empty_like(self)
|
||||
@@ -167,10 +151,8 @@ class ndarray[T]:
|
||||
|
||||
def sum(self) -> T:
|
||||
s: T = T(0)
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
s += self.data[i]
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def mean(self) -> T:
|
||||
@@ -222,10 +204,8 @@ class ndarray[T]:
|
||||
def dot(self, other: ndarray[T]*) -> T:
|
||||
s: T = T(0)
|
||||
n: sizet = self.size if (self.size < other.size) else other.size
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
s += self.data[i] * other.data[i]
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def T(self) -> ndarray[T]*:
|
||||
@@ -238,30 +218,25 @@ class ndarray[T]:
|
||||
result.shape[0] = cols
|
||||
result.shape[1] = rows
|
||||
_compute_strides(result)
|
||||
i: sizet = 0
|
||||
while i < rows:
|
||||
for i in range(rows):
|
||||
j: sizet = 0
|
||||
while j < cols:
|
||||
result.data[j * rows + i] = self.data[i * cols + j]
|
||||
j += 1
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def print_arr(self):
|
||||
if self.ndim == 1:
|
||||
stdio.printf("[")
|
||||
i: sizet = 0
|
||||
while i < self.size:
|
||||
for i in range(self.size):
|
||||
if i > 0: stdio.printf(", ")
|
||||
stdio.printf("%.4f", self.data[i])
|
||||
i += 1
|
||||
stdio.printf("]\n")
|
||||
elif self.ndim == 2:
|
||||
rows: sizet = self.shape[0]
|
||||
cols: sizet = self.shape[1]
|
||||
stdio.printf("[")
|
||||
i: sizet = 0
|
||||
while i < rows:
|
||||
for i in range(rows):
|
||||
if i > 0: stdio.printf(" ")
|
||||
stdio.printf("[")
|
||||
j: sizet = 0
|
||||
@@ -273,7 +248,6 @@ class ndarray[T]:
|
||||
stdio.printf("]\n")
|
||||
else:
|
||||
stdio.printf("]]\n")
|
||||
i += 1
|
||||
|
||||
|
||||
# ============================================================
|
||||
@@ -402,10 +376,8 @@ def linspace(pool: rawptr[memhub.MemManager], start: double, stop: double, num:
|
||||
a.data[0] = start
|
||||
return a
|
||||
step: double = (stop - start) / double(num - 1)
|
||||
i: sizet = 0
|
||||
while i < num:
|
||||
for i in range(num):
|
||||
a.data[i] = start + double(i) * step
|
||||
i += 1
|
||||
return a
|
||||
|
||||
def empty2d(pool: rawptr[memhub.MemManager], rows: sizet, cols: sizet) -> ndarray[double]*:
|
||||
@@ -438,20 +410,16 @@ def ones2d(pool: rawptr[memhub.MemManager], rows: sizet, cols: sizet) -> ndarray
|
||||
def eye(pool: rawptr[memhub.MemManager], n: sizet) -> ndarray[double]*:
|
||||
a: ndarray[double]* = empty2d(pool, n, n)
|
||||
if not a: return None
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
a.data[i * n + i] = double(1.0)
|
||||
i += 1
|
||||
return a
|
||||
|
||||
def diag(pool: rawptr[memhub.MemManager], vals: ndarray[double]*) -> ndarray[double]*:
|
||||
n: sizet = vals.size
|
||||
a: ndarray[double]* = empty2d(pool, n, n)
|
||||
if not a: return None
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
a.data[i * n + i] = vals.data[i]
|
||||
i += 1
|
||||
return a
|
||||
|
||||
|
||||
@@ -461,74 +429,58 @@ def diag(pool: rawptr[memhub.MemManager], vals: ndarray[double]*) -> ndarray[dou
|
||||
def np_abs(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
v: double = a.data[i]
|
||||
result.data[i] = v if v >= double(0.0) else -v
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_sqrt(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.sqrt(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_exp(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.exp(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_log(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.log(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_sin(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.sin(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_cos(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.cos(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_tan(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.tan(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_pow(a: ndarray[double]*, p: double) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.pow(a.data[i], p)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -538,40 +490,32 @@ def np_pow(a: ndarray[double]*, p: double) -> ndarray[double]*:
|
||||
def add_scalar(a: ndarray[double]*, s: double) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = a.data[i] + s
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def mul_scalar(a: ndarray[double]*, s: double) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = a.data[i] * s
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def sub_scalar(a: ndarray[double]*, s: double) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = a.data[i] - s
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def div_scalar(a: ndarray[double]*, s: double) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
if s != double(0.0):
|
||||
result.data[i] = a.data[i] / s
|
||||
else:
|
||||
result.data[i] = double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -588,8 +532,7 @@ def matmul(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
if k != k2: return None
|
||||
c: ndarray[double]* = empty2d(a.pool, m, n)
|
||||
if not c: return None
|
||||
i: sizet = 0
|
||||
while i < m:
|
||||
for i in range(m):
|
||||
j: sizet = 0
|
||||
while j < n:
|
||||
s: double = double(0.0)
|
||||
@@ -599,7 +542,6 @@ def matmul(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
p += 1
|
||||
c.data[i * n + j] = s
|
||||
j += 1
|
||||
i += 1
|
||||
return c
|
||||
|
||||
def dot_product(a: ndarray[double]*, b: ndarray[double]*) -> double:
|
||||
@@ -635,11 +577,9 @@ def var(a: ndarray[double]*) -> double:
|
||||
if a.size == 0: return double(0.0)
|
||||
m: double = a.mean()
|
||||
s: double = double(0.0)
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
d: double = a.data[i] - m
|
||||
s += d * d
|
||||
i += 1
|
||||
return s / double(a.size)
|
||||
|
||||
def std(a: ndarray[double]*) -> double:
|
||||
@@ -651,13 +591,11 @@ def norm(a: ndarray[double]*) -> double:
|
||||
def clip(a: ndarray[double]*, lo: double, hi: double) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
v: double = a.data[i]
|
||||
if v < lo: v = lo
|
||||
if v > hi: v = hi
|
||||
result.data[i] = v
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def concatenate(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
@@ -692,10 +630,8 @@ def sort_arr(a: ndarray[double]*) -> ndarray[double]*:
|
||||
def reverse(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = a.data[a.size - 1 - i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -705,177 +641,139 @@ def reverse(a: ndarray[double]*) -> ndarray[double]*:
|
||||
def np_log10(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.log10(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_log2(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.log2(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_floor(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.floor(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_ceil(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.ceil(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_round(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.round(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_sign(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
if a.data[i] > double(0.0):
|
||||
result.data[i] = double(1.0)
|
||||
elif a.data[i] < double(0.0):
|
||||
result.data[i] = double(-1.0)
|
||||
else:
|
||||
result.data[i] = double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_tanh(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.tanh(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_sinh(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.sinh(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_cosh(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.cosh(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_arcsin(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.asin(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_arccos(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.acos(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_arctan(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.atan(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_arctan2(y: ndarray[double]*, x: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(y)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < y.size:
|
||||
for i in range(y.size):
|
||||
result.data[i] = math.atan2(y.data[i], x.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_degrees(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.degrees(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_radians(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = math.radians(a.data[i])
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_isnan(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(math.isnan(a.data[i]))
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_isinf(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(math.isinf(a.data[i]))
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_maximum(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = a.data[i] if a.data[i] > b.data[i] else b.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_minimum(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = a.data[i] if a.data[i] < b.data[i] else b.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -886,21 +784,17 @@ def cumsum(a: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
s: double = double(0.0)
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
s += a.data[i]
|
||||
result.data[i] = s
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def diff(a: ndarray[double]*) -> ndarray[double]*:
|
||||
if a.size < 2: return None
|
||||
result: ndarray[double]* = zeros(a.pool, a.size - 1)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size - 1:
|
||||
for i in range(a.size - 1):
|
||||
result.data[i] = a.data[i + 1] - a.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def flatten(a: ndarray[double]*) -> ndarray[double]*:
|
||||
@@ -916,113 +810,89 @@ def trace(a: ndarray[double]*) -> double:
|
||||
if a.ndim != 2: return double(0.0)
|
||||
n: sizet = a.shape[0] if a.shape[0] < a.shape[1] else a.shape[1]
|
||||
s: double = double(0.0)
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
s += a.data[i * a.shape[1] + i]
|
||||
i += 1
|
||||
return s
|
||||
|
||||
def outer(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = empty2d(a.pool, a.size, b.size)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
j: sizet = 0
|
||||
while j < b.size:
|
||||
result.data[i * b.size + j] = a.data[i] * b.data[j]
|
||||
j += 1
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_where(condition: ndarray[double]*, x: ndarray[double]*, y: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(x)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < x.size:
|
||||
for i in range(x.size):
|
||||
if condition.data[i] != double(0.0):
|
||||
result.data[i] = x.data[i]
|
||||
else:
|
||||
result.data[i] = y.data[i]
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_count_nonzero(a: ndarray[double]*) -> int:
|
||||
count: int = 0
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
if a.data[i] != double(0.0):
|
||||
count += 1
|
||||
i += 1
|
||||
return count
|
||||
|
||||
def np_all(a: ndarray[double]*) -> int:
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
if a.data[i] == double(0.0):
|
||||
return 0
|
||||
i += 1
|
||||
return 1
|
||||
|
||||
def np_any(a: ndarray[double]*) -> int:
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
if a.data[i] != double(0.0):
|
||||
return 1
|
||||
i += 1
|
||||
return 0
|
||||
|
||||
def np_equal(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(1.0) if a.data[i] == b.data[i] else double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_not_equal(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(1.0) if a.data[i] != b.data[i] else double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_less(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(1.0) if a.data[i] < b.data[i] else double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_greater(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(1.0) if a.data[i] > b.data[i] else double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_less_equal(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(1.0) if a.data[i] <= b.data[i] else double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
def np_greater_equal(a: ndarray[double]*, b: ndarray[double]*) -> ndarray[double]*:
|
||||
result: ndarray[double]* = _empty_like(a)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
result.data[i] = double(1.0) if a.data[i] >= b.data[i] else double(0.0)
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -1073,13 +943,11 @@ def meshgrid(x: ndarray[double]*, y: ndarray[double]*) -> ndarray[double]*:
|
||||
# Returns X grid as 2D array (each row is x)
|
||||
result: ndarray[double]* = empty2d(x.pool, y.size, x.size)
|
||||
if not result: return None
|
||||
i: sizet = 0
|
||||
while i < y.size:
|
||||
for i in range(y.size):
|
||||
j: sizet = 0
|
||||
while j < x.size:
|
||||
result.data[i * x.size + j] = x.data[j]
|
||||
j += 1
|
||||
i += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -1118,20 +986,16 @@ def np_interp(x: double, xp: ndarray[double]*, fp: ndarray[double]*) -> double:
|
||||
if xp.size == 0: return double(0.0)
|
||||
if x <= xp.data[0]: return fp.data[0]
|
||||
if x >= xp.data[xp.size - 1]: return fp.data[xp.size - 1]
|
||||
i: sizet = 0
|
||||
while i < xp.size - 1:
|
||||
for i in range(xp.size - 1):
|
||||
if x >= xp.data[i] and x <= xp.data[i + 1]:
|
||||
t_val: double = (x - xp.data[i]) / (xp.data[i + 1] - xp.data[i])
|
||||
return fp.data[i] + t_val * (fp.data[i + 1] - fp.data[i])
|
||||
i += 1
|
||||
return fp.data[xp.size - 1]
|
||||
|
||||
def prod(a: ndarray[double]*) -> double:
|
||||
p: double = double(1.0)
|
||||
i: sizet = 0
|
||||
while i < a.size:
|
||||
for i in range(a.size):
|
||||
p *= a.data[i]
|
||||
i += 1
|
||||
return p
|
||||
|
||||
def median(a: ndarray[double]*) -> double:
|
||||
|
||||
+8
-14
@@ -310,10 +310,8 @@ def decode_chunked(src: str, src_len: INT, dst: str, dst_cap: INT) -> INT:
|
||||
if size == 0: return w
|
||||
# 4) 拷贝数据 + 跳过 CRLF
|
||||
if w + size > dst_cap: return -1
|
||||
k: INT = 0
|
||||
while k < size:
|
||||
for k in range(size):
|
||||
dst[w + k] = src[r + k]
|
||||
k += 1
|
||||
w += size
|
||||
r += size
|
||||
if r < src_len and src[r] == '\r': r += 1
|
||||
@@ -574,10 +572,8 @@ def _ResolveRedirectUrl(base: str, loc: str, out: str, cap: INT) -> INT:
|
||||
prefix_len: INT = INT(uint64(q) - uint64(base))
|
||||
need: INT = prefix_len + lb + 2
|
||||
if need >= cap: return -1
|
||||
i: INT = 0
|
||||
while i < prefix_len:
|
||||
for i in range(prefix_len):
|
||||
out[i] = base[i]
|
||||
i += 1
|
||||
if loc[0] == '/':
|
||||
j: INT = 0
|
||||
while loc[j] != '\0':
|
||||
@@ -606,8 +602,7 @@ def _HttpRedirectLoop(method: str, url: str, data: str, content_type: str) -> Re
|
||||
return None
|
||||
string.strcpy(cur, url)
|
||||
|
||||
hop: INT = 0
|
||||
while hop < 5:
|
||||
for hop in range(5):
|
||||
resp: Response* = None
|
||||
if string.strcmp(method, "POST") == 0:
|
||||
resp = _HttpPostOnce(cur, data, content_type)
|
||||
@@ -654,7 +649,6 @@ def _HttpRedirectLoop(method: str, url: str, data: str, content_type: str) -> Re
|
||||
_mbuddy.free(loc)
|
||||
_mbuddy.free(cur)
|
||||
cur = nxt
|
||||
hop += 1
|
||||
|
||||
_SetHttpError("too many redirects")
|
||||
_mbuddy.free(cur)
|
||||
@@ -802,8 +796,8 @@ def _DlOnce(url: str, start: sizet, count: INT, dst: str, dst_cap: INT,
|
||||
if url is None or dst is None or dst_cap <= 0 \
|
||||
or out_status is None or out_total is None:
|
||||
return -1
|
||||
c.Set(*out_status, 0)
|
||||
c.Set(*out_total, 0)
|
||||
*out_status = 0
|
||||
*out_total = 0
|
||||
if out_loc is not None and out_loccap > 0:
|
||||
out_loc[0] = 0
|
||||
|
||||
@@ -870,7 +864,7 @@ def _DlOnce(url: str, start: sizet, count: INT, dst: str, dst_cap: INT,
|
||||
dst[total] = 0
|
||||
|
||||
st: INT = _StatusRaw(dst)
|
||||
c.Set(*out_status, st)
|
||||
*out_status = st
|
||||
if st == 0:
|
||||
_SetHttpError("empty response")
|
||||
return -3
|
||||
@@ -884,11 +878,11 @@ def _DlOnce(url: str, start: sizet, count: INT, dst: str, dst_cap: INT,
|
||||
return -3
|
||||
|
||||
if st == 206:
|
||||
c.Set(*out_total, _CRTotalOf(dst, total))
|
||||
*out_total = _CRTotalOf(dst, total)
|
||||
else:
|
||||
cl2: INT = _CLenOf(dst, total)
|
||||
if cl2 > 0:
|
||||
c.Set(*out_total, sizet(cl2))
|
||||
*out_total = sizet(cl2)
|
||||
bo: INT = _FindBodyStart(dst, total)
|
||||
if bo < 0 or bo >= total:
|
||||
return 0
|
||||
|
||||
+8
-16
@@ -113,7 +113,7 @@ def _dl_slice(url: str, pos: sizet, want: INT, verify: bool, ca_file: str,
|
||||
stdlib.free(cur)
|
||||
if rc < 0:
|
||||
return rc
|
||||
c.Set(*out_total, tot)
|
||||
*out_total = tot
|
||||
return rc
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ def _dl_probe(url: str, verify: bool, ca_file: str,
|
||||
"""探测服务器总大小与 Range 支持。
|
||||
返回 0=支持 Range 且 out_total 有效;1=服务器返回 200(不支持 Range,
|
||||
退化为整段下载,out_total=Content-Length);-3 失败。"""
|
||||
c.Set(*out_total, 0)
|
||||
*out_total = 0
|
||||
buf: str = stdlib.malloc(8192)
|
||||
if buf is None:
|
||||
_dl_set_err("out of memory")
|
||||
@@ -197,7 +197,7 @@ def _dl_probe(url: str, verify: bool, ca_file: str,
|
||||
_dl_set_err("probe failed")
|
||||
return -3
|
||||
if tot > 0:
|
||||
c.Set(*out_total, tot)
|
||||
*out_total = tot
|
||||
return 0
|
||||
_dl_set_err("cannot determine size")
|
||||
return -3
|
||||
@@ -235,7 +235,7 @@ def _dl_download_band(path: str, url: str, is_https: INT, verify: bool, ca_file:
|
||||
if _dl_write_at(path, buf + bo, got, pos) != 0:
|
||||
_dl_set_err("write file failed")
|
||||
return -2
|
||||
c.Set(*p_done, *p_done + sizet(got))
|
||||
*p_done = *p_done + sizet(got)
|
||||
pos += sizet(got)
|
||||
if got < want:
|
||||
# 服务端提前结束(正常收尾时仅末片 < want)
|
||||
@@ -353,8 +353,7 @@ def download(url: str, path: str, threads: INT = 1,
|
||||
handles: t.CArray[VOIDPTR, DL_MAX_THREADS]
|
||||
threads_ok: INT = 0
|
||||
|
||||
i: INT = 0
|
||||
while i < threads:
|
||||
for i in range(threads):
|
||||
b_start: sizet = sizet(i) * band
|
||||
if b_start >= total:
|
||||
break
|
||||
@@ -402,33 +401,27 @@ def download(url: str, path: str, threads: INT = 1,
|
||||
th.start()
|
||||
handles[i] = th.handle
|
||||
threads_ok += 1
|
||||
i += 1
|
||||
|
||||
if threads_ok == 0:
|
||||
_dl_set_err("thread create failed")
|
||||
return -3
|
||||
|
||||
# 等待全部线程结束
|
||||
j: INT = 0
|
||||
while j < threads_ok:
|
||||
for j in range(threads_ok):
|
||||
wsync.WaitForSingleObject(handles[j], 0xFFFFFFFF)
|
||||
wb.CloseHandle(handles[j])
|
||||
j += 1
|
||||
|
||||
# 汇总结果
|
||||
total_done: sizet = 0
|
||||
failed_job: INT = 0
|
||||
k: INT = 0
|
||||
while k < threads_ok:
|
||||
for k in range(threads_ok):
|
||||
jobk: DlJob* = ctxs[k]
|
||||
total_done += jobk.done
|
||||
if jobk.status != 0:
|
||||
failed_job = 1
|
||||
k += 1
|
||||
|
||||
# 释放线程上下文
|
||||
m: INT = 0
|
||||
while m < threads_ok:
|
||||
for m in range(threads_ok):
|
||||
jobm: DlJob* = ctxs[m]
|
||||
stdlib.free(jobm.path)
|
||||
stdlib.free(jobm.url)
|
||||
@@ -436,7 +429,6 @@ def download(url: str, path: str, threads: INT = 1,
|
||||
stdlib.free(jobm.ca_file)
|
||||
stdlib.free(jobm.buf)
|
||||
stdlib.free(t.CPtr(uint64(jobm)))
|
||||
m += 1
|
||||
|
||||
if failed_job != 0 or total_done != total:
|
||||
stdio.printf("[download] incomplete: %zu/%zu bytes\n", total_done, total)
|
||||
|
||||
+9
-17
@@ -76,10 +76,8 @@ def stream_pull(out: str, cap: INT) -> INT:
|
||||
avail = INT(_st_len - _st_consumed)
|
||||
if avail > cap - 1:
|
||||
avail = cap - 1
|
||||
i: sizet = 0
|
||||
while i < sizet(avail):
|
||||
for i in range(sizet(avail)):
|
||||
out[i] = _st_buf[_st_consumed + i]
|
||||
i += 1
|
||||
out[sizet(avail)] = 0
|
||||
_st_consumed += sizet(avail)
|
||||
return avail
|
||||
@@ -503,8 +501,7 @@ def _HttpsRedirectLoop(method: str, url: str, verify: bool, ca_file: str, data:
|
||||
return None
|
||||
string.strcpy(cur, url)
|
||||
|
||||
hop: INT = 0
|
||||
while hop < 5:
|
||||
for hop in range(5):
|
||||
resp: rawptr[requests.Response] = _HttpsRequest(method, cur, verify, ca_file, data, content_type, auth)
|
||||
if resp is None:
|
||||
requests._mbuddy.free(cur)
|
||||
@@ -549,7 +546,6 @@ def _HttpsRedirectLoop(method: str, url: str, verify: bool, ca_file: str, data:
|
||||
requests._mbuddy.free(loc)
|
||||
requests._mbuddy.free(cur)
|
||||
cur = nxt
|
||||
hop += 1
|
||||
|
||||
_RecordErrorText("too many redirects")
|
||||
requests._mbuddy.free(cur)
|
||||
@@ -843,12 +839,10 @@ def post_stream(url: str, data: str, content_type: str = "application/json",
|
||||
while True:
|
||||
# 找行尾 \n
|
||||
nl: INT = -1
|
||||
k: INT = 0
|
||||
while k < llen:
|
||||
for k in range(llen):
|
||||
if leftover[k] == 10:
|
||||
nl = k
|
||||
break
|
||||
k += 1
|
||||
if nl < 0:
|
||||
break
|
||||
e: INT = nl
|
||||
@@ -886,10 +880,8 @@ def post_stream(url: str, data: str, content_type: str = "application/json",
|
||||
_StreamAppendContent(dtx)
|
||||
# 3) 移除已处理行
|
||||
rem: INT = llen - (nl + 1)
|
||||
j2: INT = 0
|
||||
while j2 < rem:
|
||||
for j2 in range(rem):
|
||||
leftover[j2] = leftover[nl + 1 + j2]
|
||||
j2 += 1
|
||||
llen = rem
|
||||
|
||||
# ---- 收尾 ----
|
||||
@@ -938,8 +930,8 @@ def _DlOnce(url: str, start: sizet, count: INT, verify: bool, ca_file: str,
|
||||
if url is None or dst is None or dst_cap <= 0 \
|
||||
or out_status is None or out_total is None:
|
||||
return -1
|
||||
c.Set(*out_status, 0)
|
||||
c.Set(*out_total, 0)
|
||||
*out_status = 0
|
||||
*out_total = 0
|
||||
if out_loc is not None and out_loccap > 0:
|
||||
out_loc[0] = 0
|
||||
_last_verify_flag = 1 if verify else 0
|
||||
@@ -1064,7 +1056,7 @@ def _DlOnce(url: str, start: sizet, count: INT, verify: bool, ca_file: str,
|
||||
dst[total] = 0
|
||||
|
||||
st: INT = requests._StatusRaw(dst)
|
||||
c.Set(*out_status, st)
|
||||
*out_status = st
|
||||
if st == 0:
|
||||
_RecordErrorText("empty response")
|
||||
return -3
|
||||
@@ -1078,11 +1070,11 @@ def _DlOnce(url: str, start: sizet, count: INT, verify: bool, ca_file: str,
|
||||
return -3
|
||||
|
||||
if st == 206:
|
||||
c.Set(*out_total, requests._CRTotalOf(dst, total))
|
||||
*out_total = requests._CRTotalOf(dst, total)
|
||||
else:
|
||||
cl2: INT = requests._CLenOf(dst, total)
|
||||
if cl2 > 0:
|
||||
c.Set(*out_total, sizet(cl2))
|
||||
*out_total = sizet(cl2)
|
||||
bo: INT = requests._FindBodyStart(dst, total)
|
||||
if bo < 0 or bo >= total:
|
||||
return 0
|
||||
|
||||
@@ -116,11 +116,9 @@ def strncmp(str1: str, str2: str, n: sizet) -> int:
|
||||
def memcmp(ptr1: t.CPtr, ptr2: t.CPtr, n: sizet) -> int:
|
||||
p1: BYTEPTR = BYTEPTR(ptr1)
|
||||
p2: BYTEPTR = BYTEPTR(ptr2)
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
if p1[i] != p2[i]:
|
||||
return int(p1[i]) - int(p2[i])
|
||||
i += 1
|
||||
return 0
|
||||
|
||||
|
||||
@@ -427,10 +425,8 @@ def _dd_pow10(e: int, out: t.CArray[double, 2], tmp: t.CArray[double, 2]):
|
||||
if k < 22:
|
||||
step = k
|
||||
p10: double = 1.0
|
||||
i: int = 0
|
||||
while i < step:
|
||||
for i in range(step):
|
||||
p10 = p10 * 10.0
|
||||
i += 1
|
||||
_dd_mul(out[0], out[1], p10, 0.0, tmp)
|
||||
out[0] = tmp[0]
|
||||
out[1] = tmp[1]
|
||||
|
||||
+15
-45
@@ -119,10 +119,8 @@ def fill(t0: Tensor*, val: double):
|
||||
return
|
||||
d: double* = t0.Data
|
||||
n: sizet = t0.Rows * t0.Cols
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
d[i] = val
|
||||
i += 1
|
||||
|
||||
|
||||
def zero_grad(t0: Tensor*):
|
||||
@@ -161,10 +159,8 @@ def uniform_fill(t0: Tensor*, lo: double, hi: double):
|
||||
d: double* = t0.Data
|
||||
n: sizet = t0.Rows * t0.Cols
|
||||
span: double = hi - lo
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
d[i] = lo + _next_rand() * span
|
||||
i += 1
|
||||
|
||||
|
||||
def kaiming_uniform_fill(w: Tensor*, fan_in: sizet,
|
||||
@@ -241,8 +237,7 @@ def linear_fwd(w: Tensor*, b: Tensor*,
|
||||
if acc_buf is None:
|
||||
return
|
||||
accp: double* = acc_buf
|
||||
i: sizet = 0
|
||||
while i < m:
|
||||
for i in range(m):
|
||||
j: sizet = 0
|
||||
while j < n:
|
||||
acc: double = bd[j]
|
||||
@@ -259,7 +254,6 @@ def linear_fwd(w: Tensor*, b: Tensor*,
|
||||
kk += 1
|
||||
od[i * n + j] = acc
|
||||
j += 1
|
||||
i += 1
|
||||
stdlib.free(acc_buf)
|
||||
|
||||
|
||||
@@ -294,8 +288,7 @@ def linear_bwd(w: Tensor*, x: Tensor*,
|
||||
string.memset(db.Data, 0, n * sizet(8))
|
||||
string.memset(dx.Data, 0, m * k * sizet(8))
|
||||
|
||||
b: sizet = 0
|
||||
while b < m:
|
||||
for b in range(m):
|
||||
j: sizet = 0
|
||||
while j < n:
|
||||
gj: double = gd[b * n + j]
|
||||
@@ -307,7 +300,6 @@ def linear_bwd(w: Tensor*, x: Tensor*,
|
||||
dxd[b * k + i] = dxd[b * k + i] + gj * wd[j * k + i]
|
||||
i += 1
|
||||
j += 1
|
||||
b += 1
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -348,13 +340,11 @@ def relu_backward(x: Tensor*, g: Tensor*,
|
||||
xd: double* = x.Data
|
||||
gd: double* = g.Data
|
||||
od: double* = gx.Data
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
if xd[i] > double(0.0):
|
||||
od[i] = gd[i]
|
||||
else:
|
||||
od[i] = double(0.0)
|
||||
i += 1
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -378,8 +368,7 @@ def softmax_crossentropy(logits: Tensor*,
|
||||
lb: int* = labels
|
||||
total: double = double(0.0)
|
||||
inv_m: double = double(1.0) / double(m)
|
||||
b: sizet = 0
|
||||
while b < m:
|
||||
for b in range(m):
|
||||
# 数值稳定 softmax
|
||||
mx: double = ld[b * c]
|
||||
j: sizet = 1
|
||||
@@ -404,7 +393,6 @@ def softmax_crossentropy(logits: Tensor*,
|
||||
o = double(1.0)
|
||||
gd[b * c + j] = (p - o) * inv_m
|
||||
j += 1
|
||||
b += 1
|
||||
loss[0] = total
|
||||
|
||||
|
||||
@@ -417,8 +405,7 @@ def row_argmax(x: Tensor*, pred: int*):
|
||||
m: sizet = x.Rows
|
||||
c: sizet = x.Cols
|
||||
d: double* = x.Data
|
||||
i: sizet = 0
|
||||
while i < m:
|
||||
for i in range(m):
|
||||
best: sizet = 0
|
||||
bv: double = d[i * c]
|
||||
j: sizet = 1
|
||||
@@ -428,7 +415,6 @@ def row_argmax(x: Tensor*, pred: int*):
|
||||
best = j
|
||||
j += 1
|
||||
pred[i] = int(best)
|
||||
i += 1
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -440,10 +426,8 @@ def sgd_step(param: Tensor*, lr: double):
|
||||
d: double* = param.Data
|
||||
g: double* = param.Grad
|
||||
n: sizet = param.Rows * param.Cols
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
d[i] = d[i] - lr * g[i]
|
||||
i += 1
|
||||
|
||||
|
||||
def sgd_step_momentum(param: Tensor*, vel: t.CPtr,
|
||||
@@ -462,12 +446,10 @@ def sgd_step_momentum(param: Tensor*, vel: t.CPtr,
|
||||
g: double* = param.Grad
|
||||
v: double* = vel
|
||||
n: sizet = param.Rows * param.Cols
|
||||
i: sizet = 0
|
||||
while i < n:
|
||||
for i in range(n):
|
||||
vv: double = momentum * v[i] + g[i]
|
||||
v[i] = vv
|
||||
d[i] = d[i] - lr * vv
|
||||
i += 1
|
||||
|
||||
|
||||
# ------------------------------------------------------------
|
||||
@@ -545,8 +527,7 @@ def conv2d_fwd(x: t.CPtr, w: t.CPtr, b: t.CPtr, out: t.CPtr,
|
||||
wbd: double* = wb
|
||||
t4d: double* = t4
|
||||
|
||||
bi: sizet = 0
|
||||
while bi < n:
|
||||
for bi in range(n):
|
||||
co: sizet = 0
|
||||
while co < cout:
|
||||
bias: double = double(0.0)
|
||||
@@ -628,7 +609,6 @@ def conv2d_fwd(x: t.CPtr, w: t.CPtr, b: t.CPtr, out: t.CPtr,
|
||||
ox += 1
|
||||
oy += 1
|
||||
co += 1
|
||||
bi += 1
|
||||
if wb is not None:
|
||||
stdlib.free(wb)
|
||||
if t4 is not None:
|
||||
@@ -667,8 +647,7 @@ def conv2d_bwd_dw(x: t.CPtr, dout: t.CPtr, dw: t.CPtr, db: t.CPtr,
|
||||
simd_on = 0
|
||||
accd: double* = acc
|
||||
|
||||
bi: sizet = 0
|
||||
while bi < n:
|
||||
for bi in range(n):
|
||||
co: sizet = 0
|
||||
while co < cout:
|
||||
gp: sizet = (bi * cout + co) * hout * wout
|
||||
@@ -745,7 +724,6 @@ def conv2d_bwd_dw(x: t.CPtr, dout: t.CPtr, dw: t.CPtr, db: t.CPtr,
|
||||
ky += 1
|
||||
ci += 1
|
||||
co += 1
|
||||
bi += 1
|
||||
if acc is not None:
|
||||
stdlib.free(acc)
|
||||
|
||||
@@ -782,17 +760,14 @@ def conv2d_bwd_dx(w: t.CPtr, dout: t.CPtr, dx: t.CPtr,
|
||||
# 权重在一次调用内不变 → 整体预广播一次(注意别在 4 路循环里重复
|
||||
# vbroadcastsd: 那是 4 次 store, 会把 SIMD 的收益吃掉一半)
|
||||
wjn: sizet = cout * kk
|
||||
wj4: sizet = 0
|
||||
while wj4 < wjn:
|
||||
for wj4 in range(wjn):
|
||||
wq2: double = wd[wj4]
|
||||
wbd[wj4 * 4] = wq2
|
||||
wbd[wj4 * 4 + 1] = wq2
|
||||
wbd[wj4 * 4 + 2] = wq2
|
||||
wbd[wj4 * 4 + 3] = wq2
|
||||
wj4 += 1
|
||||
|
||||
bi: sizet = 0
|
||||
while bi < n:
|
||||
for bi in range(n):
|
||||
ci: sizet = 0
|
||||
while ci < cin:
|
||||
ky: sizet = 0
|
||||
@@ -839,7 +814,6 @@ def conv2d_bwd_dx(w: t.CPtr, dout: t.CPtr, dx: t.CPtr,
|
||||
oy += 1
|
||||
ky += 1
|
||||
ci += 1
|
||||
bi += 1
|
||||
if wb is not None:
|
||||
stdlib.free(wb)
|
||||
|
||||
@@ -858,8 +832,7 @@ def maxpool2d_fwd(x: t.CPtr, out: t.CPtr, argmax: t.CPtr,
|
||||
xd: double* = x
|
||||
od: double* = out
|
||||
am: int* = argmax
|
||||
bi: sizet = 0
|
||||
while bi < n:
|
||||
for bi in range(n):
|
||||
ch: sizet = 0
|
||||
while ch < c:
|
||||
plano: sizet = (bi * c + ch) * hin * win
|
||||
@@ -891,7 +864,6 @@ def maxpool2d_fwd(x: t.CPtr, out: t.CPtr, argmax: t.CPtr,
|
||||
ox += 1
|
||||
oy += 1
|
||||
ch += 1
|
||||
bi += 1
|
||||
|
||||
|
||||
def maxpool2d_bwd(dout: t.CPtr, argmax: t.CPtr, dx: t.CPtr,
|
||||
@@ -906,8 +878,7 @@ def maxpool2d_bwd(dout: t.CPtr, argmax: t.CPtr, dx: t.CPtr,
|
||||
am: int* = argmax
|
||||
dxd: double* = dx
|
||||
string.memset(dx, 0, n * c * hin * win * sizet(8))
|
||||
bi: sizet = 0
|
||||
while bi < n:
|
||||
for bi in range(n):
|
||||
ch: sizet = 0
|
||||
while ch < c:
|
||||
plano: sizet = (bi * c + ch) * hin * win
|
||||
@@ -921,4 +892,3 @@ def maxpool2d_bwd(dout: t.CPtr, argmax: t.CPtr, dx: t.CPtr,
|
||||
ox += 1
|
||||
oy += 1
|
||||
ch += 1
|
||||
bi += 1
|
||||
+4
-12
@@ -932,8 +932,7 @@ def LoadMapFile(hFile: HANDLE, Size: int64) -> int:
|
||||
return MapFailHdr(Size, "string pool does not end with '\\0' (pool corrupt)", Buf)
|
||||
# Full-table check: strictly ascending rva + string offsets inside the pool.
|
||||
Prev: uint64 = 0
|
||||
i: int = 0
|
||||
while i < int(Cnt):
|
||||
for i in range(int(Cnt)):
|
||||
Off: int = TRACEBACK_MAP_HEADER + int(i) * TRACEBACK_ENTRY_SIZE
|
||||
Cur: uint64 = ReadU64(Buf, Off)
|
||||
if i > 0 and Cur <= Prev:
|
||||
@@ -951,7 +950,6 @@ def LoadMapFile(hFile: HANDLE, Size: int64) -> int:
|
||||
return MapFailEntry(Size, int(i),
|
||||
"func_off is neither 0 (no name) nor inside the string pool",
|
||||
uint64(FN))
|
||||
i += 1
|
||||
_State.MapBase = Buf
|
||||
_State.EntryCount = Cnt
|
||||
_State.StrBytes = SBytes
|
||||
@@ -1430,8 +1428,7 @@ def ScanStack(StartIndex: int, Rsp: uint64, Base: uint64) -> int:
|
||||
EmitLine(D1)
|
||||
Stop = "block_read_failed"
|
||||
break
|
||||
k: int = 0
|
||||
while k < N:
|
||||
for k in range(N):
|
||||
W: uint64 = Words[int(k)]
|
||||
if W >= Base and W < ModEnd:
|
||||
# A neighbouring 8-byte word (A-8 or A+8) looks like a stack address: accept W.
|
||||
@@ -1456,7 +1453,6 @@ def ScanStack(StartIndex: int, Rsp: uint64, Base: uint64) -> int:
|
||||
Found[Hits] = W
|
||||
Hits += 1
|
||||
Prev = W
|
||||
k += 1
|
||||
Addr = Addr + uint64(TRACEBACK_SCAN_CHUNK_BYTES)
|
||||
if DiagEnabled() != 0:
|
||||
D2: int = stdio.snprintf(_State.LineBuf, sizet(TRACEBACK_LINE_CAP),
|
||||
@@ -1761,19 +1757,15 @@ def DumpMainThread(IsBreak: int) -> int:
|
||||
SavedCount: int = _State.FrameCount
|
||||
SaveAddrBuf: t.CArray[uint64, TRACEBACK_FRAME_BUF]
|
||||
SaveScanBuf: t.CArray[int32, TRACEBACK_FRAME_BUF]
|
||||
si: int = 0
|
||||
while si < SavedCount:
|
||||
for si in range(SavedCount):
|
||||
SaveAddrBuf[si] = _State.FrameAddr[si]
|
||||
SaveScanBuf[si] = _State.FrameScan[si]
|
||||
si += 1
|
||||
_State.FrameCount = 0
|
||||
F2: int = WalkViaDbgHelp(wp.GetCurrentProcess(), hThread, _State.ContextBuf, Base)
|
||||
if F2 == 0:
|
||||
ri: int = 0
|
||||
while ri < SavedCount:
|
||||
for ri in range(SavedCount):
|
||||
if FramePush(SaveAddrBuf[ri], int(SaveScanBuf[ri])) == 0:
|
||||
break
|
||||
ri += 1
|
||||
# The count that is actually buffered is authoritative.
|
||||
Frames = _State.FrameCount
|
||||
if DiagEnabled() != 0:
|
||||
|
||||
+4
-12
@@ -644,10 +644,8 @@ export def vsnprintf(buf: bytes, size: sizet, fmt: str, ap: str) -> int:
|
||||
work = work - double(d) * scale
|
||||
scale /= 10.0
|
||||
frac_val: double = work
|
||||
p: int = 0
|
||||
while p < precision:
|
||||
for p in range(precision):
|
||||
frac_val *= 10.0
|
||||
p += 1
|
||||
frac_part: uint64 = uint64(frac_val + 0.5)
|
||||
f_total: int = di + (precision + 1 if precision > 0 else 0)
|
||||
if not left_align and not pad_zero and width > f_total:
|
||||
@@ -808,10 +806,8 @@ export def vsnprintf(buf: bytes, size: sizet, fmt: str, ap: str) -> int:
|
||||
p += 1
|
||||
frac_p: uint64 = uint64(frac_v + 0.5)
|
||||
carry: uint64 = 1
|
||||
p = 0
|
||||
while p < precision:
|
||||
for p in range(precision):
|
||||
carry *= 10
|
||||
p += 1
|
||||
if frac_p >= carry and carry > 0:
|
||||
frac_p = 0
|
||||
int_digit += 1
|
||||
@@ -1011,10 +1007,8 @@ export def vsnprintf(buf: bytes, size: sizet, fmt: str, ap: str) -> int:
|
||||
p += 1
|
||||
frac_p: uint64 = uint64(frac_v + 0.5)
|
||||
carry: uint64 = 1
|
||||
p = 0
|
||||
while p < prec_e:
|
||||
for p in range(prec_e):
|
||||
carry *= 10
|
||||
p += 1
|
||||
if frac_p >= carry and carry > 0:
|
||||
frac_p = 0
|
||||
int_digit += 1
|
||||
@@ -1063,10 +1057,8 @@ export def vsnprintf(buf: bytes, size: sizet, fmt: str, ap: str) -> int:
|
||||
temp[g_len] = 46
|
||||
g_len += 1
|
||||
frac_val: double = work
|
||||
p = 0
|
||||
while p < prec_f:
|
||||
for p in range(prec_f):
|
||||
frac_val *= 10.0
|
||||
p += 1
|
||||
frac_part: uint64 = uint64(frac_val + 0.5)
|
||||
# Store decimal digits in reverse order (ones place goes to g_len prec_f-1), temp is directly in forward order.
|
||||
# The original swap-reverse loop doesn't work in TPV compiled output (decimal digits aren't reversed, e.g., 456->654),
|
||||
|
||||
+1
-3
@@ -331,8 +331,7 @@ class ZipFile:
|
||||
|
||||
cp: sizet = sizet(cd_off)
|
||||
end: sizet = sizet(cd_off) + sizet(cd_size)
|
||||
idx: sizet = 0
|
||||
while idx < total:
|
||||
for idx in range(total):
|
||||
if cp + 46 > end:
|
||||
zipfile_set_error(ZIP_ERR_NOT_ZIP, "central directory entry truncated")
|
||||
return ZIP_ERR_NOT_ZIP
|
||||
@@ -370,7 +369,6 @@ class ZipFile:
|
||||
node.file_size = sizet(usize)
|
||||
node.header_offset = sizet(hoff)
|
||||
cp = cp + rec_len
|
||||
idx += 1
|
||||
return ZIP_ERR_OK
|
||||
|
||||
# ---- 公共查询 ----
|
||||
|
||||
+16
-16
@@ -97,7 +97,7 @@ class Compress:
|
||||
set_error(Z_STREAM_ERROR, "out_len is None")
|
||||
return None
|
||||
if data_len == 0:
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -115,7 +115,7 @@ class Compress:
|
||||
self.pool.free(self.input_buf)
|
||||
if not new_buf:
|
||||
set_error(Z_MEM_ERROR, "out of memory")
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -125,7 +125,7 @@ class Compress:
|
||||
self.input_buf = new_buf
|
||||
string.memcpy(self.input_buf + self.input_buf_len, data, data_len)
|
||||
self.input_buf_len += data_len
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -171,7 +171,7 @@ class Compress:
|
||||
else:
|
||||
result: BYTEPTR = BYTEPTR(self.pool.alloc(total))
|
||||
if result: string.memcpy(result, s.writer.buf, total)
|
||||
c.Set(*out_len, total)
|
||||
*out_len = total
|
||||
if self.pool == None:
|
||||
stdlib.free(self.input_buf)
|
||||
else:
|
||||
@@ -195,7 +195,7 @@ class Compress:
|
||||
delta: sizet = total - prev_pos
|
||||
self.last_pos = s.writer.byte_pos
|
||||
if delta == 0:
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -208,9 +208,9 @@ class Compress:
|
||||
else:
|
||||
result: BYTEPTR = BYTEPTR(self.pool.alloc(delta))
|
||||
if result: string.memcpy(result, s.writer.buf + prev_pos, delta)
|
||||
c.Set(*out_len, delta)
|
||||
*out_len = delta
|
||||
return result
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -319,7 +319,7 @@ class Decompress:
|
||||
if data and data_len > 0:
|
||||
append_bytes(self.pool, &self._unused_data, &self._unused_data_len,
|
||||
&self._unused_data_cap, data, data_len)
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -331,7 +331,7 @@ class Decompress:
|
||||
append_bytes(self.pool, &self.input_buf, &self.input_buf_len,
|
||||
&self.input_buf_cap, data, data_len)
|
||||
if self.input_buf_len == 0:
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -377,7 +377,7 @@ class Decompress:
|
||||
if not out_len:
|
||||
set_error(Z_STREAM_ERROR, "out_len is None")
|
||||
return None
|
||||
c.Set(*out_len, 0)
|
||||
*out_len = 0
|
||||
if self.pool == None:
|
||||
return BYTEPTR(stdlib.calloc(1, 1))
|
||||
else:
|
||||
@@ -446,7 +446,7 @@ class Decompress:
|
||||
# c.Set(c.Deref(length), 0)
|
||||
# return None
|
||||
if length:
|
||||
c.Set(*length, self._unused_data_len)
|
||||
*length = self._unused_data_len
|
||||
return self._unused_data
|
||||
|
||||
def unconsumed_tail(self, length: sizet*) -> BYTEPTR:
|
||||
@@ -455,7 +455,7 @@ class Decompress:
|
||||
# c.Set(c.Deref(length), 0)
|
||||
# return None
|
||||
if length:
|
||||
c.Set(*length, self._unconsumed_tail_len)
|
||||
*length = self._unconsumed_tail_len
|
||||
return self._unconsumed_tail
|
||||
|
||||
# def eof(self) -> t.CInt:
|
||||
@@ -501,10 +501,10 @@ def append_bytes(pool: rawptr[memhub.MemManager], buf: BYTEPTR*, length: sizet*,
|
||||
string.memcpy(new_buf, *buf, *length)
|
||||
pool.free(*buf)
|
||||
if not new_buf: return -1
|
||||
c.Set(*buf, new_buf)
|
||||
c.Set(*cap, new_cap)
|
||||
*buf = new_buf
|
||||
*cap = new_cap
|
||||
string.memcpy(*buf + *length, data, data_len)
|
||||
c.Set(*length, *length + data_len)
|
||||
*length = *length + data_len
|
||||
return 0
|
||||
|
||||
|
||||
@@ -602,7 +602,7 @@ def compress(pool: rawptr[memhub.MemManager], data: BYTEPTR, data_len: sizet,
|
||||
gzip_buf[pos + 6] = (data_len >> 16) & 0xFF
|
||||
gzip_buf[pos + 7] = (data_len >> 24) & 0xFF
|
||||
pos += 8
|
||||
c.Set(*out_len, pos)
|
||||
*out_len = pos
|
||||
return shrink_to_fit(pool, gzip_buf, pos)
|
||||
return shrink_to_fit(pool, raw_result, *out_len)
|
||||
|
||||
|
||||
+2
-2
@@ -250,7 +250,7 @@ class zbit_reader:
|
||||
if self.bit_pos == 8:
|
||||
self.bit_pos = 0
|
||||
self.byte_pos += 1
|
||||
c.Set(*out, val)
|
||||
*out = val
|
||||
return 0
|
||||
|
||||
def read_bits_rev(self, nbits: int, out: UINTPTR) -> int:
|
||||
@@ -263,7 +263,7 @@ class zbit_reader:
|
||||
if self.bit_pos == 8:
|
||||
self.bit_pos = 0
|
||||
self.byte_pos += 1
|
||||
c.Set(*out, val)
|
||||
*out = val
|
||||
return 0
|
||||
|
||||
def align(self):
|
||||
|
||||
+9
-9
@@ -27,7 +27,7 @@ class zdeflate_stream:
|
||||
h: uint = zdeflate_hash(data + pos)
|
||||
chain: int = self.hash_head[h]
|
||||
best_len: int = zdef.ZDEFLATE_MIN_MATCH - 1
|
||||
c.Set(*best_dist, 0)
|
||||
*best_dist = 0
|
||||
max_chain: int = 128 if (self.level >= 5) else (32 if (self.level >= 2) else 4)
|
||||
limit: int = (1 << self.wbits) if (self.wbits > 0) else zdef.ZDEFLATE_WINDOW_SIZE
|
||||
if limit > zdef.ZDEFLATE_WINDOW_SIZE:
|
||||
@@ -44,7 +44,7 @@ class zdeflate_stream:
|
||||
match_len += 1
|
||||
if match_len > best_len:
|
||||
best_len = match_len
|
||||
c.Set(*best_dist, dist)
|
||||
*best_dist = dist
|
||||
if best_len >= zdef.ZDEFLATE_MAX_MATCH: break
|
||||
chain = self.hash_prev[chain & zdef.ZDEFLATE_WINDOW_MASK]
|
||||
if chain <= int(pos) - limit: break
|
||||
@@ -171,15 +171,15 @@ class zdeflate_stream:
|
||||
out: BYTEPTR*, out_len: sizet*) -> int:
|
||||
if self.is_finished: return -2
|
||||
if not data or length == 0:
|
||||
c.Set(*out, None)
|
||||
c.Set(*out_len, 0)
|
||||
*out = None
|
||||
*out_len = 0
|
||||
return 0
|
||||
self.adler = zchecksum.zchecksum_adler32(data, length, self.adler)
|
||||
string.memset(self.hash_head, -1, zdef.ZDEFLATE_HASH_SIZE * int.__sizeof__())
|
||||
string.memset(self.hash_prev, -1, zdef.ZDEFLATE_WINDOW_SIZE * int.__sizeof__())
|
||||
self.compress_block(data, length, 0)
|
||||
c.Set(*out_len, self.writer.total())
|
||||
c.Set(*out, UINT8PTR(zdef.zdef_alloc(self.pool, *out_len)))
|
||||
*out_len = self.writer.total()
|
||||
*out = UINT8PTR(zdef.zdef_alloc(self.pool, *out_len))
|
||||
if not *out: return -4
|
||||
string.memcpy(*out, self.writer.buf, *out_len)
|
||||
return 0
|
||||
@@ -211,8 +211,8 @@ class zdeflate_stream:
|
||||
self.writer.write_bits(0, 1)
|
||||
self.writer.write_bits(0, 2)
|
||||
self.writer.align()
|
||||
c.Set(*out_len, self.writer.total())
|
||||
c.Set(*out, UINT8PTR(zdef.zdef_alloc(self.pool, *out_len)))
|
||||
*out_len = self.writer.total()
|
||||
*out = UINT8PTR(zdef.zdef_alloc(self.pool, *out_len))
|
||||
if not *out: return -4
|
||||
string.memcpy(*out, self.writer.buf, *out_len)
|
||||
return 0
|
||||
@@ -436,7 +436,7 @@ def zdeflate_one_shot(pool: rawptr[memhub.MemManager], data: UINT8PTR, length: s
|
||||
s.writer.buf[s.writer.byte_pos + 2] = (adler >> 8) & 0xFF
|
||||
s.writer.buf[s.writer.byte_pos + 3] = (adler >> 0) & 0xFF
|
||||
s.writer.byte_pos += 4
|
||||
c.Set(*out_len, s.writer.total())
|
||||
*out_len = s.writer.total()
|
||||
result: UINT8PTR = UINT8PTR(zdef.zdef_alloc(pool, *out_len))
|
||||
if result: string.memcpy(result, s.writer.buf, *out_len)
|
||||
s.destroy()
|
||||
|
||||
+4
-4
@@ -104,7 +104,7 @@ class zinflate_stream:
|
||||
if self.reader.bit_pos == 8:
|
||||
self.reader.bit_pos = 0
|
||||
self.input_pos += 1
|
||||
c.Set(*out, val)
|
||||
*out = val
|
||||
return 0
|
||||
|
||||
|
||||
@@ -394,12 +394,12 @@ class zinflate_stream:
|
||||
self.max_length = max_length
|
||||
err: int = self.inflate_stream()
|
||||
if err != 0: return err
|
||||
c.Set(*out_len, self.output_len)
|
||||
*out_len = self.output_len
|
||||
if self.output_len == 0:
|
||||
c.Set(*out, UINT8PTR(zdef.zdef_alloc(self.pool, 1)))
|
||||
*out = UINT8PTR(zdef.zdef_alloc(self.pool, 1))
|
||||
else:
|
||||
dst: UINT8PTR = UINT8PTR(zdef.zdef_alloc(self.pool, self.output_len))
|
||||
c.Set(*out, dst)
|
||||
*out = dst
|
||||
if dst:
|
||||
string.memcpy(dst, self.output, self.output_len)
|
||||
return 0
|
||||
|
||||
Reference in new issue
Block a user