|
PineForge v0.1.2-15-g0247b7f
Deterministic PineScript v6 backtest runtime — C ABI reference
|
PineForge follows semantic versioning at the C ABI level. This page is the contract that lets a strategy .so compiled today keep working against tomorrow's runtime — and tells you when it won't.
Within the same PINEFORGE_VERSION_MAJOR:
<pineforge/pineforge.h> are append-only. Fields are never reordered, removed, or retyped. New fields may only appear at the end of an existing struct.extern "C" symbol signatures are append-only. New functions may be added; existing functions are never removed or signature-changed.Across major versions all bets are off. PineForge bumps MAJOR only when breaking the ABI — and announces it in release notes.
| Scenario | Outcome |
|---|---|
Strategy .so built against 0.1.0, loaded by runtime 0.1.7. | Works. |
Strategy .so built against 0.1.0, loaded by runtime 0.2.0. | Works (minor bump = additive). |
Strategy .so built against 0.1.0, loaded by runtime 1.0.0. | No guarantee. Recompile against the new ABI. |
Strategy .so built against 0.2.0, loaded by runtime 0.1.7. | Undefined. Newer ABI on older runtime — strategy may reference symbols that don't exist. |
The forward-compatible direction is older strategy → newer runtime.
Three layers:
static_asserts in src/c_abi.cpp pin every POD struct's sizeof and offsetof against drift between the C header and the internal C++ types. Any layout change that would affect the ABI fails the build.libpineforge.a is built with -fvisibility=hidden -fvisibility-inlines-hidden. Only symbols tagged PF_API (visibility=default) appear in any final .so that links it. Internal C++ classes (BacktestEngine, ta::*, pineforge::internal::*) stay hidden.scripts/check_c_abi_runtime.py verifies the ABI surface on every commit. Strategy-side parity is checked locally against the private corpus.A compiled strategy .so exports exactly these 10 C symbols and zero internal C++ symbols:
| Symbol | Group |
|---|---|
strategy_create | Strategy lifecycle |
strategy_free | Strategy lifecycle |
run_backtest | Strategy lifecycle |
run_backtest_full | Strategy lifecycle |
report_free | Strategy lifecycle |
strategy_set_input | Per-strategy configuration |
strategy_set_override | Per-strategy configuration |
strategy_set_magnifier_volume_weighted | Per-strategy configuration |
strategy_set_trace_enabled | Per-strategy configuration |
pf_version_get | Version query |
Plus the runtime-only export pf_version_string (string descriptor) and the configuration knob strategy_set_trade_start_time. The 10 above are the historical canonical surface; the additional symbols are append-only additions covered by the same minor-version guarantee.
You can verify this against any strategy .so:
The following are internal and may change in any release without notice:
<pineforge/engine.hpp>, <pineforge/ta.hpp>, etc.PF_API).If you find yourself reaching for any of these from outside the closed PineForge transpiler, you're holding it wrong — file an issue and we'll lift the missing surface into the public ABI.
The generated <pineforge/version.h> exposes:
Use these for compile-time gating of features added in later minors:
The runtime's actual linked version is also queryable at runtime via pf_version_get and pf_version_string.