Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
156 commits
Select commit Hold shift + click to select a range
dce109a
Bump minimum required CMake version to v3.19
soulofmischief Dec 7, 2025
02e1665
Set the minimum macOS deployment target for ARM64 to macOS 11.0 (Big …
soulofmischief Dec 7, 2025
3d4f031
Use native tuning for ARM64
soulofmischief Dec 7, 2025
eb2465a
Correctly match modern macOS system versions
soulofmischief Dec 7, 2025
564cb43
Use native tuning for ARM64
soulofmischief Dec 7, 2025
9986409
Build all core AOT libs with aot_core target
soulofmischief Dec 7, 2025
6fc9e17
Build with c++17
soulofmischief Dec 8, 2025
56686fd
Upgrade to LLVM 21.1.7
soulofmischief Dec 8, 2025
3ea06d4
Remove trailing whitespace
soulofmischief Dec 8, 2025
7dc4851
Shim __hash_memory when building on macOS
soulofmischief Dec 8, 2025
15e96e3
Remove whitespace
soulofmischief Dec 8, 2025
54aa874
Turn back off zlib support
soulofmischief Dec 8, 2025
37db78a
Upgrade to LLVM 21
soulofmischief Dec 8, 2025
d936c38
Support ARM64
soulofmischief Dec 9, 2025
cd1c498
Support optimization configuration
soulofmischief Dec 9, 2025
dd03bf8
Use optimization level 3 for AOT compilation
soulofmischief Dec 9, 2025
8366105
Include homebrew directories
soulofmischief Dec 9, 2025
940d167
Format
soulofmischief Dec 9, 2025
797b095
configure backlog
benswift Dec 16, 2025
b084a51
Create task-1 - Fix-LLVM-memcpy-intrinsic-signature-for-LLVM-21-compa…
benswift Dec 16, 2025
b4af93b
add AGENTS.md
benswift Dec 16, 2025
c7009b3
Modernise CMake configuration
benswift Dec 16, 2025
4339c76
update task
benswift Dec 16, 2025
cdeb90b
create a couple of new tasks
benswift Dec 16, 2025
cb41b00
update task-1 with fix notes
benswift Dec 16, 2025
b3f7f59
complete task-1: fix LLVM memcpy intrinsic for LLVM 21
benswift Dec 16, 2025
2382d74
add SIGKILL workaround note to AGENTS.md
benswift Dec 16, 2025
c2072e7
disable LLVM tools build for faster compilation
benswift Dec 16, 2025
8ab2bb9
complete task-3: disable LLVM tools build
benswift Dec 16, 2025
a10976a
replace ExternalProject with FetchContent for LLVM
benswift Dec 16, 2025
4bae755
update audio dependencies to tagged releases
benswift Dec 16, 2025
c0e4152
update file extension so change tracking tracks the correct file for
benswift Dec 16, 2025
a67b3ce
wrap AOT compilation with timeout to prevent hung processes
benswift Dec 16, 2025
501ab24
modernise CI workflow for current GitHub Actions runners
benswift Dec 16, 2025
813dc84
use macos-15-large for Intel x86_64 (macos-13 deprecated)
benswift Dec 16, 2025
e1414a1
drop macOS x86_64 (requires paid -large runner)
benswift Dec 16, 2025
21546fe
cache LLVM build to speed up subsequent CI runs
benswift Dec 16, 2025
7c21975
currently running these tasks, so we'll see how they go
benswift Dec 16, 2025
4bfece8
Create task-4 - Ensure-llvm-as-is-built-and-available-for-AOT-compila…
benswift Dec 16, 2025
e2e7041
add --batch option for serverless single-process execution
benswift Dec 16, 2025
ef41cc0
replace llc/llvm-as with llvm:emit-object-file FFI binding
benswift Dec 16, 2025
cf97949
default EXTERNAL_SHLIBS_GRAPHICS to OFF
benswift Dec 16, 2025
d329828
mark task-4 (llvm-as for AOT) as done
benswift Dec 16, 2025
0ce53da
fix Windows portmidi build: define bzero as memset
benswift Dec 16, 2025
cebfe83
fix Windows portmidi build: move bzero define inside EXTERNAL_SHLIBS …
benswift Dec 16, 2025
826e5ff
Create task-5 - sort-out-EXT_SHARE_DIR-and-other-env-vars.md
benswift Dec 16, 2025
de562cd
Create task-6 - see-if-GH-build-and-test-action-is-caching-the-LLVM-b…
benswift Dec 16, 2025
b0c5102
Create task-7 - fix-cpp-compiler-warnings.md
benswift Dec 16, 2025
457ab3a
enable cache saving even on build failure
benswift Dec 16, 2025
1ce92c6
mark task as done
benswift Dec 16, 2025
b60bb9e
Create task-8 - set-up-aot-targets-in-CMakeLists.txt-so-that-the-crea…
benswift Dec 16, 2025
16b5f58
fix AOT target tracking to include both output files and dependencies
benswift Dec 17, 2025
64567f6
Create task-7 - Fix-LLVM-21-JIT-compilation-first-path-IR-string-comp…
benswift Dec 16, 2025
1ad7fc4
Fix duplicate symbol declarations in AOT compilation
benswift Dec 17, 2025
766eb3e
Update task-7 - fix-cpp-compiler-warnings.md
benswift Dec 17, 2025
8abde90
fix PortMidi bzero linker error on Windows
benswift Dec 17, 2025
bbc58bd
fix Windows portmidi.dll path (installed to bin/ not lib/)
benswift Dec 17, 2025
a6f128e
update env var task with a detailed plan
benswift Dec 17, 2025
0022861
Create task-9 - fix-GH-actions-caching-issues.md
benswift Dec 17, 2025
924be82
fix GH Actions cache: use separate restore/save steps with always()
benswift Dec 17, 2025
5a5e702
update task-9 with fix details
benswift Dec 17, 2025
21e93b0
fix compiler warning
benswift Dec 17, 2025
ce12f8f
Create task-9 - ORC-JIT-symbol-lookup-fails-despite-successful-compil…
benswift Dec 17, 2025
b0b4ba9
update task file (on linux)
benswift Dec 17, 2025
3d99496
task is done
benswift Dec 17, 2025
aecbdf7
update task-9: macOS build succeeds, confirms Linux-specific issue
benswift Dec 17, 2025
ba12b39
Fix LLVM JIT symbol lookup on Linux by exporting symbols to dynamic t…
benswift Dec 17, 2025
7db0c3b
fix LLVM cache invalidation on Unix by fixing timestamps after restore
benswift Dec 17, 2025
db23851
simplify CI: use default CMake generators instead of Ninja
benswift Dec 17, 2025
70a528a
fix Windows rtmidi copy path in CMakeLists.txt
benswift Dec 17, 2025
2c923e2
fix Windows build: add NOMINMAX to prevent min/max macro conflicts wi…
benswift Dec 17, 2025
cfb801c
fix compiler warnings: sprintf, sign comparison, VLA, unused variables
benswift Dec 17, 2025
3d5e259
cache AOT-compiled libs in CI, don't build graphics AOT by default
benswift Dec 17, 2025
c9cf0aa
backlog cleanup
benswift Dec 17, 2025
dc1eb2f
mark task-7 and task-9 as done, remove duplicate task file
benswift Dec 17, 2025
89348ef
fix Windows build: replace std::regex::multiline with portable altern…
benswift Dec 17, 2025
8494d4c
fix Windows warning: move C++ exception code outside extern "C" block
benswift Dec 17, 2025
b87a4d2
fix build: restore C linkage for string_value function
benswift Dec 17, 2025
871b8eb
fix multiline regex: use line-by-line processing for removal operations
benswift Dec 17, 2025
2c4f464
Create task-10 - update-EXTLLVM-to-use-C-apis-rather-than-string-mung…
benswift Dec 17, 2025
fc11bca
Create task-11 - setup-CTest-to-use-batch-mode-if-possible-for-easier…
benswift Dec 18, 2025
daf097c
don't check remote branches
benswift Dec 18, 2025
1dd1bdc
fix: remove duplicate PIf/TWOPIf definitions from vaudio_dsp.xtm
benswift Dec 18, 2025
6d7785f
use --batch mode for CTest tests where possible
benswift Dec 18, 2025
f8759b3
add note about parallel tests to AGENTS.md
benswift Dec 18, 2025
d08a913
Create task-012 - update-external-graphics-libs.md
benswift Dec 18, 2025
8fa2745
refactor: use LLVM C++ APIs instead of string munging in EXTLLVM
benswift Dec 18, 2025
833cbe4
update GLFW to 3.4
benswift Dec 18, 2025
8cb6fee
update Assimp to 5.4.3
benswift Dec 18, 2025
f36383e
Update task-012 - update-external-graphics-libs.md
benswift Dec 18, 2025
d21e252
Create task-013 - Update-stb_image-bindings-for-stb_image_resize2-API.md
benswift Dec 18, 2025
a9b7529
remove obsolete register_for_window_events calls from glfw3.xtm
benswift Dec 18, 2025
02e9066
update backlog tasks for graphics libs update
benswift Dec 18, 2025
88a8c42
add cmake system information dir to gitignore
benswift Dec 18, 2025
09d54e0
fix Windows build: correct LLVM header path and MSVC divide-by-zero
benswift Dec 18, 2025
aa8b58e
fix Windows build: use line-by-line regex for sBuiltinTypes
benswift Dec 18, 2025
5231ab5
fix AOT build: strip duplicate type definitions from inline.ll
benswift Dec 18, 2025
72bf30e
consolidate inline.ll into bitcode.ll
benswift Dec 18, 2025
b5ce4e5
Create task-014 - check-cmake-cpack-packaging.md
benswift Dec 18, 2025
4d54704
add GH action stage for checking LLVM build status
benswift Dec 18, 2025
963d9d0
remove broken CPack packaging
benswift Dec 18, 2025
7ced525
refactor CMake build system for simplicity and robustness
benswift Dec 18, 2025
99ec039
add note about GH actions
benswift Dec 18, 2025
8b75ced
add note about tests
benswift Dec 18, 2025
729ae7d
fix Windows build: remove duplicate types from init.ll
benswift Dec 18, 2025
8bc974b
document LLVM dependency in AGENTS.md
benswift Dec 18, 2025
fe098ae
bump licence year to 2025
benswift Dec 18, 2025
ecc04f3
add some tasks
benswift Dec 18, 2025
b8fe7a6
add task about modernising the LLVM IR generation
benswift Dec 18, 2025
9a95038
Add Windows Azure VM provisioning scripts
benswift Dec 19, 2025
64e16d6
Document Azure VM provisioning env usage
benswift Dec 19, 2025
a8e0b3c
Add start/stop actions to Azure VM script
benswift Dec 19, 2025
8121fec
Default Azure VM location to australiaeast
benswift Dec 19, 2025
ee03fb8
Add destroy action and update usage comment
benswift Dec 19, 2025
a26d29c
Wait for resource group deletion on destroy
benswift Dec 19, 2025
a6ff197
update provisioning script
benswift Dec 19, 2025
cea2a43
update windows vm provisioning scripts
benswift Dec 19, 2025
8d52aa0
backlog cleanup
benswift Dec 19, 2025
f5aeeec
fix Windows build: handle CRLF line endings in IR parsing
benswift Dec 19, 2025
0ed23cf
Create task-019 - add-changelog-for-merging-aarch4-branch-back-to-mas…
benswift Dec 19, 2025
30a4438
Create task-020 - add-libs-aot-cache-back-to-the-build-cache-in-GH-ac…
benswift Dec 19, 2025
4aab926
simplify CI caching to LLVM-only with two-stage build
benswift Dec 19, 2025
7207b07
add info about running extempore to AGENTS.md
benswift Dec 19, 2025
404f63c
document batch mode and align extempore path in AGENTS.md
benswift Dec 19, 2025
eb77bfd
close task-018 (typed pointers work), create task-021 for JIT refacto…
benswift Dec 19, 2025
355ae00
Create task-022 - make-batch-flag-set-noaudio-as-well.md
benswift Dec 19, 2025
626320e
commit extempore debugging skills file
benswift Dec 20, 2025
95f3f0a
make --batch flag imply --noaudio
benswift Dec 20, 2025
ceba80f
tweak some debugging instructions in agents file
benswift Dec 21, 2025
11c5329
refactor jitCompile to use LLVM module cloning with LinkOnceODR
benswift Dec 22, 2025
e514861
Create task-023 - clang-format-cpp-code.md
benswift Dec 22, 2025
d5020ef
unify AOT compilation across all platforms
benswift Dec 22, 2025
2d4a7e0
document @TIME redefinition bug and update debugging skill
benswift Feb 17, 2026
664e933
filter template module globals from sTypeDefinitions before IR parsing
benswift Feb 17, 2026
957d30e
assert return value in bind-func redefinition test
benswift Feb 17, 2026
7f42709
replace AGENTS.md symlink approach with single CLAUDE.md file
benswift Feb 17, 2026
dd60285
replace sTypeDefinitions string with structured maps
benswift Feb 17, 2026
4ec1712
fix batch mode scheduler by initialising time before thread start
benswift Feb 18, 2026
73043f2
add missing native function declarations to template bitcode
benswift Feb 19, 2026
597683d
filter preamble against user IR and capture declarations from all com…
benswift Feb 19, 2026
1e9260a
fix get_native_fptr lookup by adding adhoc alias map
benswift Feb 19, 2026
1dd2c72
add backlog tasks for adhoc alias improvements
benswift Feb 19, 2026
32dc235
add task-027 for Windows AOT compilation hang
benswift Feb 19, 2026
3760709
fix Windows scheduler time advancing without sleep
benswift Feb 19, 2026
1c512b5
enforce LF line endings for .xtm and .scm files
benswift Feb 19, 2026
26f584f
replace platform-specific ifdefs with C++17 stdlib
benswift Feb 19, 2026
6ecb5a9
trigger CI
benswift Feb 19, 2026
ab0484d
use Ninja generator and EXCLUDE_FROM_ALL for LLVM to fix Windows CI c…
benswift Feb 19, 2026
ccf4460
restore _aligned_malloc/_aligned_free on Windows (MSVC lacks std::ali…
benswift Feb 20, 2026
ced1293
cache Ninja state files (.ninja_deps/.ninja_log) to prevent LLVM rebu…
benswift Feb 20, 2026
6f9337e
remove dead init()/destroy() methods from mutex/condition wrappers
benswift Feb 20, 2026
5239d4f
replace C standard headers with C++ equivalents
benswift Feb 20, 2026
8046a15
replace NULL with nullptr in extempore-authored source files
benswift Feb 20, 2026
df2fdc4
replace malloc/free with std::vector in OSC::sendOSC
benswift Feb 20, 2026
f23bdaf
use value-type vectors in tcp_osc_server_thread data_map
benswift Feb 20, 2026
abef3a9
use std::string_view for read-only string parameters in EXTLLVM
benswift Feb 20, 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
197 changes: 197 additions & 0 deletions .claude/skills/extempore-debugging.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,197 @@
# Extempore debugging skill

## Architecture overview

Extempore has three main layers:

1. **C++ runtime** (`src/`): Scheme interpreter, LLVM JIT, audio/OSC
2. **Scheme runtime** (`runtime/`): scheme.xtm, llvmir.xtm, llvmti.xtm
3. **xtlang libraries** (`libs/`): user-facing compiled DSL code

## Compilation paths

### Normal (interactive) compilation

```
llvm:compile-ir
-> llvm:jit-compile-ir-string (Scheme FFI)
-> jitCompile() in src/SchemeFFI.cpp
-> initializeTemplateModule() parses runtime/bitcode.ll once
-> parseAssemblyInto() of (type defs + user IR)
-> EXTLLVM::addTrackedModule() (ORC JIT)
-> EXTLLVM::addModule() (metadata tracking)
```

### AOT compilation

When `*impc:aot:current-output-port*` is set:

```
llvm:compile-ir
-> impc:compiler:queue-ir-for-compilation
-> appends to *impc:compiler:queued-llvm-ir-string*

impc:compiler:flush-jit-compilation-queue
-> llvm:jit-compile-ir-string with accumulated IR
```

## Startup sequence

1. C++ `main()` in Extempore.cpp
2. SchemeProcess ctor loads `runtime/init.xtm`
3. SchemeProcess task loads `runtime/scheme.xtm`, `runtime/llvmti.xtm`,
`runtime/llvmir.xtm`
4. Primary process compiles `runtime/init.ll` via `sys:compile-init-ll`
5. If `EXT_LOADBASE` is true (default), loads `libs/base/base.xtm`
6. `base.xtm` triggers AOT cache loading via
`impc:aot:insert-header`/`impc:aot:import-ll`
7. AOT cache files (e.g. `libs/aot-cache/base.xtm`) call `llvm:compile-ir` with
`.ll` files

## Key flags

- `--nobase`: Skip loading base library (useful for debugging JIT in isolation)
- `--noaudio`: Disable audio (required for headless/CI testing)
- `--batch "expr"`: Batch mode (no server, single process, no audio); exits only
if the expression calls `(quit ...)`. Implies `--noaudio`.

## Symbol tracking

`EXTLLVM::addModule()` populates `sGlobalMap` with function/global pointers:

- Key: symbol name (string)
- Value: pointer to `llvm::GlobalValue` in the metadata module clone

`EXTLLVM::getFunction()` / `EXTLLVM::getGlobalValue()` look up symbols in this
map.

## sTypeDefinitions accumulator

`jitCompile()` maintains a static string `sTypeDefinitions` (~400KB after full
library loading). It accumulates LLVM IR declarations (struct types, function
declarations, external globals) from every successful compilation so that
subsequent modules can reference earlier symbols. It is prepended to every user
IR string before parsing:

```
fullIR = sTypeDefinitions + userIR
```

This is parsed via `parseAssemblyInto()` into a cloned template module (from
`bitcode.ll`). If `sTypeDefinitions` contains a declaration that conflicts with
something already defined in the template module, the parse fails silently
(stderr is /dev/null) and the Scheme layer sees `#f` from
`llvm:jit-compile-ir-string`, producing "FLUSH FAILED".

## Adhoc polymorphism names

The xtlang compiler generates specialised function names for ad-hoc
polymorphism using the pattern:

```
<basename>_adhoc_<counter>_<base64-encoded-type-signature>
```

For example: `xtm_play_adhoc_492_W05vdGVEYXRhKi...`. The base64 portion
(`cname-encode`/`cname-decode` in `runtime/llvmir.xtm`) encodes the full type
signature. These names can be extremely long (hundreds of characters).

## Common issues

### Type definitions

AOT-compiled `.ll` files reference types like `%mzone`, `%clsvar` defined in
`runtime/bitcode.ll`. These must be available when parsing user IR.

### Windows CRLF

Regex-based IR parsing fails on Windows due to CRLF line endings. Use
line-by-line parsing with explicit CR stripping.

### Symbol not found after compilation

Check that:

1. Module was added to ORC JIT successfully
2. `EXTLLVM::addModule()` was called with the metadata clone
3. Symbol name matches exactly (including mangling like `_adhoc_`, `_poly_`)

### --batch mode hangs after errors

When a compilation error occurs in `--batch` mode, the process does not
automatically exit --- it hangs waiting for further input. Use `timeout` when
running batch tests. The `sys:load-then-quit` helper is designed to exit after a
timeout, but compilation errors can prevent it from reaching the quit call.

## Debugging commands

```scheme
;; List all modules
(llvm:list-modules)

;; Print all modules
(llvm:print)

;; Check if function exists
(llvm:get-function "function_name")

;; Print specific function
(llvm:print-function "prefix")
```

## Testing in isolation

```bash
# Skip base library to test JIT directly
./extempore --nobase --batch "(begin (llvm:jit-compile-ir-string \"define i64 @test() { ret i64 42 }\") (println (llvm:get-function \"test\")) (quit 0))"

# Test AOT cache loading
./extempore --nobase --batch "(begin (llvm:compile-ir (sys:slurp-file \"libs/aot-cache/xtmbase.ll\")) (quit 0))"
```

## C++ debug output

**stderr is unconditionally redirected to /dev/null** at startup
(`src/Extempore.cpp:174`: `freopen("/dev/null", "w", stderr)`). Neither
`std::cerr`, `fprintf(stderr, ...)`, nor any amount of flushing will produce
visible output. Options:

- Write to a file: `FILE* f = fopen("/tmp/xtm_debug.log", "a"); fprintf(f, ...); fflush(f);`
- Write to stdout: `printf(...); fflush(stdout);` (mixes with Scheme output)
- Temporarily comment out the `freopen` line for a debug build

## Building and testing

```bash
# configure (fetches LLVM ~30s, full configure ~30s)
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DEXTERNAL_SHLIBS_GRAPHICS=OFF

# build (LLVM is the bulk of the build time)
cmake --build build --target extempore -- -j$(nproc)

# run core tests (no audio needed, ~150s total)
cd build && ctest -L libs-core --output-on-failure

# run audio example tests (need audio libs built, each test has 300s timeout)
cd build && ctest -L examples-audio --output-on-failure

# quick smoke test of a specific file
timeout 120 ./build/extempore --noaudio --batch \
'(sys:load-then-quit "examples/core/fmsynth.xtm" 10)'
```

Test labels: `libs-core`, `libs-external`, `examples-audio`, `examples-core`,
`examples-graphics`. Defined in `extras/cmake/tests.cmake`.

## Key files

| File | Purpose |
| ---------------------- | --------------------------------------------------- |
| `src/SchemeFFI.cpp` | `jitCompile()` - main JIT entry point |
| `src/EXTLLVM.cpp` | `addModule()`, `getGlobalValue()` - symbol tracking |
| `src/ffi/llvm.inc` | Scheme FFI bindings for LLVM functions |
| `runtime/llvmir.xtm` | `llvm:compile-ir`, compilation queue |
| `runtime/llvmti.xtm` | Type inference, AOT compilation |
| `runtime/bitcode.ll` | Base type definitions (`%mzone`, `%clsvar`) |
| `libs/aot-cache/*.ll` | Pre-compiled LLVM IR |
| `libs/aot-cache/*.xtm` | Scheme stubs that load `.ll` files |
20 changes: 20 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Ensure consistent line endings across platforms
* text=auto

# LLVM IR files must use LF line endings (the C++ regex parser expects this)
*.ll text eol=lf

# Other source files
*.cpp text
*.h text
*.hpp text
*.xtm text eol=lf
*.scm text eol=lf

# Binary files
*.png binary
*.jpg binary
*.wav binary
*.aif binary
*.aiff binary
*.bc binary
Loading