Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
330a819
moon Phase 1: ARC accounting through the VM stack, calls, and registers
Jun 27, 2026
a3c240b
moon Phase 1 (task #8, step 1): fix C-side ARC acquire/release asymme…
Jun 27, 2026
de2fe1b
moon Phase 1 (task #8, step 2): neuter lua_gc collection + ARC the C-…
Jun 27, 2026
6765de1
moon Phase 1 (task #8, step 3): fix metamethod result transfer (moonT…
Jun 27, 2026
bec768a
moon Phase 1 (task #8, step 4): ARC-wire string concatenation (VM con…
Jun 27, 2026
5fe63d2
docs: ARC Phase 1 task #8 progress (oracle method + fixed/remaining)
Jun 27, 2026
c9564a0
moon Phase 1 (task #8, step 5): ARC the error-propagation, pushes, an…
Jun 27, 2026
7941812
moon Phase 1 (task #8, step 6): ARC-correct string interning
Jun 27, 2026
3b644a0
docs: ARC drain-on now UAF-clean for feature smoke + stress (task #8)
Jun 27, 2026
f050693
moon Phase 1 (task #8, step 7): reclaim closures, upvalues, C-closure…
Jun 27, 2026
a1c2a84
docs: ARC reclamation now bounded for common hot-loop patterns (task #8)
Jun 27, 2026
9e0984e
moon Phase 1 (task #8, step 8): reclaim abandoned coroutine stacks
Jun 27, 2026
9feeac5
docs: coroutines now bounded under ARC drain-on (task #8)
Jun 27, 2026
953d0d1
moon Phase 1 (task #8, step 9): fix free-region pushes in close/final…
Jun 27, 2026
204a4b5
moon Phase 1 (task #8, step 10): ARC-wire generic-for, next, load, se…
Jun 28, 2026
8c5770a
moon Phase 1 (task #8, step 11): nil C-call scratch window under drai…
Jun 28, 2026
2386b34
moon Phase 1 (task #8, step 12): ARC-wire debug.getlocal / debug.setl…
Jun 28, 2026
2840f43
moon Phase 1 (task #8, step 13): ARC-wire error handler + unary metam…
Jun 28, 2026
38c38ab
moon Phase 1 (task #8, step 14): ARC-correct GET family + finishGet m…
Jun 28, 2026
62f87c8
moon Phase 1 (task #8, step 15): ARC-correct OP_VARARG expansion
Jun 28, 2026
8a2254a
moon Phase 1 (task #8, step 16): ARC-correct coroutine error propagation
Jun 28, 2026
f2d6eed
moon Phase 1 (task #8, step 17): don't ARC-free finalizable objects (…
Jun 28, 2026
fe7b641
moon Phase 1 (task #8, step 18): ARC-correct moon_xmove cross-stack t…
Jun 28, 2026
d1add2b
moon Phase 1 (task #8, step 19): ARC-correct moon_upvaluejoin
Jun 29, 2026
60cb4c6
moon Phase 1 (task #8, step 20): ARC-correct table-set GC anchors (OO…
Jun 29, 2026
49e97da
moon Phase 1 (task #8, step 21): ARC-wire userdata user-values
Jun 29, 2026
b2e34fe
moon Phase 1 (task #8, step 22): retain in moon_pushthread (thread UAF)
Jul 3, 2026
cf3a18a
moon Phase 1 (task #8, step 23): flip MOON_ARC_DRAIN on by default
Jul 3, 2026
787893d
moon Phase 1 (task #9): ARC-wire the Proto graph (protos now reclaim)
Jul 3, 2026
f93899d
moon Phase 1 (task #9): full string reclamation + frame-window teardo…
Jul 4, 2026
f5c8da9
moon Phase 1 (task #9): release dead temporaries at metamethod calls
Jul 4, 2026
d124b0e
moon Phase 1 (task #9): coroutine open upvalues -- verify handled + u…
Jul 4, 2026
719e821
moon Phase 1: comparison-TM results, deterministic __gc, all.lua reen…
Jul 4, 2026
e9e1c8e
moon Phase 1 (task #9): drain at every GC checkpoint; all.lua passes …
Jul 4, 2026
2bab052
moon Phase 1 (task #9): moon_arith ARC accounting
Jul 5, 2026
0a55453
moon Phase 1 (task #9): O(1) list unlink via intrusive back-link
Jul 5, 2026
efd243d
moon Phase 1 (task #9): plug string.dump anchor leak (moon_dump)
Jul 5, 2026
c23c18a
moon Phase 2: delete tracing GC — marking, weak, collector; write bar…
Jul 5, 2026
d82c329
moon Phase 2: remove orphaned tracing helpers (gray lists, generational)
Jul 5, 2026
cc47fb4
moon Phase 2: simplify finalizer path — drop generational remnants
Jul 5, 2026
0b8266f
moon Phase 2: drop dead GlobalState GC-control method decls
Jul 5, 2026
019c9c4
Finish ARC suite cleanup
Jul 5, 2026
bdd7621
Continue C++ modernization sweep
Jul 5, 2026
311a07b
Convert helper functions to methods
Jul 5, 2026
8b2504c
Split internal parser and state headers
Jul 5, 2026
71b4353
Remove MoonVector wrapper and clarify identifiers
Jul 5, 2026
d0146cb
Update GitHub Actions for ARC branch
Jul 5, 2026
b66c9ee
Align moon_State declaration tags
Jul 5, 2026
760aa67
Build test_arc across compilers
Jul 5, 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
46 changes: 46 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copilot instructions for this repository

## Build and test commands

```bash
# Standard development build
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build

# Run the CTest entry point wired in CMake
cd build && ctest --output-on-failure
cd build && ctest -R LuaTestSuite --output-on-failure

# Run the end-to-end Lua compatibility suite in user mode
cd testes && ../build/moon -e "_U=true" all.lua

# Focused checks
cd testes && ../build/moon phase0_smoke.mn # quick interpreter smoke used by CI
./build/test_arc # ARC reclamation regression test

# Sanitizer build
cmake -B build -DCMAKE_BUILD_TYPE=Debug -DLUA_ENABLE_ASAN=ON -DLUA_ENABLE_UBSAN=ON
cmake --build build
```

There is no separate lint target. Normal CMake builds act as the lint gate because warnings are treated as errors (`-Werror`).

`LUA_BUILD_TESTS` defaults to `ON` and injects `MOON_USER_H="mtests.h"` for the test harness. Use `-DLUA_BUILD_TESTS=OFF` only when you explicitly want a production-style build.

## High-level architecture

- `libmoon_static` is the main product built from the whole runtime; the `moon` executable in `src/interpreter/moon.cpp` is a thin CLI on top of it. `libmoon_shared` is optional.
- `src/core/` owns runtime state and control flow: `moon_State`, `GlobalState`, `CallInfo`, API entry points, protected-call/error handling, and the `MoonStack` subsystem.
- `src/vm/` contains the bytecode interpreter. VM behavior is centralized in the `VirtualMachine` class; older `moonV_*` wrapper-style entry points have been folded into methods there.
- `src/compiler/` parses source and emits bytecode/prototypes; `src/serialization/` dumps and undumps that bytecode representation.
- `src/objects/` defines the runtime object model (`Table`, `TString`, `Proto`, closures, userdata, etc.) on top of `GCObject` / `GCBase`.
- `src/memory/` is the current memory-management pivot point. The moon fork has replaced the old tracing-GC direction with ARC-style reference counting and deterministic drain logic in `mgc.cpp`; `src/memory/gc/*.cpp` still contains graph-walking/finalization machinery and related invariants that ARC code reuses.
- `testes/` is still largely the upstream Lua test suite. Those tests are mostly `.lua` files, while Moon modules default to `.mn`; `testes/all.lua` prepends `./?.lua` to `package.path` so legacy helper modules still load.

## Key repository-specific conventions

- This branch is a hard fork to **moon**. Prefer `moon*` names, `include/moon*.h`, the `moon` binary, and `.mn` as the default script/module extension. Some older docs and tests still mention `lua`; treat those as historical unless the current source/build files say otherwise.
- ARC ownership rules are critical. When changing stack, table, upvalue, or API write paths, use the existing ownership helpers (`moonC_slotAssign`, `moonC_slotInit`, `MoonStack::setSlot`, `copySlot`, `pushSlot`, `releaseRange`, etc.) instead of raw slot writes unless the code is intentionally doing an ownership transfer.
- Keep stack manipulation inside `MoonStack` and opcode behavior inside `VirtualMachine` when possible. This codebase has already consolidated those responsibilities; avoid reintroducing scattered helper logic or wrapper layers.
- Be careful with GC/layout-sensitive types. `GCObject`-derived layouts are intentionally guarded, including the reserved header padding in `src/objects/mobject_core.h`; do not remove layout-preserving fields or asserts when refactoring object headers.
- CI currently uses `testes/phase0_smoke.mn` as the fast smoke path, but deeper local validation for runtime work should include `test_arc` and usually `testes/all.lua`.
78 changes: 66 additions & 12 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
name: Moon CI (Phase 0)

# Moon fork, Phase 0: the tracing GC is neutered (ARC arrives in Phase 1), so the
# full Lua test suite cannot run yet — it would grow memory without bound. CI
# builds on both compilers and runs the self-contained Phase 0 smoke instead.
name: Moon CI

on:
push:
branches: [ moon, main ]
branches:
- '**'
pull_request:
branches: [ moon, main ]
branches: [ main ]
workflow_dispatch:

jobs:
build-and-test:
name: Build & Smoke (${{ matrix.compiler }}, ${{ matrix.build-type }})
name: Build & Tests (${{ matrix.compiler }}, ${{ matrix.build-type }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
Expand Down Expand Up @@ -44,7 +42,57 @@ jobs:
- name: Build
run: cmake --build build

- name: Phase 0 smoke
- name: ARC regression
run: ./build/test_arc

- name: Lua test suite
working-directory: build
run: ctest -R LuaTestSuite --output-on-failure

- name: Interpreter smoke
working-directory: testes
run: |
../build/moon phase0_smoke.mn 2>&1 | tee smoke.txt
grep -q "phase0 smoke OK" smoke.txt || exit 1

lto-smoke:
name: LTO Smoke (${{ matrix.compiler }})
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
compiler: [gcc-13, clang-15]

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y cmake ninja-build
if [[ "${{ matrix.compiler }}" == "gcc-13" ]]; then
sudo apt-get install -y g++-13
echo "CC=gcc-13" >> $GITHUB_ENV
echo "CXX=g++-13" >> $GITHUB_ENV
else
sudo apt-get install -y clang-15
echo "CC=clang-15" >> $GITHUB_ENV
echo "CXX=clang++-15" >> $GITHUB_ENV
fi

- name: Configure with LTO
run: |
cmake -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER=${{ env.CC }} \
-DCMAKE_CXX_COMPILER=${{ env.CXX }} \
-DLUA_ENABLE_LTO=ON \
-G Ninja

- name: Build
run: cmake --build build

- name: Interpreter smoke
working-directory: testes
run: |
../build/moon phase0_smoke.mn 2>&1 | tee smoke.txt
Expand All @@ -68,11 +116,15 @@ jobs:
-DLUA_ENABLE_ASAN=ON -DLUA_ENABLE_UBSAN=ON
cmake --build build

- name: Sanitizer ARC regression
run: |
ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
./build/test_arc

- name: Sanitizer smoke
working-directory: testes
run: |
# Phase 0 leaks by design (GC neutered), so disable leak detection;
# still catch use-after-free / out-of-bounds / UB on a bounded workload.
ASAN_OPTIONS=detect_leaks=0:halt_on_error=1 \
UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1 \
../build/moon phase0_smoke.mn 2>&1 | tee smoke.txt
Expand All @@ -81,14 +133,16 @@ jobs:
build-summary:
name: Build Summary
runs-on: ubuntu-latest
needs: [build-and-test, sanitizers]
needs: [build-and-test, lto-smoke, sanitizers]
if: always()
steps:
- name: Check results
run: |
echo "Build & Smoke: ${{ needs.build-and-test.result }}"
echo "LTO Smoke: ${{ needs.lto-smoke.result }}"
echo "Sanitizers: ${{ needs.sanitizers.result }}"
if [[ "${{ needs.build-and-test.result }}" != "success" ]] || \
[[ "${{ needs.lto-smoke.result }}" != "success" ]] || \
[[ "${{ needs.sanitizers.result }}" != "success" ]]; then
echo "❌ Some checks failed"; exit 1
fi
Expand Down
15 changes: 2 additions & 13 deletions .github/workflows/coverage.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
name: Code Coverage

on:
# Moon fork Phase 0: coverage runs the full Lua suite, which can't run under the
# neutered GC. Manual-only until the suite is restored with ARC (Phase 1+).
workflow_dispatch: # Allow manual trigger
workflow_dispatch:

jobs:
coverage:
Expand Down Expand Up @@ -35,7 +33,7 @@ jobs:

- name: Run tests to generate coverage data
working-directory: testes
run: ../build/lua all.lua
run: ../build/moon -e "_U=true" all.lua

- name: Generate coverage report
run: |
Expand Down Expand Up @@ -110,12 +108,3 @@ jobs:
repo: context.repo.repo,
body: body
});

# Optional: Upload to Codecov
# - name: Upload to Codecov
# uses: codecov/codecov-action@v4
# with:
# files: ./coverage_filtered.info
# flags: unittests
# name: codecov-lua-cpp
# fail_ci_if_error: false
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ temp
build/
build_clang/
build-clang/
build-asan/
install_test/
cmake-build-*/
coverage_html/
Expand Down
54 changes: 28 additions & 26 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ option(LUA_ENABLE_ASSERTIONS "Enable runtime assertions (for debugging)" ON)
option(LUA_ENABLE_ASAN "Enable AddressSanitizer" OFF)
option(LUA_ENABLE_UBSAN "Enable UndefinedBehaviorSanitizer" OFF)
option(LUA_ENABLE_COVERAGE "Enable code coverage reporting (gcov/lcov)" OFF)
option(LUA_ENABLE_LTO "Enable Link Time Optimization" OFF)
option(LUA_ENABLE_LTO "Enable Link Time Optimization for optimized builds" ON)
option(LUA_BUILD_SHARED "Build shared library in addition to static" OFF)

# Platform detection
Expand Down Expand Up @@ -126,14 +126,22 @@ endif()

# Link Time Optimization
if(LUA_ENABLE_LTO)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_RELWITHDEBINFO TRUE)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_MINSIZEREL TRUE)
# LTO can be aggressive about strict aliasing - Lua uses type punning extensively
# so we need to disable strict aliasing optimization to ensure correctness
add_compile_options(-fno-strict-aliasing)
add_link_options(-fno-strict-aliasing)
add_compile_options(
"$<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>:-fno-strict-aliasing>"
)
add_link_options(
"$<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>:-fno-strict-aliasing>"
)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
# Fat LTO objects: GCC-only flag (clang rejects it, fatal under -Werror).
add_compile_options(-ffat-lto-objects)
add_compile_options(
"$<$<OR:$<CONFIG:Release>,$<CONFIG:RelWithDebInfo>,$<CONFIG:MinSizeRel>>:-ffat-lto-objects>"
)
# GCC 15's whole-program IPA miscompiles the GC liveness/marking path:
# the registry root fails checkliveness on any full collection. clang+LTO
# and UBSan are both clean, so this is a GCC LTO bug, not portable UB.
Expand All @@ -145,11 +153,8 @@ if(LUA_ENABLE_LTO)
set_source_files_properties(
src/memory/mgc.cpp
src/memory/gc/gc_core.cpp
src/memory/gc/gc_marking.cpp
src/memory/gc/gc_sweeping.cpp
src/memory/gc/gc_finalizer.cpp
src/memory/gc/gc_weak.cpp
src/memory/gc/gc_collector.cpp
PROPERTIES COMPILE_OPTIONS "-fno-lto")
endif()
endif()
Expand Down Expand Up @@ -194,11 +199,8 @@ set(LUA_MEMORY_SOURCES
src/memory/mgc.cpp
src/memory/mmem.cpp
src/memory/gc/gc_core.cpp
src/memory/gc/gc_marking.cpp
src/memory/gc/gc_sweeping.cpp
src/memory/gc/gc_finalizer.cpp
src/memory/gc/gc_weak.cpp
src/memory/gc/gc_collector.cpp
)

set(LUA_SERIALIZATION_SOURCES
Expand Down Expand Up @@ -389,23 +391,23 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
${CMAKE_CURRENT_SOURCE_DIR}/src/vm
${CMAKE_CURRENT_SOURCE_DIR}/src/serialization
)

# ARC reclamation engine test (moon fork, Phase 1)
add_executable(test_arc test_arc.cpp)
target_link_libraries(test_arc PRIVATE libmoon_static)
target_compile_options(test_arc PRIVATE -Wall ${WARNING_FLAGS} ${OPTIMIZE_FLAGS})
target_include_directories(test_arc PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/testing
${CMAKE_CURRENT_SOURCE_DIR}/src/memory
${CMAKE_CURRENT_SOURCE_DIR}/src/memory/gc
${CMAKE_CURRENT_SOURCE_DIR}/src/core
${CMAKE_CURRENT_SOURCE_DIR}/src/objects
${CMAKE_CURRENT_SOURCE_DIR}/src/compiler
${CMAKE_CURRENT_SOURCE_DIR}/src/vm
${CMAKE_CURRENT_SOURCE_DIR}/src/serialization
)
endif()

# ARC reclamation engine test (moon fork, Phase 1)
add_executable(test_arc test_arc.cpp)
target_link_libraries(test_arc PRIVATE libmoon_static)
target_compile_options(test_arc PRIVATE -Wall ${WARNING_FLAGS} ${OPTIMIZE_FLAGS})
target_include_directories(test_arc PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/src/testing
${CMAKE_CURRENT_SOURCE_DIR}/src/memory
${CMAKE_CURRENT_SOURCE_DIR}/src/memory/gc
${CMAKE_CURRENT_SOURCE_DIR}/src/core
${CMAKE_CURRENT_SOURCE_DIR}/src/objects
${CMAKE_CURRENT_SOURCE_DIR}/src/compiler
${CMAKE_CURRENT_SOURCE_DIR}/src/vm
${CMAKE_CURRENT_SOURCE_DIR}/src/serialization
)

# Install targets
include(GNUInstallDirs)

Expand Down
Loading
Loading