Skip to content

Kilo/electric bear mdr - #20

Merged
Omena0 merged 8 commits into
mainfrom
kilo/electric-bear-mdr
Oct 30, 2026
Merged

Omena0 merged 8 commits into
mainfrom
kilo/electric-bear-mdr

Conversation

@Omena0

@Omena0 Omena0 commented Oct 29, 2026

Copy link
Copy Markdown
Owner

No description provided.

Introduces support for language-level pointers, including address-of
operations, dereferencing, and pointer arithmetic. This change
includes significant updates to the compiler, optimizer, and runtime
to support a modern memory model.

Key changes:
- Added `PtrType` to the IR and compiler to track pointer types.
- Implemented `ALLOCA`, `ADDR_LOCAL`, `ADDR_GLOBAL`, `PTR_LOAD`, and
  `PTR_STORE` instructions in the VM and IR.
- Updated the optimizer with escape analysis support for pointers and
  new SSA optimization passes (block merging and unreachable block
  removal).
- Enhanced the runtime with a segregated free-list allocator and
  support for reference-semantics structs and lists.
- Added support for `__addr__` and `__deref__` built-in functions in
  the Python interpreter.
- Updated documentation to reflect the new memory model and pointer
  operations.
…te specialization

Introduce a more sophisticated optimization suite including interprocedural
integer/boolean range analysis and branch-sensitive call-site
specialization. This allows the compiler to specialize functions based on
constant arguments and inferred value ranges, improving performance through
reduced branching and better constant folding.

Key changes include:
- Added `src/optimizer/ranges.py` for range inference and folding.
- Added `src/optimizer/puresim.py` for compile-time pure-function
  simulation.
- Updated `CodeGen` to support lookup tables for specialized function
  paths.
- Enhanced IR to track value ranges and argument constraints.
- Added `OptimizerConfig` for tunable analysis budgets.

refactor(runtime): implement deterministic scope-based reference counting

Transition from a simple free-list allocator to a deterministic memory
model using scope-based reference counting for managed objects (structs,
lists, sets).

Key changes include:
- Implemented `FrObjHeader` to manage reference counts and scope tracking.
- Added `runtime_scope_push` and `runtime_scope_pop` to manage allocation
  lifetimes.
- Updated `fr_rt.c` to handle automatic cleanup of objects when their
  owning function scope exits.
- Modified `CodeGen` to automatically emit scope management instructions
  for all user functions.
- Updated documentation to reflect the new memory model and ownership
  semantics.
Introduces a new dictionary data type and a working HTTP/1.1 library
(client and server) to the language. This change includes significant
updates to the runtime, compiler, and optimizer.

Key changes:
- **Runtime**: Added `RuntimeDict` support, socket syscall wrappers
  (connect, accept, bind, listen, etc.), and improved value handling.
- **Compiler**: Implemented dictionary bytecode operations, improved
  string equality handling, and enhanced struct field resolution.
- **Optimizer**: Added type propagation for generic list types to
  refine element types at call sites, and implemented parallel move
  resolution in code generation to prevent register clobbering.
- **Parser/Interpreter**: Added support for `elif` syntax, improved
  constant evaluation for booleans and bytes, and added `contains`
  builtin.
- **Examples**: Added a complete HTTP library example suite.
…eephole

Implement several new optimization passes and code generation improvements:
- Add Loop-Invariant Code Motion (LICM) to hoist side-effect-free
  instructions out of loops.
- Implement pure constant-call folding to evaluate pure functions at
  compile-time when arguments are constants.
- Add an assembly peephole pass to remove redundant temporary copies
  and simplify identity operations (e.g., `mov r1, r1` or `add r1, 0`).
- Implement comparison folding in codegen to fuse comparison instructions
  directly into conditional branches.
- Improve type propagation for PHI nodes and struct field access.
- Add support for trigonometric builtins (sin, cos, tan) and expanded
  filesystem operations.

Additionally, add new benchmarks (nbody) and test cases for filesystem
and math operations.
Update the optimizer to include heuristics for call-site specialization
to prevent code bloat and refine the Loop Invariant Code Motion (LICM)
pass to exclude constant operations. Additionally, update benchmarks
to include a new memory benchmark and adjust the N-body benchmark.

- optimizer: add check to ensure specialized clones are smaller or
  have fewer blocks than the original target
- optimizer: exclude constant operations from LICM candidates
- bench: add memory_bench.fr for RSS/allocation measurement
- bench: update nbody_bench.fr to use dynamic body generation
- docs: update bench/README.md with new benchmark descriptions and
  usage instructions
