cpyte 4.3.0__tar.gz → 4.3.2__tar.gz
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.
- {cpyte-4.3.0/source/cpyte.egg-info → cpyte-4.3.2}/PKG-INFO +1 -1
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/__init__.py +1 -1
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/bytecoding.py +10 -19
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/compiling.py +48 -21
- cpyte-4.3.2/source/cpyte/elf2sef.py +832 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/mainpie.py +192 -13
- cpyte-4.3.2/source/cpyte/mksef.py +134 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/sef.py +310 -21
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/semantic_analasis.py +7 -9
- {cpyte-4.3.0 → cpyte-4.3.2/source/cpyte.egg-info}/PKG-INFO +1 -1
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte.egg-info/SOURCES.txt +4 -1
- cpyte-4.3.2/test/test_sef_tools.py +221 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/MANIFEST.in +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/pyproject.toml +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/readme.md +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/setup.cfg +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/__main__.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/_bignum_bc.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/_runtime_bc.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/astparse.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/bignum.c +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/clib.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/extension_hooks.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/formatter.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/gc_runtime.c +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/generate_bc.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/lexar.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/linker.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/lsp_server.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/optimizations.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/package_manifest.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/runtime.c +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/runtime_scorpion.c +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/ugc.h +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/ui.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/update_check.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/winjit_patch.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte/winjit_stubs.c +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte.egg-info/dependency_links.txt +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte.egg-info/entry_points.txt +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte.egg-info/requires.txt +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/source/cpyte.egg-info/top_level.txt +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/test/test_bignum_jit.py +0 -0
- {cpyte-4.3.0 → cpyte-4.3.2}/test/test_fuzz_del_has.py +0 -0
|
@@ -2,7 +2,7 @@ import hashlib
|
|
|
2
2
|
import hmac
|
|
3
3
|
import os
|
|
4
4
|
from traceback import print_exception
|
|
5
|
-
from typing import Any,
|
|
5
|
+
from typing import Any, Protocol
|
|
6
6
|
|
|
7
7
|
from llvmlite import binding, ir
|
|
8
8
|
from llvmlite.ir import instructions
|
|
@@ -253,9 +253,7 @@ class LLVM:
|
|
|
253
253
|
t = _bc_array_norm(t)
|
|
254
254
|
if t == "int":
|
|
255
255
|
result = ir.IntType(32)
|
|
256
|
-
elif t == "int64":
|
|
257
|
-
result = ir.IntType(64)
|
|
258
|
-
elif t == "uint64":
|
|
256
|
+
elif t == "int64" or t == "uint64":
|
|
259
257
|
result = ir.IntType(64)
|
|
260
258
|
elif t == "size_t":
|
|
261
259
|
# Pointer-sized unsigned integer (i64 on every 64-bit cpyte target,
|
|
@@ -273,11 +271,7 @@ class LLVM:
|
|
|
273
271
|
result = ir.PointerType(ir.IntType(8))
|
|
274
272
|
elif t == "char":
|
|
275
273
|
result = ir.IntType(8)
|
|
276
|
-
elif t == "void*":
|
|
277
|
-
result = ir.PointerType(ir.IntType(8))
|
|
278
|
-
elif t == "big":
|
|
279
|
-
result = ir.PointerType(ir.IntType(8))
|
|
280
|
-
elif t == "ubig":
|
|
274
|
+
elif t == "void*" or t == "big" or t == "ubig":
|
|
281
275
|
result = ir.PointerType(ir.IntType(8))
|
|
282
276
|
elif t == "dynamic":
|
|
283
277
|
# A runtime-typed value: (kind, data) tag pair. Mirrors DynValue.
|
|
@@ -288,10 +282,7 @@ class LLVM:
|
|
|
288
282
|
elif t.endswith("[]"):
|
|
289
283
|
base = self.llvm_type(t[:-2])
|
|
290
284
|
result = ir.PointerType(base)
|
|
291
|
-
elif t.endswith("*"):
|
|
292
|
-
base = self.llvm_type(t[:-1])
|
|
293
|
-
result = ir.PointerType(base)
|
|
294
|
-
elif t.endswith("&"):
|
|
285
|
+
elif t.endswith("*") or t.endswith("&"):
|
|
295
286
|
base = self.llvm_type(t[:-1])
|
|
296
287
|
result = ir.PointerType(base)
|
|
297
288
|
elif t in self.structs:
|
|
@@ -1656,7 +1647,7 @@ class LLVM:
|
|
|
1656
1647
|
for table in (self.locals, self.local_types, self.ssa_values):
|
|
1657
1648
|
table.pop(name, None)
|
|
1658
1649
|
self.const_vars.pop(name, None)
|
|
1659
|
-
return
|
|
1650
|
+
return
|
|
1660
1651
|
if kind == "dynamic":
|
|
1661
1652
|
name = target.name
|
|
1662
1653
|
if name in self.locals and getattr(
|
|
@@ -1679,15 +1670,15 @@ class LLVM:
|
|
|
1679
1670
|
ir.Constant(_i64, 0),
|
|
1680
1671
|
],
|
|
1681
1672
|
)
|
|
1682
|
-
return
|
|
1673
|
+
return
|
|
1683
1674
|
if kind == "heap":
|
|
1684
1675
|
self._emit_builtin_free(target)
|
|
1685
|
-
return
|
|
1676
|
+
return
|
|
1686
1677
|
if kind == "slot":
|
|
1687
1678
|
slot = self._emit_lvalue(target)
|
|
1688
1679
|
if isinstance(slot.type, ir.PointerType) and slot.type.pointee is not None:
|
|
1689
1680
|
self.builder.store(ir.Constant(slot.type.pointee, None), slot)
|
|
1690
|
-
return
|
|
1681
|
+
return
|
|
1691
1682
|
raise Exception(
|
|
1692
1683
|
f"unhandled del_kind {kind!r} at L{node._token.line}:{node._token.column}"
|
|
1693
1684
|
)
|
|
@@ -6409,7 +6400,7 @@ class LLVM:
|
|
|
6409
6400
|
slot = self._emit_lvalue(target)
|
|
6410
6401
|
cur = self.builder.load(slot, "append.cur")
|
|
6411
6402
|
|
|
6412
|
-
elem_t = arr_t
|
|
6403
|
+
elem_t = arr_t.removesuffix("[]")
|
|
6413
6404
|
if arr_t == "dynamic":
|
|
6414
6405
|
# Element slot holds a DynValue; its i64 data is the inner list ptr.
|
|
6415
6406
|
elem_llvm = _DynValue
|
|
@@ -6778,7 +6769,7 @@ class LLVM:
|
|
|
6778
6769
|
def _is_const_var(self, name: str) -> bool:
|
|
6779
6770
|
return name in self._const_prop
|
|
6780
6771
|
|
|
6781
|
-
def _const_var_value(self, name: str) ->
|
|
6772
|
+
def _const_var_value(self, name: str) -> int | None:
|
|
6782
6773
|
return self._const_prop.get(name)
|
|
6783
6774
|
|
|
6784
6775
|
def _try_unroll_counted_loop(self, node: While, pending_ivs: dict) -> bool:
|
|
@@ -1806,8 +1806,33 @@ def _find_scorpion_tool(name, fallback):
|
|
|
1806
1806
|
return fallback
|
|
1807
1807
|
|
|
1808
1808
|
|
|
1809
|
+
def _scorpion_tool(name):
|
|
1810
|
+
"""Locate a bundled Scorpion converter script (elf2sef.py / mksef.py).
|
|
1811
|
+
|
|
1812
|
+
Prefers the copy shipped inside the cpyte package so the installed wheel
|
|
1813
|
+
works standalone; falls back to the WEW-scorpion sibling checkout for
|
|
1814
|
+
source-tree development.
|
|
1815
|
+
"""
|
|
1816
|
+
bundled = os.path.join(os.path.dirname(__file__), name)
|
|
1817
|
+
if os.path.isfile(bundled):
|
|
1818
|
+
return bundled
|
|
1819
|
+
sibling = os.path.join(
|
|
1820
|
+
os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(_RUNTIME_SCORPION_C)))),
|
|
1821
|
+
"WEW-scorpion",
|
|
1822
|
+
"tools" if name == "elf2sef.py" else "user",
|
|
1823
|
+
name,
|
|
1824
|
+
)
|
|
1825
|
+
return sibling
|
|
1826
|
+
|
|
1827
|
+
|
|
1809
1828
|
def run_scorpion(
|
|
1810
|
-
module,
|
|
1829
|
+
module,
|
|
1830
|
+
output="program.sef",
|
|
1831
|
+
opt_level=3,
|
|
1832
|
+
src_files=None,
|
|
1833
|
+
pic=False,
|
|
1834
|
+
exports=None,
|
|
1835
|
+
auto_exports=None,
|
|
1811
1836
|
):
|
|
1812
1837
|
"""Compile a Cpyte module for Scorpion (RV32 bare-metal) producing a SEF file.
|
|
1813
1838
|
Please use it good! :):)
|
|
@@ -1815,7 +1840,11 @@ def run_scorpion(
|
|
|
1815
1840
|
With pic=True the module is compiled with -fPIC and the final ELF is linked
|
|
1816
1841
|
with --emit-relocs so it can be converted to a dynamic (SEF v2) image via
|
|
1817
1842
|
WEW-scorpion/tools/elf2sef.py. `exports` names the symbols to mark as
|
|
1818
|
-
exported for dynamic linking (libraries).
|
|
1843
|
+
exported for dynamic linking (libraries). `auto_exports` are additional
|
|
1844
|
+
candidates discovered automatically (top-level `public` functions); only
|
|
1845
|
+
those that actually resolve to a defined symbol in the emitted module are
|
|
1846
|
+
added (elf2sef refuses unknown names). Returns (elf_file, [final exports])
|
|
1847
|
+
so callers can report exactly what was published.
|
|
1819
1848
|
"""
|
|
1820
1849
|
from llvmlite import binding
|
|
1821
1850
|
|
|
@@ -1829,6 +1858,18 @@ def run_scorpion(
|
|
|
1829
1858
|
optimize(mod, opt_level)
|
|
1830
1859
|
mod.verify()
|
|
1831
1860
|
|
|
1861
|
+
defined = {
|
|
1862
|
+
f.name for f in mod.functions if not getattr(f, "is_declaration", True)
|
|
1863
|
+
}
|
|
1864
|
+
final_exports = list(exports or [])
|
|
1865
|
+
seen = set(final_exports)
|
|
1866
|
+
if auto_exports:
|
|
1867
|
+
for name in auto_exports:
|
|
1868
|
+
if name in seen or name not in defined:
|
|
1869
|
+
continue
|
|
1870
|
+
seen.add(name)
|
|
1871
|
+
final_exports.append(name)
|
|
1872
|
+
|
|
1832
1873
|
target = binding.Target.from_triple("riscv32-unknown-elf")
|
|
1833
1874
|
if pic:
|
|
1834
1875
|
target_machine = target.create_target_machine(reloc="pic")
|
|
@@ -1895,17 +1936,10 @@ def run_scorpion(
|
|
|
1895
1936
|
|
|
1896
1937
|
if pic:
|
|
1897
1938
|
# Dynamic SEF v2: relocation + import/export records
|
|
1898
|
-
elf2sef =
|
|
1899
|
-
os.path.dirname(os.path.dirname(_RUNTIME_SCORPION_C)),
|
|
1900
|
-
"..",
|
|
1901
|
-
"..",
|
|
1902
|
-
"WEW-scorpion",
|
|
1903
|
-
"tools",
|
|
1904
|
-
"elf2sef.py",
|
|
1905
|
-
)
|
|
1939
|
+
elf2sef = _scorpion_tool("elf2sef.py")
|
|
1906
1940
|
cmd = [sys.executable, elf2sef, elf_file, output]
|
|
1907
|
-
if
|
|
1908
|
-
for name in
|
|
1941
|
+
if final_exports:
|
|
1942
|
+
for name in final_exports:
|
|
1909
1943
|
cmd += ["--export", name]
|
|
1910
1944
|
r = subprocess.run(cmd, capture_output=True, text=True)
|
|
1911
1945
|
if r.returncode != 0:
|
|
@@ -1913,14 +1947,7 @@ def run_scorpion(
|
|
|
1913
1947
|
raise SystemExit(1)
|
|
1914
1948
|
else:
|
|
1915
1949
|
# Static SEF v1 via mksef.py
|
|
1916
|
-
mksef =
|
|
1917
|
-
os.path.dirname(os.path.dirname(_RUNTIME_SCORPION_C)),
|
|
1918
|
-
"..",
|
|
1919
|
-
"..",
|
|
1920
|
-
"WEW-scorpion",
|
|
1921
|
-
"user",
|
|
1922
|
-
"mksef.py",
|
|
1923
|
-
)
|
|
1950
|
+
mksef = _scorpion_tool("mksef.py")
|
|
1924
1951
|
if not os.path.isfile(mksef):
|
|
1925
1952
|
# Fallback: inline SEF generation using objdump/objcopy
|
|
1926
1953
|
_elf_to_sef(elf_file, output, 0)
|
|
@@ -1935,7 +1962,7 @@ def run_scorpion(
|
|
|
1935
1962
|
raise SystemExit(1)
|
|
1936
1963
|
|
|
1937
1964
|
print_ok(f"Wrote {os.path.getsize(output)} bytes to {output}")
|
|
1938
|
-
return elf_file
|
|
1965
|
+
return elf_file, final_exports
|
|
1939
1966
|
|
|
1940
1967
|
|
|
1941
1968
|
def _elf_to_sef(elf_path, sef_output, flags=0):
|