Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
8c06aaa
fix: restore lint and runtime audit gates
proggeramlug Aug 1, 2026
48a5f41
fix(json): preserve overflow fields in array stringify
proggeramlug Aug 1, 2026
e047c07
fix(bench): sync public evidence workload contract
proggeramlug Aug 1, 2026
c314483
chore: refresh public benchmark evidence
proggeramlug Aug 1, 2026
5d60071
fix(runtime): close release parity regressions
proggeramlug Aug 1, 2026
40f4aea
test(release): make parity sweep reproducible
proggeramlug Aug 1, 2026
7aa4f1b
fix(release): close remaining parity regressions
proggeramlug Aug 1, 2026
3357b58
chore: prepare v0.5.1279 release candidate
proggeramlug Aug 1, 2026
99fc231
fix(release): repair runtime and CI regressions
proggeramlug Aug 1, 2026
a6faf9b
test(release): align parity fixtures with supported surfaces
proggeramlug Aug 1, 2026
9e03aac
fix(runtime): preserve accessor receivers
proggeramlug Aug 2, 2026
348abba
fix(streams): decode method-style subclass options
proggeramlug Aug 2, 2026
5ad67da
fix: close remaining release gate regressions
proggeramlug Aug 2, 2026
465aca8
fix(release): repair isolated workspace test gates
proggeramlug Aug 2, 2026
8d585e2
fix(i18n): link macOS locale frameworks
proggeramlug Aug 2, 2026
7c2db06
fix(codegen): repair typed-array proof gates
proggeramlug Aug 2, 2026
c339a8f
test(release): align Node 26 and native proof gates
proggeramlug Aug 2, 2026
4fb3ac3
test(codegen): distinguish dynamic shadow roots
proggeramlug Aug 2, 2026
75c7b0c
test(codegen): align numeric push proof with inline tier
proggeramlug Aug 2, 2026
627dfa1
fix(release): prepare Android emulator toolchain
proggeramlug Aug 2, 2026
03181a5
fix(release): package and launch Android emulator fixtures
proggeramlug Aug 2, 2026
4eb72b2
fix(release): align final release readiness gates
proggeramlug Aug 2, 2026
f86306a
fix(release): exclude cold launch from native ABI timing
proggeramlug Aug 2, 2026
9bec180
fix(link): rescan actual dependencies after Apple UI
proggeramlug Aug 2, 2026
c86040e
fix(release): keep local doc sweep display-independent
proggeramlug Aug 2, 2026
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
4 changes: 4 additions & 0 deletions .github/workflows/gc-ratchet.yml
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,10 @@ jobs:
# Deterministic link: use the prebuilt full stdlib rather than letting
# the auto-optimizer rebuild a workload-specific archive mid-run.
PERRY_NO_AUTO_OPTIMIZE: "1"
# The pinned baseline measures the moving collector. Keep that mode
# explicit now that ordinary binaries default loop polling off; a
# zero-cycle measurement would make the ratchet vacuous.
PERRY_GC_MOVING_LOOP_POLLS: "1"
run: |
set -euo pipefail
mkdir -p .bench-results
Expand Down
5 changes: 1 addition & 4 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,7 @@ cargo build --release # Build all crates
cargo build --profile perry-dev -p perry # Fast local dev build (#5422; perry-dev profile)
cargo build --release -p perry-runtime -p perry-stdlib # Rebuild runtime (MUST rebuild stdlib too!)
cargo build --release -p perry-runtime-static -p perry-stdlib-static # Emit libperry_{runtime,stdlib}.a (#5422: runtime/stdlib are now rlib-only; the .a comes from these wrapper crates)
cargo test --release --workspace \
--exclude perry-ui-ios --exclude perry-ui-tvos --exclude perry-ui-watchos \
--exclude perry-ui-visionos --exclude perry-ui-android --exclude perry-ui-windows \
--exclude perry-ui-gtk4 # Run tests (exclude cross-host UI crates on macOS)
scripts/release_sweep.sh --tier=1 # Release tests, isolated per package to avoid Cargo feature unification
cargo run --release -- file.ts -o output && ./output # Compile and run TypeScript
cargo run --release -- file.ts --print-hir # Debug: print HIR
cargo run --release -- file.ts --trace hir --focus fnName # Debug: focused HIR for one fn (use to localize a miscompile)
Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 24 additions & 22 deletions benchmarks/compiler_output/workloads.toml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ required = true
no_runtime_calls = true

[[workloads.image_convolution.named_regions.selectors]]
label_prefix_any = ["for.body.20", "for.body.24", "while.body.28"]
label_prefix_any = ["for.body.32", "for.body.36", "while.body.40"]

[[workloads.image_convolution.named_regions.checks]]
name = "named_region_input_generation_byte_writes"
Expand Down Expand Up @@ -114,7 +114,7 @@ no_runtime_calls = true
no_conversions = true

[[workloads.image_convolution.named_regions.selectors]]
label_prefix_any = ["for.body.42"]
label_prefix_any = ["for.body.70"]

[[workloads.image_convolution.named_regions.selectors]]
counter_min = { load_i8 = 1, xor_i32 = 1, mul_i32 = 1 }
Expand All @@ -132,7 +132,7 @@ allow_materialization_reasons = ["function_abi", "return_abi"]

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_input_generation_buffer_view"
block_label = "for.body.24"
block_label = "for.body.36"
expr_kind = "Uint8ArraySet.array"
consumer = "Uint8ArraySet.BufferView"
native_rep_name = "buffer_view"
Expand All @@ -142,7 +142,7 @@ min = 3

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_input_generation_byte_store"
block_label = "for.body.24"
block_label = "for.body.36"
expr_kind = "Uint8ArraySet"
consumer = "u8_store_trunc_i32"
native_rep_name = "u8"
Expand All @@ -152,7 +152,7 @@ min = 3

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_noise_byte_load"
block_label = "while.body.28"
block_label = "while.body.40"
expr_kind = "Uint8ArrayGet"
consumer = "u8_load_zext_i32"
native_rep_name = "u8"
Expand All @@ -161,7 +161,7 @@ bounds_state = "proven_or_guarded"

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_noise_byte_store"
block_label = "while.body.28"
block_label = "while.body.40"
expr_kind = "Uint8ArraySet"
consumer = "u8_store_trunc_i32"
native_rep_name = "u8"
Expand All @@ -170,7 +170,7 @@ bounds_state = "proven_or_guarded"

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_blur_byte_load"
block_label = "for.body.38"
block_label = "for.body.56"
expr_kind = "Uint8ArrayGet"
consumer = "u8_load_zext_i32"
native_rep_name = "u8"
Expand All @@ -181,7 +181,7 @@ min = 3

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_blur_byte_store"
block_label = "for.body.38"
block_label = "for.body.56"
expr_kind = "Uint8ArraySet"
consumer = "u8_store_trunc_i32"
native_rep_name = "u8"
Expand All @@ -191,7 +191,7 @@ alias_state = "no_alias_proven_or_guarded"

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_fnv_byte_load"
block_label = "for.body.42"
block_label = "for.body.70"
expr_kind = "Uint8ArrayGet"
consumer = "u8_load_zext_i32"
native_rep_name = "u8"
Expand All @@ -201,7 +201,7 @@ alias_state = "no_alias_proven_or_guarded"

[[workloads.image_convolution.native_rep_checks.require_records]]
name = "image_fnv_i32_hash"
block_label = "for.body.42"
block_label = "for.body.70"
expr_kind = "MathImul"
consumer = "lower_expr_native_i32.structural"
native_rep_name = "i32"
Expand Down Expand Up @@ -1512,15 +1512,15 @@ notes_contains = "typed_array_fallback=untracked_or_unproven"
min = 2

[[workloads.width_aware_buffer_kernels.native_rep_checks.require_records]]
name = "typed_array_bounds_get_fallback"
name = "typed_array_guarded_get"
source_function = "typedArrayHazards"
expr_kind = "TypedArrayGet"
consumer = "TypedArrayGet.slow_path"
consumer = "TypedArrayGet.inline_dynamic_guarded"
native_rep_name = "js_value"
access_mode = "dynamic_fallback"
bounds_state = "unknown"
materialization_reason = "unknown_bounds"
notes_contains = "typed_array_fallback=untracked_or_unproven"
access_mode = "checked_native"
bounds_state = "proven_or_guarded"
materialization_reason = "runtime_api"
notes_contains = "typed_array_fallback=js_dyn_index_get"

