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
41 changes: 35 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,21 @@ A ?= -c -fPIC -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Werror -Wall
B ?= $(A) -std=c11
OSSL ?= -DOPENSSL_SUPPRESS_DEPRECATED -DOPENSSL_API_COMPAT=30000 -Wno-deprecated-declarations
# Object lists for the archives (paths relative to compiler/, where `ar` runs).
FIB_OBJ ?= bin/memory_runtime.o bin/fiber_runtime.o bin/system_runtime.o bin/effects_runtime.o bin/string_runtime.o bin/string_runtime_list.o bin/list_runtime.o bin/map_runtime.o bin/map_runtime_hamt.o bin/json_runtime.o bin/ffi_runtime.o bin/term_runtime.o bin/random_runtime.o bin/test_runtime.o bin/profiler_runtime.o bin/profiler_sampler.o
FIB_OBJ ?= bin/memory_runtime.o bin/fiber_runtime.o bin/system_runtime.o bin/effects_runtime.o bin/string_runtime.o bin/string_runtime_list.o bin/list_runtime.o bin/map_runtime.o bin/map_runtime_hamt.o bin/json_runtime.o bin/ffi_runtime.o bin/term_runtime.o bin/random_runtime.o bin/test_runtime.o bin/coverage_runtime.o bin/profiler_runtime.o bin/profiler_sampler.o
HTTP_OBJ ?= bin/http_shared.o bin/http_client_runtime.o bin/http_server_request.o bin/http_server_response.o bin/http_server_runtime.o bin/websocket_client_runtime.o bin/websocket_server_runtime.o $(FIB_OBJ)
# GC backend archives (osprey --memory=gc): the tracing collector replaces
# memory_runtime.o, and the value-container units are rebuilt with the malloc
# redirect (osp_gc_shim.h) so their nodes live in the managed heap. Everything
# else is the same object. Implements [GC-TRACE-CONSERVATIVE], docs/plans/0011.
FIB_OBJ_GC ?= bin/memory_gc.o bin/fiber_runtime.o bin/system_runtime.o bin/effects_runtime.o bin/string_runtime.o bin/string_runtime_list.o bin/gc/list_runtime.o bin/gc/map_runtime.o bin/gc/map_runtime_hamt.o bin/json_runtime.o bin/ffi_runtime.o bin/term_runtime.o bin/random_runtime.o bin/test_runtime.o bin/profiler_runtime.o bin/profiler_sampler.o
FIB_OBJ_GC ?= bin/memory_gc.o bin/fiber_runtime.o bin/system_runtime.o bin/effects_runtime.o bin/string_runtime.o bin/string_runtime_list.o bin/gc/list_runtime.o bin/gc/map_runtime.o bin/gc/map_runtime_hamt.o bin/json_runtime.o bin/ffi_runtime.o bin/term_runtime.o bin/random_runtime.o bin/test_runtime.o bin/coverage_runtime.o bin/profiler_runtime.o bin/profiler_sampler.o
HTTP_OBJ_GC ?= bin/http_shared.o bin/http_client_runtime.o bin/http_server_request.o bin/http_server_response.o bin/http_server_runtime.o bin/websocket_client_runtime.o bin/websocket_server_runtime.o $(FIB_OBJ_GC)
# ARC backend archives (osprey --memory=arc): Perceus reference counting
# replaces memory_runtime.o, and the value-producing units (containers +
# strings + JSON) are rebuilt with the allocation redirect (osp_arc_shim.h) so
# their nodes/buffers carry the 16-byte header and registry entry. Implements
# [GC-ARC-PERCEUS], docs/plans/0011 phase 2 (milestone M1).
FIB_OBJ_ARC ?= bin/memory_arc.o bin/fiber_runtime.o bin/system_runtime.o bin/effects_runtime.o bin/arc/string_runtime.o bin/arc/string_runtime_list.o bin/arc/list_runtime.o bin/arc/map_runtime.o bin/arc/map_runtime_hamt.o bin/arc/json_runtime.o bin/ffi_runtime.o bin/term_runtime.o bin/random_runtime.o bin/test_runtime.o bin/coverage_runtime.o bin/profiler_runtime.o bin/profiler_sampler.o
HTTP_OBJ_ARC ?= bin/http_shared.o bin/http_client_runtime.o bin/http_server_request.o bin/http_server_response.o bin/http_server_runtime.o bin/websocket_client_runtime.o bin/websocket_server_runtime.o $(FIB_OBJ_ARC)

