cpyte 2.1.0__tar.gz → 2.2.0__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-2.1.0 → cpyte-2.2.0}/PKG-INFO +7 -1
- {cpyte-2.1.0 → cpyte-2.2.0}/pyproject.toml +1 -1
- {cpyte-2.1.0 → cpyte-2.2.0}/readme.md +7 -1
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/bytecoding.py +38 -5
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/compiling.py +46 -1
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/mainpie.py +2 -1
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte.egg-info/PKG-INFO +7 -1
- {cpyte-2.1.0 → cpyte-2.2.0}/setup.cfg +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/__init__.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/__main__.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/_bignum_bc.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/_runtime_bc.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/astparse.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/clib.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/extension_hooks.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/generate_bc.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/lexar.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/linker.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/lsp_server.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/package_manifest.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte/semantic_analasis.py +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte.egg-info/SOURCES.txt +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte.egg-info/dependency_links.txt +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte.egg-info/entry_points.txt +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte.egg-info/requires.txt +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/source/cpyte.egg-info/top_level.txt +0 -0
- {cpyte-2.1.0 → cpyte-2.2.0}/test/test_bignum_jit.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cpyte
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: The Cpyte programming language compiler
|
|
5
5
|
Author: Hoang Duy Tung
|
|
6
6
|
License: MIT
|
|
@@ -81,3 +81,9 @@ python source/mainpie.py --jit examples/<filename>.cpy
|
|
|
81
81
|
Cpyte is experimental software. The compiler is continuously tested with fuzzing, and we're still discovering and fixing correctness bugs. While many programs compile and run correctly, I can't make any guarantees about correctness or stability.
|
|
82
82
|
|
|
83
83
|
If you decide to use Cpyte, always use the latest version — older versions have bugs that are pretty easy to run into.
|
|
84
|
+
|
|
85
|
+
## Memory Management
|
|
86
|
+
|
|
87
|
+
Cpyte uses **Boehm GC** (bdw-gc) for automatic garbage collection. Heap-allocated objects (via `new`) are managed automatically — no manual `free` needed.
|
|
88
|
+
|
|
89
|
+
**Note:** Boehm GC adds a small runtime overhead (~5-10%) compared to manual `malloc/free`. For performance-critical ecosystem projects or embedded use cases, this trade-off may be significant. The GC is required for safety but will slow down programs that do heavy heap allocation.
|
|
@@ -69,4 +69,10 @@ python source/mainpie.py --jit examples/<filename>.cpy
|
|
|
69
69
|
## Note
|
|
70
70
|
Cpyte is experimental software. The compiler is continuously tested with fuzzing, and we're still discovering and fixing correctness bugs. While many programs compile and run correctly, I can't make any guarantees about correctness or stability.
|
|
71
71
|
|
|
72
|
-
If you decide to use Cpyte, always use the latest version — older versions have bugs that are pretty easy to run into.
|
|
72
|
+
If you decide to use Cpyte, always use the latest version — older versions have bugs that are pretty easy to run into.
|
|
73
|
+
|
|
74
|
+
## Memory Management
|
|
75
|
+
|
|
76
|
+
Cpyte uses **Boehm GC** (bdw-gc) for automatic garbage collection. Heap-allocated objects (via `new`) are managed automatically — no manual `free` needed.
|
|
77
|
+
|
|
78
|
+
**Note:** Boehm GC adds a small runtime overhead (~5-10%) compared to manual `malloc/free`. For performance-critical ecosystem projects or embedded use cases, this trade-off may be significant. The GC is required for safety but will slow down programs that do heavy heap allocation.
|
|
@@ -131,6 +131,9 @@ class LLVM:
|
|
|
131
131
|
self.loop_stack = []
|
|
132
132
|
self._malloc_fn = None
|
|
133
133
|
self._free_fn = None
|
|
134
|
+
self._gc_alloc_fn = None
|
|
135
|
+
self._gc_mark_fn = None
|
|
136
|
+
self._gc_root_register_fn = None
|
|
134
137
|
self._strlen_fn = None
|
|
135
138
|
self._memcpy_fn = None
|
|
136
139
|
self.no_userspace = no_userspace
|
|
@@ -180,6 +183,24 @@ class LLVM:
|
|
|
180
183
|
fn = ir.Function(self.module, ir.FunctionType(ret, args), name=name)
|
|
181
184
|
self.functions[name] = fn
|
|
182
185
|
|
|
186
|
+
# Boehm GC runtime functions
|
|
187
|
+
gc_fns = [
|
|
188
|
+
('GC_init', _void, []),
|
|
189
|
+
('GC_malloc', _i8ptr, [_i64]),
|
|
190
|
+
('GC_realloc', _i8ptr, [_i8ptr, _i64]),
|
|
191
|
+
('GC_free', _void, [_i8ptr]),
|
|
192
|
+
('GC_gcollect', _void, []),
|
|
193
|
+
('GC_get_heap_size', _i64, []),
|
|
194
|
+
('GC_get_free_bytes', _i64, []),
|
|
195
|
+
('GC_disable', _void, []),
|
|
196
|
+
('GC_enable', _void, []),
|
|
197
|
+
('GC_add_roots', _void, [_i8ptr, _i8ptr]),
|
|
198
|
+
('GC_remove_roots', _void, [_i8ptr, _i8ptr]),
|
|
199
|
+
]
|
|
200
|
+
for name, ret, args in gc_fns:
|
|
201
|
+
fn = ir.Function(self.module, ir.FunctionType(ret, args), name=name)
|
|
202
|
+
self.functions[name] = fn
|
|
203
|
+
|
|
183
204
|
# Exception handling globals
|
|
184
205
|
self._exc_buf_ptr = ir.GlobalVariable(self.module, _i8ptr, "_exc_buf_ptr")
|
|
185
206
|
self._exc_buf_ptr.initializer = ir.Constant(_i8ptr, None)
|
|
@@ -422,6 +443,10 @@ class LLVM:
|
|
|
422
443
|
|
|
423
444
|
if wrapper_builder is not None:
|
|
424
445
|
self.builder = wrapper_builder
|
|
446
|
+
# Initialize Boehm GC at program start
|
|
447
|
+
gc_init_fn = self.functions.get('GC_init')
|
|
448
|
+
if gc_init_fn:
|
|
449
|
+
self.builder.call(gc_init_fn, [])
|
|
425
450
|
for node in toplevel:
|
|
426
451
|
self.emit(node)
|
|
427
452
|
self.builder.ret(ir.Constant(ir.IntType(32), 0))
|
|
@@ -556,19 +581,21 @@ class LLVM:
|
|
|
556
581
|
return ptr
|
|
557
582
|
|
|
558
583
|
def _get_malloc_fn(self):
|
|
559
|
-
|
|
584
|
+
# Use Boehm GC allocator instead of malloc
|
|
585
|
+
fn = self._gc_alloc_fn
|
|
560
586
|
if fn is not None:
|
|
561
587
|
return fn
|
|
562
588
|
for f in self.module.functions:
|
|
563
|
-
if f.name == '
|
|
564
|
-
self.
|
|
589
|
+
if f.name == 'GC_malloc':
|
|
590
|
+
self._gc_alloc_fn = f
|
|
565
591
|
return f
|
|
566
592
|
fnty = ir.FunctionType(_i8ptr, [_i64])
|
|
567
|
-
fn = ir.Function(self.module, fnty, '
|
|
568
|
-
self.
|
|
593
|
+
fn = ir.Function(self.module, fnty, 'GC_malloc')
|
|
594
|
+
self._gc_alloc_fn = fn
|
|
569
595
|
return fn
|
|
570
596
|
|
|
571
597
|
def _get_free_fn(self):
|
|
598
|
+
# Boehm GC manages memory - free is a no-op but keep for compatibility
|
|
572
599
|
fn = self._free_fn
|
|
573
600
|
if fn is not None:
|
|
574
601
|
return fn
|
|
@@ -813,6 +840,12 @@ class LLVM:
|
|
|
813
840
|
self.builder = ir.IRBuilder(entry)
|
|
814
841
|
self.builder.position_at_end(entry)
|
|
815
842
|
|
|
843
|
+
# Initialize Boehm GC in main function
|
|
844
|
+
if node.name == 'main':
|
|
845
|
+
gc_init_fn = self.functions.get('GC_init')
|
|
846
|
+
if gc_init_fn:
|
|
847
|
+
self.builder.call(gc_init_fn, [])
|
|
848
|
+
|
|
816
849
|
old_locals = self.locals
|
|
817
850
|
old_local_types = self.local_types
|
|
818
851
|
self.locals = {}
|
|
@@ -229,6 +229,7 @@ def run_jit(module, opt_level=3, src_files=None, no_userspace=False, pic=False):
|
|
|
229
229
|
pass
|
|
230
230
|
|
|
231
231
|
_map_libc_fn(engine, mod, 'malloc', ctypes.c_size_t, ctypes.c_void_p)
|
|
232
|
+
_map_libc_fn(engine, mod, 'free', None, None, argtypes=[ctypes.c_void_p])
|
|
232
233
|
_map_libc_fn(engine, mod, 'strlen', ctypes.c_char_p, ctypes.c_int)
|
|
233
234
|
_map_libc_fn(engine, mod, 'memcpy', None, ctypes.c_void_p,
|
|
234
235
|
argtypes=[ctypes.c_void_p, ctypes.c_void_p, ctypes.c_int])
|
|
@@ -251,6 +252,49 @@ def run_jit(module, opt_level=3, src_files=None, no_userspace=False, pic=False):
|
|
|
251
252
|
except NameError:
|
|
252
253
|
pass
|
|
253
254
|
|
|
255
|
+
# Map Boehm GC functions
|
|
256
|
+
# NOTE: Boehm GC cannot safely scan JIT'd code stacks on ARM64 macOS
|
|
257
|
+
# because JIT'd frames lack DWARF unwind info. For JIT, GC_malloc
|
|
258
|
+
# falls back to malloc (no collection needed - process exits immediately).
|
|
259
|
+
# For AOT, Boehm GC works normally via libgc linkage (-lgc).
|
|
260
|
+
try:
|
|
261
|
+
_libgc = ctypes.CDLL('/opt/homebrew/lib/libgc.dylib')
|
|
262
|
+
_gc_fns = {
|
|
263
|
+
'GC_init': (None, []),
|
|
264
|
+
'GC_realloc': (ctypes.c_void_p, [ctypes.c_void_p, ctypes.c_size_t]),
|
|
265
|
+
'GC_free': (None, [ctypes.c_void_p]),
|
|
266
|
+
'GC_gcollect': (None, []),
|
|
267
|
+
'GC_get_heap_size': (ctypes.c_size_t, []),
|
|
268
|
+
'GC_get_free_bytes': (ctypes.c_size_t, []),
|
|
269
|
+
'GC_disable': (None, []),
|
|
270
|
+
'GC_enable': (None, []),
|
|
271
|
+
'GC_add_roots': (None, [ctypes.c_void_p, ctypes.c_void_p]),
|
|
272
|
+
'GC_remove_roots': (None, [ctypes.c_void_p, ctypes.c_void_p]),
|
|
273
|
+
}
|
|
274
|
+
for gc_name, (gc_restype, gc_argtypes) in _gc_fns.items():
|
|
275
|
+
try:
|
|
276
|
+
fn = mod.get_function(gc_name)
|
|
277
|
+
if gc_argtypes:
|
|
278
|
+
cfunctype = ctypes.CFUNCTYPE(gc_restype, *gc_argtypes)
|
|
279
|
+
else:
|
|
280
|
+
cfunctype = ctypes.CFUNCTYPE(gc_restype)
|
|
281
|
+
cfn = cfunctype(getattr(_libgc, gc_name))
|
|
282
|
+
_callbacks.append(cfn)
|
|
283
|
+
engine.add_global_mapping(fn, ctypes.cast(cfn, ctypes.c_void_p).value)
|
|
284
|
+
except (NameError, AttributeError):
|
|
285
|
+
pass
|
|
286
|
+
# For JIT: map GC_malloc to malloc (avoids Boehm stack scanning crashes)
|
|
287
|
+
try:
|
|
288
|
+
fn = mod.get_function('GC_malloc')
|
|
289
|
+
cfunctype = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_size_t)
|
|
290
|
+
cfn = cfunctype(_libc.malloc)
|
|
291
|
+
_callbacks.append(cfn)
|
|
292
|
+
engine.add_global_mapping(fn, ctypes.cast(cfn, ctypes.c_void_p).value)
|
|
293
|
+
except (NameError, AttributeError):
|
|
294
|
+
pass
|
|
295
|
+
except OSError:
|
|
296
|
+
pass
|
|
297
|
+
|
|
254
298
|
engine.finalize_object()
|
|
255
299
|
engine.run_static_constructors()
|
|
256
300
|
|
|
@@ -334,7 +378,8 @@ def run_aot(module, output="program.o", opt_level=3, src_files=None, no_userspac
|
|
|
334
378
|
|
|
335
379
|
out_name = output.rsplit('.', 1)[0] if '.' in output else output
|
|
336
380
|
r = subprocess.run(
|
|
337
|
-
['clang', '-O3', '-o', out_name] + objs + ['-lm'
|
|
381
|
+
['clang', '-O3', '-o', out_name] + objs + ['-lgc', '-lm',
|
|
382
|
+
'-L/opt/homebrew/opt/bdw-gc/lib', '-I/opt/homebrew/opt/bdw-gc/include'],
|
|
338
383
|
capture_output=True, text=True
|
|
339
384
|
)
|
|
340
385
|
if r.returncode != 0:
|
|
@@ -369,7 +369,8 @@ def cmd_build(args, tab_size=4, strict=False, no_userspace=False, pic=False):
|
|
|
369
369
|
objs.append(runtime_obj)
|
|
370
370
|
|
|
371
371
|
executable = output or out_base
|
|
372
|
-
l.link(objs, executable,
|
|
372
|
+
l.link(objs, executable, libraries=['gc'], library_paths=['/opt/homebrew/opt/bdw-gc/lib'],
|
|
373
|
+
opt_level=opt, debug=debug, frameworks=frameworks, pic=pic)
|
|
373
374
|
print(f'Wrote {executable}')
|
|
374
375
|
|
|
375
376
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cpyte
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2.0
|
|
4
4
|
Summary: The Cpyte programming language compiler
|
|
5
5
|
Author: Hoang Duy Tung
|
|
6
6
|
License: MIT
|
|
@@ -81,3 +81,9 @@ python source/mainpie.py --jit examples/<filename>.cpy
|
|
|
81
81
|
Cpyte is experimental software. The compiler is continuously tested with fuzzing, and we're still discovering and fixing correctness bugs. While many programs compile and run correctly, I can't make any guarantees about correctness or stability.
|
|
82
82
|
|
|
83
83
|
If you decide to use Cpyte, always use the latest version — older versions have bugs that are pretty easy to run into.
|
|
84
|
+
|
|
85
|
+
## Memory Management
|
|
86
|
+
|
|
87
|
+
Cpyte uses **Boehm GC** (bdw-gc) for automatic garbage collection. Heap-allocated objects (via `new`) are managed automatically — no manual `free` needed.
|
|
88
|
+
|
|
89
|
+
**Note:** Boehm GC adds a small runtime overhead (~5-10%) compared to manual `malloc/free`. For performance-critical ecosystem projects or embedded use cases, this trade-off may be significant. The GC is required for safety but will slow down programs that do heavy heap allocation.
|
|
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
|