l0n0lc 0.8.4__py3-none-any.whl → 1.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- l0n0lc/Py/350/275/254Cpp/350/275/254/350/257/221/345/231/250.py +579 -0
- l0n0lc/__init__.py +75 -6
- l0n0lc/aot/347/274/226/350/257/221.py +679 -0
- l0n0lc/ast/350/256/277/351/227/256/350/200/205.py +599 -0
- l0n0lc/cpp/347/261/273/345/236/213.py +330 -0
- l0n0lc/cpp/347/274/226/350/257/221/345/231/250.py +317 -0
- l0n0lc/simd/344/274/230/345/214/226.py +260 -0
- l0n0lc/std_map.py +153 -0
- l0n0lc/std_set.py +185 -0
- l0n0lc/std_vector.py +96 -0
- l0n0lc//344/273/243/347/240/201/344/274/230/345/214/226.py +302 -0
- l0n0lc//344/273/243/347/240/201/347/224/237/346/210/220.py +546 -0
- l0n0lc//344/276/235/350/265/226/346/263/250/345/205/245.py +155 -0
- l0n0lc//345/215/263/346/227/266/347/274/226/350/257/221.py +192 -0
- l0n0lc//345/217/230/351/207/217/347/256/241/347/220/206/345/231/250.py +123 -0
- l0n0lc//345/237/272/347/241/200/346/230/240/345/260/204.py +103 -0
- l0n0lc//345/237/272/347/241/200/346/267/267/345/205/245.py +147 -0
- l0n0lc//345/256/271/345/231/250/346/236/204/345/273/272/345/231/250.py +214 -0
- l0n0lc//345/267/245/345/205/267.py +285 -0
- l0n0lc//345/271/266/350/241/214/347/274/226/350/257/221/345/231/250.py +412 -0
- l0n0lc//345/274/202/345/270/270.py +474 -0
- l0n0lc//346/225/260/347/273/204/345/257/271/350/261/241/346/261/240.py +248 -0
- l0n0lc//346/226/207/344/273/266/347/256/241/347/220/206/345/231/250.py +286 -0
- l0n0lc//346/227/245/345/277/227/345/267/245/345/205/267.py +152 -0
- l0n0lc//347/261/273/345/236/213/346/216/250/346/226/255/345/267/245/345/205/267.py +352 -0
- l0n0lc//347/261/273/345/236/213/350/275/254/346/215/242.py +210 -0
- l0n0lc//347/261/273/346/224/257/346/214/201.py +372 -0
- l0n0lc//347/274/226/350/257/221/344/270/212/344/270/213/346/226/207.py +132 -0
- l0n0lc//347/274/226/350/257/221/347/256/241/347/220/206/345/231/250.py +171 -0
- l0n0lc//350/241/250/350/276/276/345/274/217/345/244/204/347/220/206.py +462 -0
- l0n0lc//350/275/254/350/257/221/345/231/250/345/267/245/345/205/267.py +49 -0
- l0n0lc//350/277/220/350/241/214/346/227/266/345/212/240/350/275/275.py +217 -0
- l0n0lc//351/200/232/347/224/250/345/267/245/345/205/267.py +149 -0
- l0n0lc-1.0.0.dist-info/METADATA +363 -0
- l0n0lc-1.0.0.dist-info/RECORD +39 -0
- {l0n0lc-0.8.4.dist-info → l0n0lc-1.0.0.dist-info}/WHEEL +1 -1
- l0n0lc-1.0.0.dist-info/entry_points.txt +2 -0
- {l0n0lc-0.8.4.dist-info → l0n0lc-1.0.0.dist-info}/licenses/LICENSE +0 -0
- l0n0lc/StdList.py +0 -24
- l0n0lc/StdMap.py +0 -21
- l0n0lc/c/345/237/272/347/241/200/345/244/204/347/220/206.py +0 -207
- l0n0lc/jit.py +0 -604
- l0n0lc//347/274/226/350/257/221.py +0 -58
- l0n0lc//351/200/232/347/224/250.py +0 -134
- l0n0lc-0.8.4.dist-info/METADATA +0 -241
- l0n0lc-0.8.4.dist-info/RECORD +0 -12
- {l0n0lc-0.8.4.dist-info → l0n0lc-1.0.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
import ctypes
|
|
2
|
+
from typing import Tuple, Any, Optional
|
|
3
|
+
import sys
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
# 安全限制配置
|
|
7
|
+
MAX_ARRAY_SIZE = 10**6 # 最大数组大小
|
|
8
|
+
MAX_NESTING_DEPTH = 100 # 最大嵌套深度
|
|
9
|
+
|
|
10
|
+
# 导入对象池
|
|
11
|
+
from .数组对象池 import 获取全局对象池, 获取全局池统计, 数组对象池
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class 运行时加载器:
|
|
15
|
+
"""处理编译后库的加载和调用"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, transpiler):
|
|
18
|
+
self.transpiler = transpiler
|
|
19
|
+
|
|
20
|
+
def 递归加载依赖(self, transpiler, loaded_deps, depth=0):
|
|
21
|
+
"""递归加载所有依赖的类库"""
|
|
22
|
+
# 检查嵌套深度,防止无限递归
|
|
23
|
+
if depth > MAX_NESTING_DEPTH:
|
|
24
|
+
raise RuntimeError(f"依赖嵌套深度超过限制 {MAX_NESTING_DEPTH}")
|
|
25
|
+
|
|
26
|
+
for dep in transpiler.依赖函数:
|
|
27
|
+
if dep in loaded_deps:
|
|
28
|
+
continue
|
|
29
|
+
|
|
30
|
+
# 验证依赖对象
|
|
31
|
+
if not hasattr(dep, '是否为类') or not hasattr(dep, '获取库文件名'):
|
|
32
|
+
raise ValueError(f"无效的依赖对象: {dep}")
|
|
33
|
+
|
|
34
|
+
loaded_deps.add(dep)
|
|
35
|
+
|
|
36
|
+
if dep.是否为类:
|
|
37
|
+
# 递归加载依赖的依赖
|
|
38
|
+
self.递归加载依赖(dep, loaded_deps, depth + 1)
|
|
39
|
+
# 加载当前依赖的库
|
|
40
|
+
dep_lib_path = dep.文件管理器.获取完整路径(dep.获取库文件名())
|
|
41
|
+
|
|
42
|
+
# 验证库文件路径
|
|
43
|
+
if not os.path.exists(dep_lib_path):
|
|
44
|
+
raise FileNotFoundError(f"依赖库文件不存在: {dep_lib_path}")
|
|
45
|
+
|
|
46
|
+
ctypes.CDLL(dep_lib_path, mode=ctypes.RTLD_GLOBAL)
|
|
47
|
+
|
|
48
|
+
def 加载库(self):
|
|
49
|
+
"""加载编译好的动态库(直接设置到转译器实例)"""
|
|
50
|
+
if self.transpiler.可执行文件名:
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
# 递归加载所有依赖的类库
|
|
54
|
+
loaded_deps = set()
|
|
55
|
+
self.递归加载依赖(self.transpiler, loaded_deps)
|
|
56
|
+
|
|
57
|
+
# 加载主库
|
|
58
|
+
lib_path = self.transpiler.文件管理器.获取完整路径(self.transpiler.获取库文件名())
|
|
59
|
+
|
|
60
|
+
# 如果是类,只加载库到全局命名空间,不获取函数符号
|
|
61
|
+
self.transpiler.目标库 = ctypes.CDLL(lib_path, mode=ctypes.RTLD_GLOBAL)
|
|
62
|
+
if self.transpiler.是否为类:
|
|
63
|
+
# 类只需要加载库,使符号对其他编译单元可见
|
|
64
|
+
self.transpiler.cpp函数 = None
|
|
65
|
+
else:
|
|
66
|
+
# 普通函数需要获取函数符号
|
|
67
|
+
self.transpiler.cpp函数 = self.transpiler.目标库[self.transpiler.C函数名]
|
|
68
|
+
self.transpiler.cpp函数.argtypes = self.transpiler.ctypes参数类型
|
|
69
|
+
self.transpiler.cpp函数.restype = self.transpiler.ctypes返回类型
|
|
70
|
+
|
|
71
|
+
def 处理参数转换(self, args: tuple) -> Tuple[list, list, list]:
|
|
72
|
+
"""
|
|
73
|
+
处理参数转换,特别是列表参数的拆分
|
|
74
|
+
|
|
75
|
+
优化说明:
|
|
76
|
+
- 使用对象池复用 ctypes 数组,减少内存分配
|
|
77
|
+
- 使用 memcpy 快速复制数据(避免逐元素赋值)
|
|
78
|
+
- 支持零拷贝(当输入已经是 ctypes 数组时)
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
(转换后的参数列表, 需要保持的引用列表, 需要释放的数组信息列表)
|
|
82
|
+
释放信息格式: [(数组, 元素类型, 大小), ...]
|
|
83
|
+
"""
|
|
84
|
+
new_args = []
|
|
85
|
+
keep_alive = []
|
|
86
|
+
to_release = [] # 需要释放回池的数组信息
|
|
87
|
+
pool = 获取全局对象池()
|
|
88
|
+
|
|
89
|
+
if not self.transpiler.列表参数映射:
|
|
90
|
+
# 没有列表参数,直接返回
|
|
91
|
+
return list(args), [], []
|
|
92
|
+
|
|
93
|
+
# 遍历预期参数 (按名称)
|
|
94
|
+
param_names = list(self.transpiler.参数变量.keys())
|
|
95
|
+
arg_idx = 0
|
|
96
|
+
|
|
97
|
+
for i, arg in enumerate(args):
|
|
98
|
+
if i >= len(param_names):
|
|
99
|
+
break
|
|
100
|
+
|
|
101
|
+
param_name = param_names[i]
|
|
102
|
+
|
|
103
|
+
if param_name in self.transpiler.列表参数映射:
|
|
104
|
+
if not isinstance(arg, (list, tuple)):
|
|
105
|
+
raise TypeError(
|
|
106
|
+
f"Argument '{param_name}' expected list, got {type(arg)}"
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
length = len(arg)
|
|
110
|
+
|
|
111
|
+
# 检查数组大小限制
|
|
112
|
+
if length > MAX_ARRAY_SIZE:
|
|
113
|
+
raise ValueError(
|
|
114
|
+
f"参数 '{param_name}' 的数组大小 {length} 超过限制 {MAX_ARRAY_SIZE}"
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# 空数组是允许的
|
|
118
|
+
if length == 0:
|
|
119
|
+
pointer_type = self.transpiler.ctypes参数类型[arg_idx]
|
|
120
|
+
array_type = pointer_type._type_ * 0
|
|
121
|
+
c_array = array_type()
|
|
122
|
+
keep_alive.append(c_array)
|
|
123
|
+
new_args.append(c_array)
|
|
124
|
+
new_args.append(0)
|
|
125
|
+
arg_idx += 2
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
# ctypes参数类型[arg_idx] 是对应的指针类型
|
|
129
|
+
pointer_type = self.transpiler.ctypes参数类型[arg_idx]
|
|
130
|
+
element_type = pointer_type._type_
|
|
131
|
+
|
|
132
|
+
# 验证数组元素类型
|
|
133
|
+
for j, element in enumerate(arg):
|
|
134
|
+
if not isinstance(element, (int, float, str, bool)):
|
|
135
|
+
raise TypeError(
|
|
136
|
+
f"参数 '{param_name}' 的第 {j} 个元素类型不支持: {type(element)}"
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
# 尝试从对象池获取或分配新数组
|
|
140
|
+
c_array, from_pool = pool.获取或分配(element_type, length)
|
|
141
|
+
|
|
142
|
+
# 使用 memcpy 快速复制数据
|
|
143
|
+
try:
|
|
144
|
+
# 将 Python list 转为 ctypes 数组后复制
|
|
145
|
+
temp_array = (element_type * length)(*arg)
|
|
146
|
+
ctypes.memmove(ctypes.addressof(c_array), ctypes.addressof(temp_array), length * ctypes.sizeof(element_type))
|
|
147
|
+
except (TypeError, ValueError) as e:
|
|
148
|
+
raise ValueError(
|
|
149
|
+
f"无法为参数 '{param_name}' 创建C数组: {e}"
|
|
150
|
+
) from e
|
|
151
|
+
|
|
152
|
+
keep_alive.append(c_array)
|
|
153
|
+
to_release.append((c_array, element_type, length))
|
|
154
|
+
|
|
155
|
+
new_args.append(c_array)
|
|
156
|
+
new_args.append(length)
|
|
157
|
+
|
|
158
|
+
arg_idx += 2
|
|
159
|
+
else:
|
|
160
|
+
new_args.append(arg)
|
|
161
|
+
arg_idx += 1
|
|
162
|
+
|
|
163
|
+
return new_args, keep_alive, to_release
|
|
164
|
+
|
|
165
|
+
def 获取对象池(self) -> Optional[数组对象池]:
|
|
166
|
+
"""获取当前使用的对象池"""
|
|
167
|
+
return 获取全局对象池()
|
|
168
|
+
|
|
169
|
+
def 获取对象池统计(self):
|
|
170
|
+
"""获取对象池统计信息"""
|
|
171
|
+
return 获取全局池统计()
|
|
172
|
+
|
|
173
|
+
def 调用函数(self, *args, **kwargs):
|
|
174
|
+
"""调用编译后的函数"""
|
|
175
|
+
if self.transpiler.cpp函数 is None:
|
|
176
|
+
raise Exception(f"{self.transpiler.目标函数} cpp函数 is None!")
|
|
177
|
+
|
|
178
|
+
if self.transpiler.可执行文件名:
|
|
179
|
+
executable_path = self.transpiler.文件管理器.获取完整路径(self.transpiler.可执行文件名)
|
|
180
|
+
raise RuntimeError(
|
|
181
|
+
f"Cannot call executable directly. Run {executable_path}"
|
|
182
|
+
)
|
|
183
|
+
|
|
184
|
+
if self.transpiler.列表参数映射:
|
|
185
|
+
pool = 获取全局对象池()
|
|
186
|
+
new_args, keep_alive, to_release = self.处理参数转换(args)
|
|
187
|
+
try:
|
|
188
|
+
result = self.transpiler.cpp函数(*new_args)
|
|
189
|
+
finally:
|
|
190
|
+
# 释放数组回对象池
|
|
191
|
+
if pool.是否启用():
|
|
192
|
+
for arr, elem_type, size in to_release:
|
|
193
|
+
pool.释放(elem_type, size, arr)
|
|
194
|
+
return result
|
|
195
|
+
|
|
196
|
+
# 处理字符串参数转换
|
|
197
|
+
converted_args = []
|
|
198
|
+
for i, arg in enumerate(args):
|
|
199
|
+
# 检查对应的ctypes参数类型
|
|
200
|
+
if i < len(self.transpiler.ctypes参数类型):
|
|
201
|
+
expected_type = self.transpiler.ctypes参数类型[i]
|
|
202
|
+
# 如果期望的是c_char_p且参数是字符串,转换为字节
|
|
203
|
+
if expected_type == ctypes.c_char_p and isinstance(arg, str):
|
|
204
|
+
# UTF-8编码字节字符串
|
|
205
|
+
converted_args.append(arg.encode("utf-8"))
|
|
206
|
+
else:
|
|
207
|
+
converted_args.append(arg)
|
|
208
|
+
else:
|
|
209
|
+
converted_args.append(arg)
|
|
210
|
+
|
|
211
|
+
return self.transpiler.cpp函数(*converted_args)
|
|
212
|
+
|
|
213
|
+
def 获取函数地址(self):
|
|
214
|
+
"""获取编译后的函数地址(用于其他模块调用)"""
|
|
215
|
+
if self.transpiler.cpp函数 is None:
|
|
216
|
+
return None
|
|
217
|
+
return ctypes.cast(self.transpiler.cpp函数, ctypes.c_void_p).value
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"""
|
|
2
|
+
通用工具模块 - 提供统一的错误处理、类型解析和异常处理功能
|
|
3
|
+
用于消除代码中的重复逻辑
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import ast
|
|
7
|
+
import inspect
|
|
8
|
+
import traceback
|
|
9
|
+
from typing import Any, Union
|
|
10
|
+
from .异常 import Jit错误
|
|
11
|
+
from .工具 import 全局上下文
|
|
12
|
+
from .类型转换 import 类型转换器
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def 统一抛出错误(transpiler, message: str, node: Union[ast.stmt, ast.expr, ast.arg, ast.arguments]):
|
|
16
|
+
"""
|
|
17
|
+
统一的错误处理函数,消除22处重复的hasattr检查模式
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
transpiler: 转译器实例
|
|
21
|
+
message: 错误消息
|
|
22
|
+
node: AST节点,用于获取行号
|
|
23
|
+
"""
|
|
24
|
+
if hasattr(transpiler, '抛出错误'):
|
|
25
|
+
transpiler.抛出错误(message, node)
|
|
26
|
+
else:
|
|
27
|
+
line_no = getattr(node, "lineno", "?")
|
|
28
|
+
raise Jit错误(f"Line {line_no}: {message}")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def 解析自定义类型(py_type, transpiler) -> str:
|
|
32
|
+
"""
|
|
33
|
+
统一的类型解析逻辑,消除4处重复的类型映射处理
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
py_type: Python类型对象
|
|
37
|
+
transpiler: 转译器实例
|
|
38
|
+
|
|
39
|
+
Returns:
|
|
40
|
+
str: C++类型名称
|
|
41
|
+
"""
|
|
42
|
+
if inspect.isclass(py_type):
|
|
43
|
+
# 首先检查是否有类型映射
|
|
44
|
+
mapped_type = 全局上下文.类型映射表.get(py_type)
|
|
45
|
+
if mapped_type:
|
|
46
|
+
# 使用映射的类型
|
|
47
|
+
c_type = mapped_type.目标类型
|
|
48
|
+
# 添加需要包含的头文件
|
|
49
|
+
if mapped_type.包含目录:
|
|
50
|
+
if hasattr(transpiler, '包含头文件'):
|
|
51
|
+
transpiler.包含头文件.update(mapped_type.包含目录)
|
|
52
|
+
return c_type
|
|
53
|
+
elif py_type.__module__ == "builtins":
|
|
54
|
+
return 类型转换器.Python类型转C类型(py_type)
|
|
55
|
+
else:
|
|
56
|
+
# 用户自定义类
|
|
57
|
+
return py_type.__name__
|
|
58
|
+
|
|
59
|
+
return 类型转换器.Python类型转C类型(py_type)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def 统一异常处理(e: Exception, transpiler, node: Union[ast.stmt, ast.expr, ast.arg, ast.arguments], context_msg: str = ""):
|
|
63
|
+
"""
|
|
64
|
+
统一的异常处理逻辑,消除3处重复的异常+回溯处理模式
|
|
65
|
+
|
|
66
|
+
Args:
|
|
67
|
+
e: 异常对象
|
|
68
|
+
transpiler: 转译器实例
|
|
69
|
+
node: AST节点
|
|
70
|
+
context_msg: 上下文消息
|
|
71
|
+
"""
|
|
72
|
+
error_msg = f"{context_msg}: {str(e)}" if context_msg else str(e)
|
|
73
|
+
|
|
74
|
+
# 添加原始回溯信息
|
|
75
|
+
if traceback.format_exc():
|
|
76
|
+
error_msg += f"\nOriginal traceback:\n{traceback.format_exc()}"
|
|
77
|
+
|
|
78
|
+
统一抛出错误(transpiler, error_msg, node)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def 构建参数字符串(args: list, 获取值函数) -> str:
|
|
82
|
+
"""
|
|
83
|
+
统一的参数字符串构建逻辑
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
args: 参数列表
|
|
87
|
+
获取值函数: 用于获取参数值的函数
|
|
88
|
+
|
|
89
|
+
Returns:
|
|
90
|
+
str: 逗号分隔的参数字符串
|
|
91
|
+
"""
|
|
92
|
+
arg_list = [str(获取值函数(arg)) for arg in args]
|
|
93
|
+
return ",".join(arg_list)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def 处理函数参数(node_args, 获取值函数) -> list:
|
|
97
|
+
"""
|
|
98
|
+
统一的函数参数处理逻辑
|
|
99
|
+
|
|
100
|
+
Args:
|
|
101
|
+
node_args: AST参数节点
|
|
102
|
+
获取值函数: 用于获取参数值的函数
|
|
103
|
+
|
|
104
|
+
Returns:
|
|
105
|
+
list: 处理后的参数列表
|
|
106
|
+
"""
|
|
107
|
+
return [获取值函数(arg) for arg in node_args]
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def 生成函数调用(func_name: str, args_str: str):
|
|
111
|
+
"""
|
|
112
|
+
统一的函数调用生成逻辑
|
|
113
|
+
|
|
114
|
+
Args:
|
|
115
|
+
func_name: 函数名
|
|
116
|
+
args_str: 参数字符串
|
|
117
|
+
|
|
118
|
+
Returns:
|
|
119
|
+
C函数调用对象
|
|
120
|
+
"""
|
|
121
|
+
from .cpp类型 import C函数调用
|
|
122
|
+
return C函数调用(func_name, args_str)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def 验证AST节点类型(node, expected_type, transpiler, error_msg: str):
|
|
126
|
+
"""
|
|
127
|
+
统一的AST节点类型验证
|
|
128
|
+
|
|
129
|
+
Args:
|
|
130
|
+
node: AST节点
|
|
131
|
+
expected_type: 期望的类型
|
|
132
|
+
transpiler: 转译器实例
|
|
133
|
+
error_msg: 错误消息
|
|
134
|
+
"""
|
|
135
|
+
if not isinstance(node, expected_type):
|
|
136
|
+
统一抛出错误(transpiler, error_msg, node)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def 获取节点行号(node) -> str:
|
|
140
|
+
"""
|
|
141
|
+
统一的行号获取逻辑
|
|
142
|
+
|
|
143
|
+
Args:
|
|
144
|
+
node: AST节点
|
|
145
|
+
|
|
146
|
+
Returns:
|
|
147
|
+
str: 行号字符串
|
|
148
|
+
"""
|
|
149
|
+
return str(getattr(node, "lineno", "?"))
|