[[workloads.width_aware_buffer_kernels.native_rep_checks.require_records]]
name = "typed_array_alias_set_fallback"
Expand All @@ -1535,15 +1535,15 @@ notes_contains = "typed_array_fallback=untracked_or_unproven"
min = 2

[[workloads.width_aware_buffer_kernels.native_rep_checks.require_records]]
name = "typed_array_bounds_set_fallback"
name = "typed_array_guarded_set"
source_function = "typedArrayHazards"
expr_kind = "TypedArraySet"
consumer = "TypedArraySet.slow_path"
consumer = "TypedArraySet.inline_dynamic_guarded"
native_rep_name = "js_value"
access_mode = "dynamic_fallback"
bounds_state = "unknown"
materialization_reason = "unknown_bounds"
notes_contains = "typed_array_fallback=untracked_or_unproven"
access_mode = "checked_native"
bounds_state = "proven_or_guarded"
materialization_reason = "runtime_api"
notes_contains = "typed_array_fallback=js_dyn_index_set"

[workloads.native_owned_typed_views]
source = "benchmarks/compiler_output/fixtures/native_owned_typed_views.ts"
Expand Down Expand Up @@ -1881,6 +1881,7 @@ kind = "native_abi_packet_typed"
allow_hot_loop_conversions = true
allow_dynamic_property_runtime = true
allowed_hot_loop_runtime_calls = [
"js_shadow_frame_enter",
"js_shadow_frame_push",
"js_shadow_slot_bind",
]
Expand Down Expand Up @@ -1952,6 +1953,7 @@ allowed_hot_loop_runtime_calls = [
"js_get_property",
"js_set_property",
"js_dyn_index_get",
"js_shadow_frame_enter",
"js_shadow_frame_push",
"js_shadow_slot_bind",
"js_shadow_slot_set",
Expand Down
5 changes: 5 additions & 0 deletions benchmarks/json_polyglot/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -614,5 +614,10 @@ component = {
}
Path(output_path).write_text(json.dumps(component, indent=2) + "\n")
PY
status=$?
if [[ "$status" -ne 0 ]]; then
echo "public JSON evidence assembly failed" >&2
exit "$status"
fi
echo "Machine-readable results: $PUBLIC_JSON_OUT"
fi
29 changes: 20 additions & 9 deletions benchmarks/polyglot/bench.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import sys
import time


Expand Down Expand Up @@ -119,13 +120,23 @@ def bench_loop_data_dependent():
print(f" checksum: {sum_val:.6f}")


BENCHMARKS = {
"fibonacci": bench_fibonacci,
"loop_overhead": bench_loop_overhead,
"loop_data_dependent": bench_loop_data_dependent,
"array_write": bench_array_write,
"array_read": bench_array_read,
"math_intensive": bench_math_intensive,
"object_create": bench_object_create,
"nested_loops": bench_nested_loops,
"accumulate": bench_accumulate,
}


if __name__ == "__main__":
bench_fibonacci()
bench_loop_overhead()
bench_array_write()
bench_array_read()
bench_math_intensive()
bench_object_create()
bench_nested_loops()
bench_accumulate()
bench_loop_data_dependent()
if len(sys.argv) > 2 or (len(sys.argv) == 2 and sys.argv[1] not in BENCHMARKS):
choices = ", ".join(BENCHMARKS)
raise SystemExit(f"usage: {sys.argv[0]} [{choices}]")
selected = [sys.argv[1]] if len(sys.argv) == 2 else BENCHMARKS
for name in selected:
BENCHMARKS[name]()
13 changes: 10 additions & 3 deletions benchmarks/polyglot/run_all.sh
Original file line number Diff line number Diff line change
Expand Up @@ -230,13 +230,17 @@ stats_of() {
# Run each language across all benches. Produces TSV file
# `$TMPDIR/results_<lang>.tsv` with `bench<TAB>median|p95|stddev|min|max`.
run_lang() {
local lang="$1" cmd="$2"
local lang="$1" cmd="$2" select_one="${3:-0}"
local results="$TMPDIR/results_${lang}.tsv"
: > "$results"
for bk in "fibonacci:fibonacci" "loop_overhead:loop_overhead" "loop_data_dependent:loop_data_dependent" "array_write:array_write" "array_read:array_read" "math_intensive:math_intensive" "object_create:object_create" "nested_loops:nested_loops" "accumulate:accumulate"; do
IFS=: read -r bench key <<< "$bk"
local stats
stats=$(stats_of "$cmd" "$key" "$lang" "$bench")
local cell_cmd="$cmd"
if [[ "$select_one" == "1" ]]; then
cell_cmd="$cmd $bench"
fi
stats=$(stats_of "$cell_cmd" "$key" "$lang" "$bench")
printf "%s\t%s\n" "$bench" "$stats" >> "$results"
done
echo " $lang: done"
Expand Down Expand Up @@ -315,7 +319,10 @@ run_lang "cpp" "$TMPDIR/bench_cpp"
run_lang "swift" "$TMPDIR/bench_swift"
run_lang "go" "$TMPDIR/bench_go"
run_lang "java" "java -cp $TMPDIR bench"
run_lang "python" "python3 bench.py"
# `bench.py` accepts a benchmark selector. Without it, each of these nine
# cells reruns the entire Python suite 11 times and discards eight results,
# turning the Python comparison leg from ~6 minutes into nearly an hour.
run_lang "python" "python3 bench.py" 1

# Lookup helpers
field() { echo "$1" | cut -d'|' -f"$2"; }
Expand Down
21 changes: 15 additions & 6 deletions benchmarks/public_baseline.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,9 @@
},
"json_polyglot": {"roundtrip", "field_access"},
"app_patterns": {
"buffer_transcode", "date_format_parse", "json_parse_1mb", "json_stringify_1mb",
"map_1m", "object_deep_clone", "promise_all_chains", "regex_replace",
"batch", "buffer_transcode", "date_format_parse", "json_parse_1mb",
"json_stringify_1mb", "map_1m", "object_deep_clone", "promise_all_chains",
"regex_replace",
"string_concat_csv", "string_split_map_join", "string_template_interp",
},
"honest_bench": {"image_convolution", "json_pipeline_small", "json_pipeline_full"},
Expand Down Expand Up @@ -497,10 +498,17 @@ def _replace_block(text: str, block: str) -> str:
return before + block + after


def _replace_optional_block(text: str, block: str) -> str:
"""Replace the generated block when present, or preserve an unmarked README."""
if README_START not in text and README_END not in text:
return text
return _replace_block(text, block)


def render(artifact: Mapping[str, Any]) -> None:
readme = README.read_text(encoding="utf-8")
README.write_text(
_replace_block(README.read_text(encoding="utf-8"), readme_block(artifact)),
encoding="utf-8",
_replace_optional_block(readme, readme_block(artifact)), encoding="utf-8"
)
SUITE_RESULTS.write_text(suite_results(artifact), encoding="utf-8")

Expand Down Expand Up @@ -532,8 +540,9 @@ def validate_public(artifact: Mapping[str, Any], max_age_days: int) -> None:

def check(artifact: Mapping[str, Any], max_age_days: int) -> None:
validate_public(artifact, max_age_days)
expected_readme = _replace_block(README.read_text(encoding="utf-8"), readme_block(artifact))
if expected_readme != README.read_text(encoding="utf-8"):
readme = README.read_text(encoding="utf-8")
expected_readme = _replace_optional_block(readme, readme_block(artifact))
if expected_readme != readme:
raise ArtifactError("README Node/Bun table has drifted from the public artifact")
if suite_results(artifact) != SUITE_RESULTS.read_text(encoding="utf-8"):
raise ArtifactError("suite RESULTS.md has drifted from the public artifact")
Expand Down
Loading
Loading