fix(vpi): count a static method's first parameter as an argument
LookupSignDefaultsByName subtracted one receiver slot from every class-level def, but the vpi keeps the declared parameter list: a @staticmethod's first parameter is a real argument. Scheduler.exit_process(pid: int) therefore reported 0 parameters and the call-site arity check rejected exit_process(p.pid). Subtract the receiver only when the first parameter is actually named self/cls.
This commit is contained in:
1 parent
8effc94827
commit
825fef8f41
1 file changed
+26
-2
@@ -2953,19 +2953,43 @@ def LookupSignDefaultsByName(pool: memhub.MemBuddy*, sha1: str, name: str, kinds
|
||||
if parse_defaults == 0:
|
||||
# 只数形参个数(含可变参数则放弃:调用方跳过 arity 校验)
|
||||
pc_only: int = _VpiParamCountAndVararg(vbuf, hit_ps, hit_pe)
|
||||
self_only: int = 0
|
||||
if pc_only > 0 and hit_method != 0:
|
||||
if _VpiFirstParamIsSelf(vbuf, hit_ps, hit_pe) != 0: self_only = 1
|
||||
stdlib.free(vbuf)
|
||||
if pc_only < 0: return -1
|
||||
if hit_method != 0 and pc_only > 0: pc_only -= 1
|
||||
if self_only != 0: pc_only -= 1
|
||||
return pc_only << 8
|
||||
enc: int = _VpiParseParamDefaults(pool, vbuf, hit_ps, hit_pe, kinds, ints, strs)
|
||||
self_f: int = 0
|
||||
if hit_method != 0 and _VpiFirstParamIsSelf(vbuf, hit_ps, hit_pe) != 0: self_f = 1
|
||||
stdlib.free(vbuf)
|
||||
if enc < 0: return -1
|
||||
pc_f: int = enc >> 8
|
||||
dc_f: int = enc & 0xFF
|
||||
if hit_method != 0 and pc_f > 0: pc_f -= 1
|
||||
if self_f != 0 and pc_f > 0: pc_f -= 1
|
||||
return (pc_f << 8) | dc_f
|
||||
|
||||
|
||||
# _VpiFirstParamIsSelf - 1 when the first parameter listed in [ps, pe) is named self/cls.
|
||||
# Only those methods carry a receiver slot; a `@staticmethod` whose first parameter is a real
|
||||
# argument must not have one subtracted from its parameter count.
|
||||
def _VpiFirstParamIsSelf(buf: bytes, ps: sizet, pe: sizet) -> int:
|
||||
"""1 when the first parameter in the vpi text range is named self or cls."""
|
||||
if buf is None or pe <= ps: return 0
|
||||
i: sizet = ps
|
||||
while i < pe and (buf[i] == 0x20 or buf[i] == 0x09): i += 1
|
||||
s: sizet = i
|
||||
while i < pe:
|
||||
ch: char = buf[i]
|
||||
if ch == ':' or ch == '=' or ch == ',' or ch == ')' or ch == 0x20 or ch == 0x09: break
|
||||
i += 1
|
||||
n: sizet = i - s
|
||||
if n == 4 and string.strncmp(buf + s, "self", 4) == 0: return 1
|
||||
if n == 3 and string.strncmp(buf + s, "cls", 3) == 0: return 1
|
||||
return 0
|
||||
|
||||
|
||||
# LookupParamCountByName - 取定义模块 .vpi 里某函数/方法的形参个数(方法不含 self)
|
||||
# 返回 -1 表示未找到或签名含可变参数(调用方应跳过 arity 校验)。
|
||||
def LookupParamCountByName(pool: memhub.MemBuddy*, sha1: str, name: str) -> int:
|
||||
|
||||
Reference in new issue
Block a user