# WebAssembly (wasm32-wasip1) cross-build toolchain — opt-in via `make wasm`.
# Compiles the portable C-runtime subset (no pthreads/sockets/OpenSSL/syscalls)
Expand All @@ -94,7 +101,7 @@ WASM_CFLAGS ?= --target=$(WASM_TARGET) --sysroot=$(WASI_SYSROOT) -O2 -std=c11 -
# (termios) and ffi (dlopen).
# profiler_runtime compiles to inert stubs on wasm32 (no pthreads/signals) but
# must be present: codegen anchors `osp_prof_boot` into every main [PROF-ACTIVATE-ENV].
WASM_RT_SRC ?= memory_runtime string_runtime string_runtime_list list_runtime map_runtime map_runtime_hamt json_runtime effects_runtime test_runtime web_runtime profiler_runtime
WASM_RT_SRC ?= memory_runtime string_runtime string_runtime_list list_runtime map_runtime map_runtime_hamt json_runtime effects_runtime test_runtime coverage_runtime web_runtime profiler_runtime
# `make wasm-serve` static-host dir + port for the in-browser example.
WASM_SERVE_DIR ?= examples/wasm
WASM_SERVE_PORT ?= 8080
Expand Down Expand Up @@ -275,12 +282,19 @@ setup:
# so `cd` persists; faithful port of the original hardened C recipes.
_runtime:
@echo "==> building C runtime archives ($(RTB)/lib*_runtime.a)"
@cd compiler && set -e && $(MKDIR) bin lib bin/gc && \
@cd compiler && set -e && $(MKDIR) bin lib bin/gc bin/arc && \
$(CC) $(B) runtime/memory_runtime.c -o bin/memory_runtime.o && \
$(CC) $(B) runtime/memory_gc.c -o bin/memory_gc.o && \
$(CC) $(B) runtime/memory_arc.c -o bin/memory_arc.o && \
$(CC) $(B) -include runtime/osp_gc_shim.h runtime/list_runtime.c -o bin/gc/list_runtime.o && \
$(CC) $(B) -include runtime/osp_gc_shim.h runtime/map_runtime.c -o bin/gc/map_runtime.o && \
$(CC) $(B) -include runtime/osp_gc_shim.h runtime/map_runtime_hamt.c -o bin/gc/map_runtime_hamt.o && \
$(CC) $(B) -include runtime/osp_arc_shim.h runtime/list_runtime.c -o bin/arc/list_runtime.o && \
$(CC) $(B) -include runtime/osp_arc_shim.h runtime/map_runtime.c -o bin/arc/map_runtime.o && \
$(CC) $(B) -include runtime/osp_arc_shim.h runtime/map_runtime_hamt.c -o bin/arc/map_runtime_hamt.o && \
$(CC) $(A) -include runtime/osp_arc_shim.h runtime/string_runtime.c -o bin/arc/string_runtime.o && \
$(CC) $(A) -include runtime/osp_arc_shim.h runtime/string_runtime_list.c -o bin/arc/string_runtime_list.o && \
$(CC) $(B) -include runtime/osp_arc_shim.h runtime/json_runtime.c -o bin/arc/json_runtime.o && \
$(CC) -c -fPIC -O2 -Werror -Wall -Wextra -Wpedantic -std=c11 -D_GNU_SOURCE runtime/fiber_runtime.c -o bin/fiber_runtime.o && \
$(CC) $(A) runtime/system_runtime.c -o bin/system_runtime.o && \
$(CC) $(A) runtime/effects_runtime.c -o bin/effects_runtime.o && \
Expand All @@ -294,6 +308,7 @@ _runtime:
$(CC) $(B) runtime/term_runtime.c -o bin/term_runtime.o && \
$(CC) $(B) runtime/random_runtime.c -o bin/random_runtime.o && \
$(CC) $(B) runtime/test_runtime.c -o bin/test_runtime.o && \
$(CC) $(B) runtime/coverage_runtime.c -o bin/coverage_runtime.o && \
$(CC) $(B) runtime/profiler_runtime.c -o bin/profiler_runtime.o && \
$(CC) $(B) runtime/profiler_sampler.c -o bin/profiler_sampler.o && \
$(CC) -c -fPIC -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Werror -Wall -Wextra \
Expand All @@ -312,7 +327,9 @@ _runtime:
$(AR) rcs bin/libhttp_runtime.a $(HTTP_OBJ) && \
$(AR) rcs bin/libfiber_runtime_gc.a $(FIB_OBJ_GC) && \
$(AR) rcs bin/libhttp_runtime_gc.a $(HTTP_OBJ_GC) && \
cp bin/libfiber_runtime.a bin/libhttp_runtime.a bin/libfiber_runtime_gc.a bin/libhttp_runtime_gc.a lib/
$(AR) rcs bin/libfiber_runtime_arc.a $(FIB_OBJ_ARC) && \
$(AR) rcs bin/libhttp_runtime_arc.a $(HTTP_OBJ_ARC) && \
cp bin/libfiber_runtime.a bin/libhttp_runtime.a bin/libfiber_runtime_gc.a bin/libhttp_runtime_gc.a bin/libfiber_runtime_arc.a bin/libhttp_runtime_arc.a lib/