Add a new optimization pass in the native backend that recognizes simple
list-reduction loops (integer sum, float sum, and float sum-of-squares)
and emits AVX2 vectorized loops.

The implementation includes:
- Loop analysis to identify suitable reduction patterns.
- Code generation for AVX2 loops with a scalar remainder.
- Handling of edge cases like zero-length or non-multiple length lists.
- Proper preservation of GPR/XMM state using `vzeroupper`.

Also includes:
- Redundant type conversion elimination in `passes.py`.
- Updated documentation and new benchmarks for vector reductions.
Implement the Fr OS target for native compilation, allowing the emission
of static userspace ELFs using the Fr OS syscall ABI and ISA profile.

- Update `runtime/fr_rt.c` with Fr OS syscall definitions and logic
  for file I/O, sockets, and stat operations.
- Add `--target fr-os` flag to `fr native` CLI for selecting the target.
- Update `src/optimizer` to support target-specific code generation,
  including disabling AVX2 vectorization for Fr OS due to ISA
  restrictions.
- Adjust C compiler flags for Fr OS to use `-ffreestanding` and
  disable PIE/PIC.
- Refactor BSS and global variable emission in `codegen.py`.
- Add documentation and examples for the Fr OS target.
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-29T22:16:22.454781Z
We couldn’t complete this review. Comment @codex review to try again.
071ebdb PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@sourcery-ai

sourcery-ai Bot commented Oct 29, 2026

Copy link
Copy Markdown

Sorry @Omena0, your pull request is larger than the review limit of 150,000 diff characters

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

Comment thread runtime/fr_rt.c
int line) {
if (!list) return;
if (list->elem_type < 0 || list->elem_type == 0) list->elem_type = 4;
runtime_list_set_int_at(list, index, value, line);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL]: runtime_list_set_managed_at stores value without taking ownership

Unlike runtime_list_set_int (line 1158), this path neither calls runtime_retain/runtime_scope_forget on the new value nor releases the previous element. Because the list is marked elem_type = 4, runtime_release later releases every element, so this store leads to an over-release/double free, and the value can be freed at scope pop while the list still points at it (use-after-free).

Comment thread runtime/fr_rt.c

void runtime_dict_set(RuntimeDict* dict, int64_t key, int64_t value) {
if (!dict) return;
if (dict->key_type == -1) dict->key_type = key > 0x100000 ? 1 : 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL]: Integer dict keys above 0x100000 are treated as string pointers

key > 0x100000 is used to guess that the key is a string pointer, so a dict with integer keys such as 2000000 sets key_type = 1 and runtime_dict_key_eq then calls strcmp((const char*)a, (const char*)b) on the integer value, dereferencing an invalid address. The compiler only calls runtime_dict_set, so this heuristic is always used. Pass the element type explicitly instead of guessing from the value.

Comment thread runtime/fr_rt.c

