Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: CI

on:
push:
branches: ["**"]
pull_request:
workflow_dispatch:

jobs:
tests:
name: tests (py${{ matrix.python-version }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
# The PoC needs 3.11+ (see README). Run the floor and current releases.
python-version: ["3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}

# Zero-dependency project: nothing to install. The suite runs the
# analyzer cases, the golden ArrayPool lowering, the codegen content
# assertions, and the property fuzzer (fixed seed) in one entrypoint.
- name: Run test suite
run: python tests/run_tests.py

# A heavier, non-blocking fuzz pass so a flake-free regression that only
# shows up on other random draws still gets surfaced on every push.
fuzz-extended:
name: extended codegen fuzz
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: "3.13"
- name: Property fuzz (50k draws, rotating seed)
run: python tests/test_codegen_props.py 50000 ${{ github.run_number }}
9 changes: 9 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
__pycache__/
*.py[cod]
*.egg-info/
.pytest_cache/
*.ownreport.json

# .NET build output (golden_arraypool demo)
bin/
obj/
212 changes: 201 additions & 11 deletions README.md

Large diffs are not rendered by default.

258 changes: 0 additions & 258 deletions codegen.py

This file was deleted.

File renamed without changes.
18 changes: 18 additions & 0 deletions examples/bad_maybe_release.own
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module MaybeReleaseDemo

resource Buffer {
acquire rent
release give
}

// 'b' is released on the 'then' path only. At the join its state is
// inconsistent, so the following `use b` touches a maybe-released value
// (OWN009). The 'else' path never releases, so it also leaks (OWN001).
// Good for `python -m ownlang cfg examples/bad_maybe_release.own`.
fn use_after_maybe(flag: int) {
let b = acquire Buffer(flag);
if (flag) {
release b;
}
use b;
}
10 changes: 10 additions & 0 deletions examples/bad_scratch_escape.own
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module BadScratchEscape

// OWN015: a scratch buffer may be stack-backed, so returning it would hand back
// a span into a frame that is about to pop. If you need to return a buffer, use
// Buffer.pooled(...) — a movable owned resource whose Return the checker enforces.

fn leak(size: int) -> Buffer {
let tmp = Buffer.scratch(size, inline = 1024);
return tmp;
}
32 changes: 32 additions & 0 deletions examples/buffer_scratch.own
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
module ScratchDemo

// A scratch buffer: prefer the stack, fall back to ArrayPool when the request
// exceeds the inline limit. The user states the intent; the checker proves it
// stays local; codegen emits both branches; and OwnTrace/OwnCounters log which
// backend was actually chosen at runtime.
//
// python -m ownlang check buffer_scratch.own # ownership is clean
// python -m ownlang emit buffer_scratch.own # stack-first + pool fallback
// python -m ownlang report buffer_scratch.own # what the compiler decided

policy DefaultScratch {
inline_bytes = 1024;
fallback = pool;
trace = debug;
counters = true;
clear_on_release = false;
}

extern fn Fill(borrow_mut Buffer);
extern fn Hash(borrow Buffer);

fn parse(size: int) {
let tmp = Buffer.scratch(size, inline = 1024, fallback = pool);
borrow_mut tmp as bytes {
Fill(bytes);
}
borrow tmp as view {
Hash(view);
}
release tmp;
}
Loading
Loading