# Cross-compile the portable C-runtime subset to a wasm32-wasip1 archive that
# osprey links for `--target=wasm32`. One shell so `cd` persists. Fails loudly
Expand Down Expand Up @@ -388,7 +405,11 @@ _test_c_runtime:
$(CC) -O2 -g -fno-omit-frame-pointer -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Werror -Wall -Wextra \
-ftrapv -std=c11 -D_GNU_SOURCE \
runtime/profiler_runtime_tests.c runtime/profiler_runtime.c runtime/profiler_sampler.c -pthread \
-o bin/profiler_runtime_tests && ./bin/profiler_runtime_tests
-o bin/profiler_runtime_tests && ./bin/profiler_runtime_tests && \
$(CC) -O2 -D_FORTIFY_SOURCE=2 -fstack-protector-strong -Werror -Wall -Wextra \
-ftrapv -std=c11 -D_GNU_SOURCE \
runtime/coverage_runtime_tests.c runtime/coverage_runtime.c \
-o bin/coverage_runtime_tests && ./bin/coverage_runtime_tests

# [PROF-TEST] end-to-end profiler gate: --profile runs, exports, and reports.
_test_profiler:
Expand All @@ -413,6 +434,14 @@ _conformance-gc: build
@out=$$(OSPREY_RUN_FLAGS=--memory=gc zsh crates/diff_examples.sh); echo "$$out"; \
echo "$$out" | grep -Eq 'FAIL=0 ' || { echo 'FAIL: GC backend output diverged'; exit 1; }

# _conformance-arc: run every tested example under the Perceus ARC backend;
# output must be byte-identical to the default ([MEM-BACKENDS] / [GC-ARC-PERCEUS],
# docs/plans/0011 phase 2).
_conformance-arc: build
@echo "==> [conformance] differential harness under --memory=arc..."
@out=$$(OSPREY_RUN_FLAGS=--memory=arc zsh crates/diff_examples.sh); echo "$$out"; \
echo "$$out" | grep -Eq 'FAIL=0 ' || { echo 'FAIL: ARC backend output diverged'; exit 1; }

# --- vscode-extension -------------------------------------------------------
# The extension's LSP server spawns the `osprey` binary at runtime, so the
# integration tests need a real compiler on PATH: the Rust binary is staged as
Expand Down
13 changes: 13 additions & 0 deletions benchmarks/cases/ackermann/ackermann.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Ackermann–Péter function — deep, non-tail mutual self-recursion.

System.Console.WriteLine(Ack(3, 10));

static long Add(long a, long b) => a + b;
static long Sub(long a, long b) => a - b;

static long Ack(long m, long n)
{
if (m == 0) return Add(n, 1);
if (n == 0) return Ack(Sub(m, 1), 1);
return Ack(Sub(m, 1), Ack(m, Sub(n, 1)));
}
14 changes: 14 additions & 0 deletions benchmarks/cases/ackermann/ackermann.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Ackermann–Péter function — deep, non-tail mutual self-recursion.

int add(int a, int b) => a + b;
int sub(int a, int b) => a - b;

int ack(int m, int n) {
if (m == 0) return add(n, 1);
if (n == 0) return ack(sub(m, 1), 1);
return ack(sub(m, 1), ack(m, sub(n, 1)));
}

void main() {
print(ack(3, 10));
}
32 changes: 32 additions & 0 deletions benchmarks/cases/binarytrees/binarytrees.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// Allocate + traverse many short-lived binary trees — allocation/memory stress: build 1200 trees of depth 13, sum checks.

long acc = 0;
for (long i = 0; i < 1200; i++)
{
Tree t = Make(13);
acc += Check(t);
}
System.Console.WriteLine(acc);

static Tree Make(long d)
{
Tree t = new Tree();
if (d != 0)
{
t.Left = Make(d - 1);
t.Right = Make(d - 1);
}
return t;
}

static long Check(Tree t)
{
if (t == null) return 0;
return 1 + Check(t.Left) + Check(t.Right);
}