void runtime_set_add(RuntimeSet* set, int64_t value) {
if (!set) return;
if (set->elem_type == -1) set->elem_type = value > 0x100000 ? 1 : 0;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[CRITICAL]: Large integer set elements are treated as string pointers

Same heuristic as the dict path: value > 0x100000 sets elem_type = 1, after which runtime_set_equal calls strcmp on the integer value. Any set of integers above 1,048,576 (for example s.add(2000000)) segfaults. runtime_set_add_typed exists but codegen always emits runtime_set_add (src/optimizer/codegen.py:2103), so the untyped heuristic is always used.

Comment thread runtime/fr_rt.c Resolved
Comment thread runtime/fr_rt.c Outdated
strcpy(full, "[");
strcat(full, exc_type);
strcat(full, "] ");
strcat(full, message);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Unbounded strcat into a 1024-byte stack buffer

runtime_exception_raise concatenates the user-controlled message (and exc_type) into char full[1024]. A raise message longer than about 1000 bytes overflows the stack. runtime_exception_raise_at has the same problem at lines 1631-1640. Use bounded snprintf or allocate the buffer.

Comment thread src/optimizer/codegen.py Outdated
elif lst.startswith("["):
# dst doubles as the temporary list pointer: no scratch clobber.
self._emit_int_move(lst, dst)
self._emit(f" mov {dst}, [{dst} + 8]")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Nested memory operand when the LIST_LEN result is spilled

When dst is a spill slot, _emit_int_move(lst, dst) loads the list pointer into [rbp-...], and this then emits mov [rbp-...], [[rbp-...] + 8], which x86 cannot encode. The heap/register path avoids this with a scratch register; the spilled path needs one too.

Comment thread src/optimizer/codegen.py Outdated
if val_loc.startswith("xmm"):
self._emit(f" movsd [rbp - {stack_offset - offset}], {val_loc}")
else:
self._emit(f" mov [rbp - {stack_offset - offset}], {val_loc}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Memory-to-memory store for a spilled struct field

In the stack_alloc path, a spilled val_loc (starting with [) produces mov [rbp - off], [rbp - off2], which is not a valid x86 instruction; a spilled float would also need movsd. The heap path stages through r11; do the same here.

Comment thread src/runtime.py Outdated
# Assignments alias mutable objects, matching the native/C reference
# semantics. Fresh literals and struct constructors already produce a new
# object for every evaluation, so no defensive copy is needed here.
cell = _global_vars.get(node["name"]) if _global_vars else None

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Global lookup takes precedence over the local scope

_global_vars.get(node["name"]) is checked before creating a local, so inside a function a declaration or assignment whose name matches a module global (including a parameter with that name) writes the global cell and never creates the local. This breaks local shadowing. Check vars first, then fall back to the global.

Comment thread examples/http/http_lib.fr Outdated
while (true) {
bytes chunk = sock.recv(4096)
if (len(chunk) == 0) { break }
raw = raw + chunk.decode()

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Decoding each recv chunk independently breaks multi-byte UTF-8

A UTF-8 sequence split across TCP segments makes chunk.decode() raise (or produce replacement characters), and binary bodies are always corrupted. Accumulate bytes and decode once after the full body is read.

@@ -0,0 +1,83 @@
// !true

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[WARNING]: Expected output does not match the program

main prints energy(bodies) > 0.0. The total energy is dominated by the negative central-body potential term (39.47 * 0.037 / 4.98 ~= -0.293) which exceeds the positive kinetic energy (about 0.18), so the program prints false, not true. The test will fail unless the optimizer is masking a miscompile.

@kilo-code-bot

kilo-code-bot Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (35 files)
  • cases/config.json
  • cases/data_types/dict_large_int_keys.fr
  • cases/data_types/set_large_int.fr
  • cases/error_handling/list_error_preserves_live.fr
  • cases/error_handling/long_raise_message.fr
  • cases/functions/local_shadow_global.fr
  • cases/io/listdir_refcount.fr
  • cases/math/round_half_away.fr
  • cases/math/trig_int_arg.fr
  • cases/memory/arg_escape_store.fr
  • cases/memory/deep_scope_overflow.fr
  • cases/memory/global_pointer_float.fr
  • cases/memory/list_set_managed_refs.fr
  • cases/memory/pointer_boxed_assignment.fr
  • cases/memory/pointer_conditional_addr.fr
  • cases/memory/pointer_field_assign_reuse.fr
  • cases/optimizer/div_precision.fr
  • cases/optimizer/range_unknown_call.fr
  • cases/optimizer/vector_start_offset.fr
  • doc/fr-os.md
  • examples/http/http_lib.fr
  • runtime/fr_rt.c
  • runtime/syscall.S
  • runtime/vm.c
  • src/builtin_funcs.py
  • src/compiler.py
  • src/optimizer/codegen.py
  • src/optimizer/ir_builder.py
  • src/optimizer/passes.py
  • src/optimizer/puresim.py
  • src/optimizer/ranges.py
  • src/optimizer/types.py
  • src/parser.py
  • src/runtime.py
  • src/wasm_compiler.py
Previous Review Summary (commit 071ebdb)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit 071ebdb)

Status: 27 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 11
WARNING 15
SUGGESTION 1
Issue Details (click to expand)

CRITICAL

File Line Issue
runtime/fr_rt.c 1260 Managed list element store omits retain/release of the new/old value, causing over-release/double-free or use-after-free
runtime/fr_rt.c 1396 Integer dict keys above 0x100000 are misclassified as string pointers and passed to strcmp
runtime/fr_rt.c 1453 Integer set elements above 0x100000 are misclassified as string pointers and passed to strcmp
runtime/vm.c 1511 Refcounted value_free reads List.refcount, but argv/listdir lists are malloc'ed without initializing it
runtime/vm.c 5378 SIN/COS/TAN treat every non-float operand as VAL_BIGINT; VAL_INT is dereferenced as a pointer
src/compiler.py 1839 Field assignment through a pointer stores the struct back into the pointer variable, clobbering the pointer
src/optimizer/ranges.py 536 Unknown call arguments are skipped when merging param ranges, so branches/divisor checks can be folded unsoundly
src/optimizer/passes.py 1730 ARG_ESCAPE structs are stack-allocated without checking whether the callee stores the pointer (use-after-return)
src/optimizer/ir_builder.py 407 ALLOCA for a boxed local is emitted in a conditional block and may not dominate later PTR_LOADs
src/optimizer/codegen.py 76 Peephole rewrites add/sub/xor/*sd tmp, rest + mov dst, tmp into an RMW on dst, changing semantics
src/optimizer/codegen.py 758 LIST_GET caller-save condition is inverted: it skips saving the caller-saved registers clobbered by the slow path

WARNING

File Line Issue
runtime/fr_rt.c 1042 runtime_str_repeat size multiplication can wrap, causing heap overflow
runtime/fr_rt.c 1614 Unbounded strcat of exception message into a 1024-byte stack buffer
runtime/syscall.S 78 Skipping scope push at depth 1024 desynchronizes push/pop and frees the parent scope
src/compiler.py 253 LOAD_GLOBAL/STORE_GLOBAL names break the wasm backend, which expects numeric indices
src/optimizer/ranges.py 347 SUB induction step assumes the phi is the first operand; c - i is incorrectly treated as a constant step
src/optimizer/puresim.py 234 round folding uses banker's rounding instead of C half-away-from-zero
src/optimizer/passes.py 1062 Purity set omits DIV/MOD/FDIV/LIST_ELEM_ADDR, allowing trapping calls to be eliminated
src/optimizer/ir_builder.py 396 STORE_CONST_*, COPY_LOCAL, INC_LOCAL, DEC_LOCAL bypass the boxed-local PTR_STORE path
src/optimizer/ir_builder.py 500 ADDR_GLOBAL hardcodes the pointee type as INT64 for every global
src/optimizer/codegen.py 509 Vectorized reductions assume the loop index starts at 0 and ignore the phi's initial value
src/optimizer/codegen.py 1413 Spilled LIST_LEN result emits an invalid nested memory operand
src/optimizer/codegen.py 1982 Spilled struct field emits an invalid memory-to-memory store
src/runtime.py 982 Global lookup precedes local scope, breaking local shadowing in functions
examples/http/http_lib.fr 166 Decoding each recv chunk independently breaks split multi-byte UTF-8 and binary bodies
cases/optimizer/nbody_small.fr 1 Expected output true does not match the program's negative total energy (prints false)

SUGGESTION

File Line Issue
src/optimizer/puresim.py 163 Integer division is folded through floating point, losing precision above 2^53
Files Reviewed (60 files)
  • README.md
  • TODO.md
  • bench/README.md
  • bench/memory_bench.fr
  • bench/nbody.fr
  • bench/nbody_bench.fr
  • bench/vector_bench.fr
  • cases/config.json
  • cases/data_structures/struct_reference_semantics.fr
  • cases/data_types/dict_basic.fr
  • cases/http/http_parse_request.fr
  • cases/http/http_parse_response.fr
  • cases/http/http_serialize_response.fr
  • cases/io/filesystem_basic.fr
  • cases/io/print_no_newline.fr
  • cases/math/trig_identities.fr
  • cases/memory/global_pointer.fr
  • cases/memory/pointer_basic.fr
  • cases/memory/pointer_double.fr
  • cases/memory/pointer_linked_list.fr
  • cases/memory/pointer_list_elem.fr
  • cases/memory/pointer_param.fr
  • cases/memory/pointer_return.fr
  • cases/memory/pointer_struct.fr
  • cases/memory/refcount_ownership.fr
  • cases/operators/string_equality.fr
  • cases/optimizer/branch_specialization.fr
  • cases/optimizer/lookup_table_pure.fr
  • cases/optimizer/nbody_small.fr
  • cases/optimizer/vector_reduce.fr
  • doc/fr-os.md
  • doc/ir_ops.md
  • doc/memory_and_pointers.md
  • doc/optimization.md
  • doc/vm_instructions.md
  • examples/fr-os/README.md
  • examples/fr-os/hello.fr
  • examples/http/README.md
  • examples/http/client_demo.fr
  • examples/http/http_lib.fr
  • examples/http/server_demo.fr
  • runtime/Makefile
  • runtime/fr_rt.c
  • runtime/syscall.S
  • runtime/vm.c
  • src/builtin_funcs.py
  • src/cli.py
  • src/compiler.py
  • src/optimizer/__init__.py
  • src/optimizer/codegen.py
  • src/optimizer/config.py
  • src/optimizer/ir.py
  • src/optimizer/ir_builder.py
  • src/optimizer/passes.py
  • src/optimizer/puresim.py
  • src/optimizer/ranges.py
  • src/optimizer/types.py
  • src/parser.py
  • src/run_single_test.py
  • src/runtime.py

Fix these issues in Kilo Cloud


Reviewed by free · Input: 113.3K · Output: 60.3K · Cached: 10.5M

@Omena0
Omena0 merged commit 15a4cee into main Oct 30, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant