cpyte 4.2.4__tar.gz → 4.2.6__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.2.4/source/cpyte.egg-info → cpyte-4.2.6}/PKG-INFO +1 -1
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/__init__.py +1 -1
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/compiling.py +81 -1
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/gc_runtime.c +19 -19
- {cpyte-4.2.4 → cpyte-4.2.6/source/cpyte.egg-info}/PKG-INFO +1 -1
- {cpyte-4.2.4 → cpyte-4.2.6}/MANIFEST.in +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/pyproject.toml +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/readme.md +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/setup.cfg +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/__main__.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/_bignum_bc.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/_runtime_bc.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/astparse.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/bignum.c +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/bytecoding.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/clib.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/extension_hooks.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/formatter.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/generate_bc.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/lexar.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/linker.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/lsp_server.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/mainpie.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/optimizations.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/package_manifest.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/runtime.c +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/runtime_scorpion.c +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/sef.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/semantic_analasis.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/ugc.h +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/ui.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/update_check.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/winjit_patch.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte/winjit_stubs.c +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte.egg-info/SOURCES.txt +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte.egg-info/dependency_links.txt +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte.egg-info/entry_points.txt +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte.egg-info/requires.txt +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/source/cpyte.egg-info/top_level.txt +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/test/test_bignum_jit.py +0 -0
- {cpyte-4.2.4 → cpyte-4.2.6}/test/test_fuzz_del_has.py +0 -0
|
@@ -469,7 +469,18 @@ def _find_llvm_cc():
|
|
|
469
469
|
if exe:
|
|
470
470
|
try:
|
|
471
471
|
r = subprocess.run(
|
|
472
|
-
[
|
|
472
|
+
[
|
|
473
|
+
exe,
|
|
474
|
+
"-S",
|
|
475
|
+
"-emit-llvm",
|
|
476
|
+
"-O0",
|
|
477
|
+
"-target",
|
|
478
|
+
triple,
|
|
479
|
+
"-o",
|
|
480
|
+
"-",
|
|
481
|
+
"-xc",
|
|
482
|
+
"-",
|
|
483
|
+
],
|
|
473
484
|
input="int __x = 0;",
|
|
474
485
|
capture_output=True,
|
|
475
486
|
text=True,
|
|
@@ -545,6 +556,26 @@ def _load_libc():
|
|
|
545
556
|
|
|
546
557
|
|
|
547
558
|
_libc = _load_libc()
|
|
559
|
+
|
|
560
|
+
|
|
561
|
+
def _load_optional_lib(*names):
|
|
562
|
+
for _n in names:
|
|
563
|
+
if not _n:
|
|
564
|
+
continue
|
|
565
|
+
try:
|
|
566
|
+
return ctypes.CDLL(_n)
|
|
567
|
+
except OSError:
|
|
568
|
+
continue
|
|
569
|
+
return None
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
_libm = _load_optional_lib(
|
|
573
|
+
ctypes.util.find_library("m"), "libm.so.6", "/usr/lib/libm.so", "libm.dylib"
|
|
574
|
+
)
|
|
575
|
+
_libgcc = _load_optional_lib(
|
|
576
|
+
ctypes.util.find_library("gcc_s"), "libgcc_s.so.1", "/usr/lib/libgcc_s.so.1"
|
|
577
|
+
)
|
|
578
|
+
_process_libs = tuple(lib for lib in (_libc, _libm, _libgcc) if lib is not None)
|
|
548
579
|
_libc.strlen.argtypes = [ctypes.c_char_p]
|
|
549
580
|
_libc.strlen.restype = ctypes.c_int
|
|
550
581
|
_libc.memcpy.argtypes = [ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int]
|
|
@@ -1496,9 +1527,12 @@ def run_jit(
|
|
|
1496
1527
|
try:
|
|
1497
1528
|
fn = mod.get_function("strcmp")
|
|
1498
1529
|
engine.add_global_mapping(fn, _libc_addr("strcmp"))
|
|
1530
|
+
_explicit_mapped.add("strcmp")
|
|
1499
1531
|
except NameError:
|
|
1500
1532
|
pass
|
|
1501
1533
|
|
|
1534
|
+
_map_process_libc(engine, mod)
|
|
1535
|
+
|
|
1502
1536
|
engine.finalize_object()
|
|
1503
1537
|
if _use_windows_gnu():
|
|
1504
1538
|
externs = sorted(
|
|
@@ -1579,6 +1613,9 @@ def _libc_addr(name):
|
|
|
1579
1613
|
return ctypes.cast(getattr(_libc, name), ctypes.c_void_p).value
|
|
1580
1614
|
|
|
1581
1615
|
|
|
1616
|
+
_explicit_mapped = set()
|
|
1617
|
+
|
|
1618
|
+
|
|
1582
1619
|
def _map_libc_fn(engine, mod, name, argtype, restype, argtypes=None):
|
|
1583
1620
|
"""Map an external libc symbol in the JIT module to its raw native address.
|
|
1584
1621
|
|
|
@@ -1591,6 +1628,49 @@ def _map_libc_fn(engine, mod, name, argtype, restype, argtypes=None):
|
|
|
1591
1628
|
except NameError:
|
|
1592
1629
|
return
|
|
1593
1630
|
engine.add_global_mapping(fn, _libc_addr(name))
|
|
1631
|
+
_explicit_mapped.add(name)
|
|
1632
|
+
|
|
1633
|
+
|
|
1634
|
+
def _map_process_libc(engine, mod):
|
|
1635
|
+
"""Resolve every external C symbol the runtime/bignum helpers reference.
|
|
1636
|
+
|
|
1637
|
+
RuntimeDyld's in-process symbol lookup is unreliable on Linux: llvmlite
|
|
1638
|
+
returns a NULL address for libc functions (printf, fputs, putchar, ...),
|
|
1639
|
+
and MCJIT leaves an unresolved external at address 0. A runtime helper
|
|
1640
|
+
such as print_int (whose C body calls printf) then jumps to NULL and the
|
|
1641
|
+
process SIGSEGVs before producing any output. Map each external
|
|
1642
|
+
declaration we can find in the loaded C runtime / libm / process image to
|
|
1643
|
+
its real address. LLVM intrinsics (``llvm.*``) are lowered by the backend
|
|
1644
|
+
and are deliberately skipped.
|
|
1645
|
+
"""
|
|
1646
|
+
libs = list(_process_libs)
|
|
1647
|
+
try:
|
|
1648
|
+
libs.append(ctypes.CDLL(None))
|
|
1649
|
+
except OSError:
|
|
1650
|
+
pass
|
|
1651
|
+
mapped = set()
|
|
1652
|
+
for fn in mod.functions:
|
|
1653
|
+
if not fn.is_declaration:
|
|
1654
|
+
continue
|
|
1655
|
+
name = fn.name
|
|
1656
|
+
if name.startswith("llvm.") or name in mapped or name in _explicit_mapped:
|
|
1657
|
+
continue
|
|
1658
|
+
for lib in libs:
|
|
1659
|
+
try:
|
|
1660
|
+
sym = getattr(lib, name)
|
|
1661
|
+
except AttributeError:
|
|
1662
|
+
continue
|
|
1663
|
+
try:
|
|
1664
|
+
addr = ctypes.cast(sym, ctypes.c_void_p).value
|
|
1665
|
+
except (TypeError, ValueError):
|
|
1666
|
+
continue
|
|
1667
|
+
if addr:
|
|
1668
|
+
mapped.add(name)
|
|
1669
|
+
try:
|
|
1670
|
+
engine.add_global_mapping(fn, addr)
|
|
1671
|
+
except Exception:
|
|
1672
|
+
pass
|
|
1673
|
+
break
|
|
1594
1674
|
|
|
1595
1675
|
|
|
1596
1676
|
def run_aot(
|
|
@@ -115,16 +115,19 @@ typedef struct {
|
|
|
115
115
|
|
|
116
116
|
/* Thread-local storage for TLAB.
|
|
117
117
|
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
*
|
|
123
|
-
*
|
|
118
|
+
* Native TLS (`__declspec(thread)` / `__thread`) is avoided on every POSIX
|
|
119
|
+
* platform: the JIT path compiles this file to LLVM IR and emits a native
|
|
120
|
+
* object via llvmlite's MCJIT, and the compiler lowers native TLS to a
|
|
121
|
+
* `thread_local` LLVM global, which RuntimeDyld refuses to allocate
|
|
122
|
+
* (`LLVM ERROR: allocation of TLS not implemented`; on macOS arm64 it would
|
|
123
|
+
* also require the TLVP relocation ARM64_RELOC_TLVP_LOAD_PAGEOFF12). We back
|
|
124
|
+
* the per-thread TLAB with a pthread key instead, so the emitted object is
|
|
125
|
+
* TLS-free and each thread still gets its own buffer. Windows keeps native
|
|
126
|
+
* TLS (no POSIX threads available). */
|
|
124
127
|
#ifdef _WIN32
|
|
125
128
|
__declspec(thread) static tlab_t tlab = {NULL, NULL, NULL};
|
|
126
129
|
# define TLAB_GET() (&tlab)
|
|
127
|
-
#
|
|
130
|
+
#else
|
|
128
131
|
static pthread_key_t tlab_key;
|
|
129
132
|
static pthread_once_t tlab_key_once = PTHREAD_ONCE_INIT;
|
|
130
133
|
static void tlab_key_create(void) { pthread_key_create(&tlab_key, NULL); }
|
|
@@ -138,22 +141,19 @@ static tlab_t* tlab_get(void) {
|
|
|
138
141
|
return tl;
|
|
139
142
|
}
|
|
140
143
|
# define TLAB_GET() tlab_get()
|
|
141
|
-
#else
|
|
142
|
-
static __thread tlab_t tlab = {NULL, NULL, NULL};
|
|
143
|
-
# define TLAB_GET() (&tlab)
|
|
144
144
|
#endif
|
|
145
145
|
|
|
146
146
|
static void* tlab_alloc(size_t size) {
|
|
147
147
|
/* Round up to pointer alignment */
|
|
148
148
|
size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
|
|
149
|
-
|
|
149
|
+
|
|
150
150
|
if (TLAB_GET()->start == NULL || TLAB_GET()->current + size > TLAB_GET()->end) {
|
|
151
151
|
/* TLAB exhausted or not initialized: allocate new block from global heap */
|
|
152
152
|
size_t block_size = (size > TLAB_SIZE) ? size : TLAB_SIZE;
|
|
153
|
-
|
|
153
|
+
|
|
154
154
|
gc_lock_init();
|
|
155
155
|
CPY_MUTEX_LOCK(&gc_lock_);
|
|
156
|
-
|
|
156
|
+
|
|
157
157
|
/* Allocate the TLAB block through the normal GC path */
|
|
158
158
|
cpyte_obj_t* hdr = (cpyte_obj_t*)calloc(1, sizeof(cpyte_obj_t) + block_size);
|
|
159
159
|
if (hdr == NULL) {
|
|
@@ -163,14 +163,14 @@ static void* tlab_alloc(size_t size) {
|
|
|
163
163
|
hdr->size = block_size;
|
|
164
164
|
ugc_register(&gc, &hdr->base);
|
|
165
165
|
obj_track(hdr);
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
CPY_MUTEX_UNLOCK(&gc_lock_);
|
|
168
|
-
|
|
168
|
+
|
|
169
169
|
TLAB_GET()->start = PAYLOAD(hdr);
|
|
170
170
|
TLAB_GET()->end = TLAB_GET()->start + block_size;
|
|
171
171
|
TLAB_GET()->current = TLAB_GET()->start;
|
|
172
172
|
}
|
|
173
|
-
|
|
173
|
+
|
|
174
174
|
/* Bump-pointer allocation (lock-free) */
|
|
175
175
|
void *ptr = TLAB_GET()->current;
|
|
176
176
|
TLAB_GET()->current += size;
|
|
@@ -386,7 +386,7 @@ void gc_init(void) {
|
|
|
386
386
|
if (v > 0) gc_threshold = v;
|
|
387
387
|
}
|
|
388
388
|
}
|
|
389
|
-
|
|
389
|
+
|
|
390
390
|
/* Initialize TLAB for the current thread */
|
|
391
391
|
TLAB_GET()->start = NULL;
|
|
392
392
|
TLAB_GET()->end = NULL;
|
|
@@ -406,7 +406,7 @@ void* gc_malloc(size_t size) {
|
|
|
406
406
|
return ptr;
|
|
407
407
|
}
|
|
408
408
|
}
|
|
409
|
-
|
|
409
|
+
|
|
410
410
|
/* Fallback to global allocation for large objects or TLAB failure */
|
|
411
411
|
gc_lock_init();
|
|
412
412
|
CPY_MUTEX_LOCK(&gc_lock_);
|
|
@@ -540,7 +540,7 @@ void gc_shutdown(void) {
|
|
|
540
540
|
}
|
|
541
541
|
obj_table[i] = NULL;
|
|
542
542
|
}
|
|
543
|
-
|
|
543
|
+
|
|
544
544
|
/* Reset TLAB for current thread */
|
|
545
545
|
TLAB_GET()->start = NULL;
|
|
546
546
|
TLAB_GET()->end = NULL;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|