class Tree
{
public Tree Left;
public Tree Right;
}
29 changes: 29 additions & 0 deletions benchmarks/cases/binarytrees/binarytrees.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Allocate + traverse many short-lived binary trees — allocation/memory stress: build 1200 trees of depth 13, sum checks.

class Tree {
Tree? left;
Tree? right;
}

Tree make(int d) {
final t = Tree();
if (d != 0) {
t.left = make(d - 1);
t.right = make(d - 1);
}
return t;
}

int check(Tree? t) {
if (t == null) return 0;
return 1 + check(t.left) + check(t.right);
}

void main() {
int acc = 0;
for (int i = 0; i < 1200; i++) {
final t = make(13);
acc += check(t);
}
print(acc);
}
20 changes: 20 additions & 0 deletions benchmarks/cases/coins/coins.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Coin-change ways count — branching recursion over coin kinds.

System.Console.WriteLine(Ways(600, 5));

static long Coin(long k) => k switch
{
1 => 1,
2 => 5,
3 => 10,
4 => 25,
_ => 50,
};

static long Ways(long amount, long kind)
{
if (amount == 0) return 1;
if (amount < 0) return 0;
if (kind == 0) return 0;
return Ways(amount - Coin(kind), kind) + Ways(amount, kind - 1);
}
27 changes: 27 additions & 0 deletions benchmarks/cases/coins/coins.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// Coin-change ways count — branching recursion over coin kinds.

int coin(int k) {
switch (k) {
case 1:
return 1;
case 2:
return 5;
case 3:
return 10;
case 4:
return 25;
default:
return 50;
}
}

int ways(int amount, int kind) {
if (amount == 0) return 1;
if (amount < 0) return 0;
if (kind == 0) return 0;
return ways(amount - coin(kind), kind) + ways(amount, kind - 1);
}

void main() {
print(ways(600, 5));
}
11 changes: 11 additions & 0 deletions benchmarks/cases/collatz/collatz.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Collatz (3n+1) stopping time summed over 1..N — integer division (n/2) in deep recursion.

long acc = 0;
for (long i = 1; i < 100001; i++) acc += Collatz(i);
System.Console.WriteLine(acc);

static long Collatz(long n)
{
if (n == 1) return 0;
return n % 2 == 0 ? 1 + Collatz(n / 2) : 1 + Collatz(3 * n + 1);
}
14 changes: 14 additions & 0 deletions benchmarks/cases/collatz/collatz.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Collatz (3n+1) stopping time summed over 1..N — integer division (n/2) in deep recursion.

int collatz(int n) {
if (n == 1) return 0;
return n % 2 == 0 ? 1 + collatz(n ~/ 2) : 1 + collatz(3 * n + 1);
}

void main() {
int acc = 0;
for (int i = 1; i < 100001; i++) {
acc += collatz(i);
}
print(acc);
}
14 changes: 14 additions & 0 deletions benchmarks/cases/coprime/coprime.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Count coprime pairs (i,j), 1<=i,j<=N — nested iteration + Euclidean gcd.

long n = 2000;
long acc = 0;
for (long i = n; i > 0; i--)
{
for (long j = n; j > 0; j--)
{
if (Gcd(i, j) == 1) acc++;
}
}
System.Console.WriteLine(acc);

static long Gcd(long a, long b) => b == 0 ? a : Gcd(b, a % b);
16 changes: 16 additions & 0 deletions benchmarks/cases/coprime/coprime.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Count coprime pairs (i,j), 1<=i,j<=N — nested iteration + Euclidean gcd.

int gcd(int a, int b) => b == 0 ? a : gcd(b, a % b);

void main() {
const n = 2000;
int acc = 0;
for (int i = n; i > 0; i--) {
for (int j = n; j > 0; j--) {
if (gcd(i, j) == 1) {
acc++;
}
}
}
print(acc);
}
7 changes: 7 additions & 0 deletions benchmarks/cases/digitsum/digitsum.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Sum of decimal digit-sums over 1..N — integer division (n/10) and modulo in recursion.

long acc = 0;
for (long i = 1; i < 2000001; i++) acc += DigSum(i);
System.Console.WriteLine(acc);

static long DigSum(long n) => n < 10 ? n : (n % 10) + DigSum(n / 10);
11 changes: 11 additions & 0 deletions benchmarks/cases/digitsum/digitsum.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Sum of decimal digit-sums over 1..N — integer division (n/10) and modulo in recursion.

int digsum(int n) => n < 10 ? n : (n % 10) + digsum(n ~/ 10);

void main() {
int acc = 0;
for (int i = 1; i < 2000001; i++) {
acc += digsum(i);
}
print(acc);
}
Loading
Loading