修正了一些错误
This commit is contained in:
@@ -3,6 +3,7 @@ from stdint import *
|
||||
import ast
|
||||
import memhub
|
||||
import string
|
||||
import stdlib
|
||||
import viperlib
|
||||
import stdio
|
||||
import lib.core.Handles.HandlesBase as HandlesBase
|
||||
@@ -88,14 +89,24 @@ def is_module_imported(imported_modules: str, name: str) -> int:
|
||||
def add_from_import(pool: memhub.MemBuddy | t.CPtr,
|
||||
from_imports: str,
|
||||
local_name: str,
|
||||
module_name: str) -> str:
|
||||
"""添加 from-import 映射 "name:module",返回新的 from_imports 字符串"""
|
||||
module_name: str,
|
||||
original_name: str = None) -> str:
|
||||
"""添加 from-import 映射,返回新的 from_imports 字符串
|
||||
|
||||
格式:
|
||||
无别名: "local_name:module_name"
|
||||
有别名: "local_name:module_name:original_name"
|
||||
(original_name 为源模块中的真实函数名,用于跨模块 SHA1 修饰)
|
||||
"""
|
||||
if local_name is None or module_name is None:
|
||||
return from_imports
|
||||
entry: t.CChar | t.CPtr = pool.alloc(128)
|
||||
entry: t.CChar | t.CPtr = pool.alloc(256)
|
||||
if entry is None:
|
||||
return from_imports
|
||||
viperlib.snprintf(entry, 128, "%s:%s", local_name, module_name)
|
||||
if original_name is not None and original_name != local_name:
|
||||
viperlib.snprintf(entry, 256, "%s:%s:%s", local_name, module_name, original_name)
|
||||
else:
|
||||
viperlib.snprintf(entry, 256, "%s:%s", local_name, module_name)
|
||||
if from_imports is None:
|
||||
return entry
|
||||
else:
|
||||
@@ -111,6 +122,75 @@ def add_from_import(pool: memhub.MemBuddy | t.CPtr,
|
||||
return from_imports
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 查找 from-import 名称 → 返回原始函数名(别名场景)
|
||||
#
|
||||
# 对于 from X import Y as Z,返回 Y(源模块中的真实函数名)。
|
||||
# 无别名时返回 None(local_name 即为原始名)。
|
||||
# ============================================================
|
||||
def lookup_from_import_original(from_imports: str,
|
||||
local_name: str) -> str:
|
||||
"""查找 from-import 别名对应的原始函数名,返回 None=无别名或未找到"""
|
||||
if local_name is None or from_imports is None:
|
||||
return None
|
||||
name_len: t.CSizeT = string.strlen(local_name)
|
||||
cur: t.CChar | t.CPtr = from_imports
|
||||
ci: t.CSizeT = 0
|
||||
total_len: t.CSizeT = string.strlen(from_imports)
|
||||
while ci < total_len:
|
||||
# 跳过前导空格
|
||||
while ci < total_len and cur[ci] == ' ':
|
||||
ci += 1
|
||||
if ci >= total_len:
|
||||
break
|
||||
# 找到第一个 ':' 的位置
|
||||
colon1: t.CSizeT = ci
|
||||
while colon1 < total_len and cur[colon1] != ':' and cur[colon1] != ' ':
|
||||
colon1 += 1
|
||||
if colon1 >= total_len or cur[colon1] != ':':
|
||||
break
|
||||
entry_name_len: t.CSizeT = colon1 - ci
|
||||
# 跳过 star import
|
||||
if entry_name_len == 1 and cur[ci] == '*':
|
||||
ci = colon1
|
||||
while ci < total_len and cur[ci] != ' ':
|
||||
ci += 1
|
||||
continue
|
||||
# 比较名称
|
||||
if entry_name_len == name_len:
|
||||
match: int = 1
|
||||
ei: t.CSizeT = 0
|
||||
while ei < name_len:
|
||||
if cur[ci + ei] != local_name[ei]:
|
||||
match = 0
|
||||
break
|
||||
ei += 1
|
||||
if match == 1:
|
||||
# 找到匹配,检查是否有第三个字段(原始名)
|
||||
pos: t.CSizeT = colon1 + 1
|
||||
# 跳过模块名
|
||||
while pos < total_len and cur[pos] != ':' and cur[pos] != ' ' and cur[pos] != '\0':
|
||||
pos += 1
|
||||
if pos < total_len and cur[pos] == ':':
|
||||
# 有第三个字段: original_name
|
||||
orig_start: t.CSizeT = pos + 1
|
||||
orig_end: t.CSizeT = orig_start
|
||||
while orig_end < total_len and cur[orig_end] != ' ' and cur[orig_end] != '\0':
|
||||
orig_end += 1
|
||||
orig_len: t.CSizeT = orig_end - orig_start
|
||||
if orig_len > 0:
|
||||
orig_buf: str = cur + orig_start
|
||||
# 返回指向内部的指针(调用方需在使用期内保持 from_imports 有效)
|
||||
return orig_buf
|
||||
return None
|
||||
return None
|
||||
# 跳到下一个条目
|
||||
ci = colon1
|
||||
while ci < total_len and cur[ci] != ' ':
|
||||
ci += 1
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 查找 from-import 名称 → 返回模块名或 None
|
||||
#
|
||||
@@ -150,7 +230,7 @@ def lookup_from_import(from_imports: str, name: str,
|
||||
if entry_name_len == 1 and cur[ci] == '*':
|
||||
mod_start: t.CSizeT = colon_pos + 1
|
||||
mod_end: t.CSizeT = mod_start
|
||||
while mod_end < total_len and cur[mod_end] != ' ' and cur[mod_end] != '\0':
|
||||
while mod_end < total_len and cur[mod_end] != ' ' and cur[mod_end] != '\0' and cur[mod_end] != ':':
|
||||
mod_end += 1
|
||||
star_mod = cur + mod_start
|
||||
# 比较名称
|
||||
@@ -165,7 +245,8 @@ def lookup_from_import(from_imports: str, name: str,
|
||||
if match == 1:
|
||||
mod_start2: t.CSizeT = colon_pos + 1
|
||||
mod_end2: t.CSizeT = mod_start2
|
||||
while mod_end2 < total_len and cur[mod_end2] != ' ' and cur[mod_end2] != '\0':
|
||||
# 模块名结束于: 空格、null、或第二个':'(别名格式的分隔符)
|
||||
while mod_end2 < total_len and cur[mod_end2] != ' ' and cur[mod_end2] != '\0' and cur[mod_end2] != ':':
|
||||
mod_end2 += 1
|
||||
return cur + mod_start2
|
||||
# 跳到下一个条目
|
||||
@@ -178,6 +259,93 @@ def lookup_from_import(from_imports: str, name: str,
|
||||
return star_mod
|
||||
|
||||
|
||||
# ============================================================
|
||||
# 全局 re-export 映射表(module_sha1 + func_name → source_module)
|
||||
#
|
||||
# 当 ast/__init__.py 中有 from .lexer import _lexer_init 时,
|
||||
# _lexer_init 被 re-export 为 ast._lexer_init。
|
||||
# 跨模块调用 ast._lexer_init(...) 需使用 ast.lexer 的 SHA1 混淆,
|
||||
# 而非 ast 的 SHA1。
|
||||
#
|
||||
# 数据布局:
|
||||
# _g_reexport_sha1s: 每条 17 字节(SHA1 16字符 + null)
|
||||
# _g_reexport_funcs: 每条 64 字节(函数名 + null)
|
||||
# _g_reexport_srcs: 每条 64 字节(源模块名 + null)
|
||||
# ============================================================
|
||||
MAX_REEXPORT: t.CDefine = 512
|
||||
|
||||
_g_reexport_sha1s: bytes = None
|
||||
_g_reexport_funcs: bytes = None
|
||||
_g_reexport_srcs: bytes = None
|
||||
_g_reexport_count: int = 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# register_reexport - 注册 re-export 映射
|
||||
#
|
||||
# 在 HandleImportFromNames 中调用:当处理 from .X import Y 时,
|
||||
# 记录当前模块(通过 ModuleSha1)re-export 了函数 Y,源模块为 X。
|
||||
#
|
||||
# 幂等:重复注册相同映射不会增加条目。
|
||||
# 内存用 stdlib.malloc 分配(全局存储器,跨 Phase 持久化)。
|
||||
# ============================================================
|
||||
def register_reexport(mod_sha1: str, func_name: str, source_module: str) -> int:
|
||||
"""注册 re-export 映射(幂等),返回 0 成功,-1 失败"""
|
||||
global _g_reexport_sha1s, _g_reexport_funcs, _g_reexport_srcs, _g_reexport_count
|
||||
if mod_sha1 is None or func_name is None or source_module is None:
|
||||
return -1
|
||||
# 懒初始化
|
||||
if _g_reexport_sha1s is None:
|
||||
_g_reexport_sha1s = stdlib.malloc(MAX_REEXPORT * 17)
|
||||
_g_reexport_funcs = stdlib.malloc(MAX_REEXPORT * 64)
|
||||
_g_reexport_srcs = stdlib.malloc(MAX_REEXPORT * 64)
|
||||
if _g_reexport_sha1s is None or _g_reexport_funcs is None or _g_reexport_srcs is None:
|
||||
return -1
|
||||
string.memset(_g_reexport_sha1s, 0, MAX_REEXPORT * 17)
|
||||
string.memset(_g_reexport_funcs, 0, MAX_REEXPORT * 64)
|
||||
string.memset(_g_reexport_srcs, 0, MAX_REEXPORT * 64)
|
||||
if _g_reexport_count >= MAX_REEXPORT:
|
||||
return -1
|
||||
# 幂等检查:查找是否已存在相同映射
|
||||
for i in range(_g_reexport_count):
|
||||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||||
fidx: t.CSizeT = t.CSizeT(i) * 64
|
||||
if string.strcmp(_g_reexport_sha1s + sidx, mod_sha1) == 0:
|
||||
if string.strcmp(_g_reexport_funcs + fidx, func_name) == 0:
|
||||
# 已存在,更新 source_module(以防变化)
|
||||
string.strcpy(_g_reexport_srcs + fidx, source_module)
|
||||
return 0
|
||||
# 添加新条目
|
||||
idx2: t.CSizeT = t.CSizeT(_g_reexport_count) * 17
|
||||
fidx2: t.CSizeT = t.CSizeT(_g_reexport_count) * 64
|
||||
string.strcpy(_g_reexport_sha1s + idx2, mod_sha1)
|
||||
string.strcpy(_g_reexport_funcs + fidx2, func_name)
|
||||
string.strcpy(_g_reexport_srcs + fidx2, source_module)
|
||||
_g_reexport_count += 1
|
||||
return 0
|
||||
|
||||
|
||||
# ============================================================
|
||||
# lookup_reexport - 查找 re-export 映射
|
||||
#
|
||||
# 给定模块 SHA1 和函数名,返回源模块名(如 "ast.lexer")或 None。
|
||||
# 调用方通过 _lookup_module_sha1(source_module) 获取源模块的 SHA1。
|
||||
# ============================================================
|
||||
def lookup_reexport(mod_sha1: str, func_name: str) -> str:
|
||||
"""查找 re-export 映射,返回源模块名或 None"""
|
||||
if mod_sha1 is None or func_name is None:
|
||||
return None
|
||||
if _g_reexport_sha1s is None or _g_reexport_count <= 0:
|
||||
return None
|
||||
for i in range(_g_reexport_count):
|
||||
sidx: t.CSizeT = t.CSizeT(i) * 17
|
||||
fidx: t.CSizeT = t.CSizeT(i) * 64
|
||||
if string.strcmp(_g_reexport_sha1s + sidx, mod_sha1) == 0:
|
||||
if string.strcmp(_g_reexport_funcs + fidx, func_name) == 0:
|
||||
return _g_reexport_srcs + fidx
|
||||
return None
|
||||
|
||||
|
||||
# ============================================================
|
||||
# _resolve_relative_module - 解析相对导入为完整模块名
|
||||
#
|
||||
@@ -335,6 +503,24 @@ class ImportsHandle(HandlesBase.Mixin):
|
||||
if alias.asname is not None:
|
||||
self.Trans._imported_modules = add_imported_module(
|
||||
pool_val, self.Trans._imported_modules, alias.asname)
|
||||
# 别名也加入 from_imports(asname:fullname),
|
||||
# 使 HT.func() 跨模块调用能通过 from_imports 查找别名→完整模块名→SHA1
|
||||
# 否则 _lookup_module_sha1("HT") 找不到(mod_arr 只存文件名 HandlesTranslator)
|
||||
self.Trans._from_imports = add_from_import(
|
||||
pool_val, self.Trans._from_imports, alias.asname, alias.name)
|
||||
else:
|
||||
# 无别名时(import a.b.c),将顶层包名 "a" 也加入 _imported_modules,
|
||||
# 使 a.b.c 作为属性访问的 base 被翻译时能通过 is_module_imported("a") 检查
|
||||
dot_ptr: str = string.strstr(alias.name, '.')
|
||||
if dot_ptr is not None:
|
||||
pkg_len: t.CSizeT = t.CSizeT(t.CUInt64T(dot_ptr) - t.CUInt64T(alias.name))
|
||||
if pkg_len > 0 and pkg_len < 256:
|
||||
pkg_buf: bytes = pool_val.alloc(pkg_len + 1)
|
||||
if pkg_buf is not None:
|
||||
string.strncpy(pkg_buf, alias.name, pkg_len)
|
||||
pkg_buf[pkg_len] = '\0'
|
||||
self.Trans._imported_modules = add_imported_module(
|
||||
pool_val, self.Trans._imported_modules, pkg_buf)
|
||||
return 0
|
||||
|
||||
# ============================================================
|
||||
@@ -381,13 +567,19 @@ class ImportsHandle(HandlesBase.Mixin):
|
||||
alias: ast.Alias | t.CPtr = (ast.Alias | t.CPtr)(names.get(ni))
|
||||
if alias is not None and alias.name is not None:
|
||||
local_name: str = alias.name
|
||||
orig_name: str = None
|
||||
if alias.asname is not None:
|
||||
local_name = alias.asname
|
||||
orig_name = alias.name
|
||||
self.Trans._from_imports = add_from_import(
|
||||
self.Trans.Pool, self.Trans._from_imports,
|
||||
local_name, resolved)
|
||||
local_name, resolved, orig_name)
|
||||
# 命名空间隔离:from-import 的名称标记为可见结构体
|
||||
HandlesStruct.add_visible_struct(self.Trans.Pool, local_name)
|
||||
# 注册 re-export 映射:当前模块 re-export 了 local_name,源模块为 resolved
|
||||
# 使跨模块调用 module.func() 能解析到正确的源模块 SHA1
|
||||
if self.Trans.ModuleSha1 is not None:
|
||||
register_reexport(self.Trans.ModuleSha1, local_name, resolved)
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user