Lingue: English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Français | Deutsch | Español | Italiano | Русский | العربية
NeverC può caricare un file sorgente Python tramite la stessa opzione
-fplugin= usata dai plugin nativi. Una normale build da sorgente abilita per
default i plugin Python e l'installazione del runtime incluso:
cmake -S llvm -B build -C neverc/cmake/caches/NeverC.cmake \
-DCMAKE_INSTALL_PREFIX="$PWD/neverc-install"
cmake --build build --target installLe nuove build usano NEVERC_ENABLE_PYTHON_PLUGINS=ON e
NEVERC_BUNDLE_PYTHON_RUNTIME=ON per default. CMake può usare il Python di
sistema per gli script di build, ma quell'interprete non seleziona l'ABI dei
plugin. NeverC scarica separatamente una distribution development/runtime
CPython 3.12.10 fissa e verificata con SHA-256, collega il bridge dei plugin,
la prepara in build/python e installa lo stesso runtime nella directory
adiacente python/. Le normali build da sorgente e gli archivi ufficiali
eseguono quindi i plugin con CPython 3.12.10 senza Python runtime esterno,
PYTHONHOME o PYTHONPATH.
Per una build offline, impostare -DNEVERC_MANAGED_PYTHON_ROOT=/path/to/cpython-3.12.10 su un albero
development/runtime CPython 3.12.10 esatto già estratto. NeverC lo verifica e
lo copia nella build senza modificare la directory sorgente fornita.
Su Linux il bundler d'installazione richiede patchelf in PATH. Poiché CMake
esegue una sonda ABI, le build con plugin Python gestiti devono essere native;
una cross build deve disabilitare Python o usare una fase di packaging nativa
sulla piattaforma target. Per un compiler senza Python, passare insieme
-DNEVERC_ENABLE_PYTHON_PLUGINS=OFF e
-DNEVERC_BUNDLE_PYTHON_RUNTIME=OFF.
Installare il pacchetto di authoring con python3 -m pip install ./pluginsdk/python, aggiungere la directory a
PYTHONPATH, oppure compilare e installare il componente neverc-pluginsdk.
NeverC rileva anche l'SDK preparato in
<directory di neverc>/../pluginsdk/python.
from neverc_plugin import Plugin
@Plugin(id="com.example.minimal", name="Minimal Python Plugin", version="1.0.0")
class MinimalPlugin:
def on_process_begin(self, ctx):
ctx.state = {"sessions": 0}Caricarlo tramite il percorso nel filesystem:
neverc -fplugin=/absolute/path/to/minimal.py -fsyntax-only input.cIl decorator accetta un ID canonico, un nome visualizzato non vuoto e una versione semantica rigorosa. Uno script dichiara esattamente una classe plugin. Script diversi sono moduli indipendenti e possono essere combinati con plugin nativi.
Tutti gli hook sono opzionali:
on_process_begin(ctx)eon_destroy(ctx)racchiudono il processo compiler.register(ctx)registra opzioni e observer prima del freeze del grafo delle fasi.on_session_begin(ctx)eon_session_end(ctx)racchiudono un'invocazione.on_task_begin(ctx)eon_task_end(ctx)racchiudono un'unità di compilazione.
Un hook begin può restituire un valore Python o assegnare ctx.state; l'hook
end corrispondente può leggerlo. Gli altri hook e callback observer devono
restituire None. Per impostazione predefinita sono session-serial e non
rientranti; @Plugin può scegliere gli stessi modelli di un plugin nativo.
from neverc_plugin import Plugin
from neverc_plugin.domains import driver
@Plugin(id="com.example.trace", name="Trace", version="1.0.0")
class TracePlugin:
def register(self, ctx):
ctx.option(
"--trace-python",
kind="flag",
value_type="bool",
help="Trace raw driver arguments",
)
ctx.observer(
driver.RAW_ARGUMENTS,
when=("before", "after"),
fn=self.observe,
)
def observe(self, frame):
if frame.option_values("--trace-python"):
frame.check_cancelled()
frame.emit_remark(f"arguments: {frame.arguments}", code=1001)neverc_plugin.phases contiene tutte le 130 costanti delle fasi integrate,
generate dallo schema normativo. I frame observer espongono dati di fase e
route, handle opachi di input/output, opzioni analizzate, diagnostica, controllo
della cancellazione e argomenti grezzi per driver.RAW_ARGUMENTS. Gli handle
nativi verificano la propria lifetime: usare un oggetto conservato dopo il
callback genera RuntimeError.
I kind delle opzioni sono flag, joined, separate e multi_arg; i tipi
sono bool, int, uint, string, enum e path; le molteplicità sono
single, last_wins e append. Una enum riceve il mapping
enum_values={nome: intero}. argument_count vale solo per multi_arg.
Gli helper per ciclo di vita, opzioni e observer si basano sull’intera ABI
pubblica dei plugin C. neverc_plugin.abi contiene le definizioni ctypes
generate, mentre i moduli in neverc_plugin.domains interrogano tutte le
tabelle ufficiali verificandone versione e dimensione. bind_callbacks
collega i callback Python tramite trampoline native con firma esatta.
from neverc_plugin import abi
from neverc_plugin.domains import ir
from neverc_plugin.ffi import bind_callbacks, require_ok
def register(self, context):
scope = context.ffi
core = ir.CORE.query(scope)
builder = ir.BUILDER.query(scope)
passes = ir.PASS.query(scope)L’SDK include in
pluginsdk/python/examples/ollvm
un esempio scritto esclusivamente contro questo binding pubblico che implementa
in modo deterministico instruction substitution (SUB), bogus control flow
(BCF) e control-flow flattening (FLA):
neverc -fplugin=/path/to/ollvm_plugin.py \
--ollvm-sub --ollvm-bcf --ollvm-fla \
--ollvm-seed 42 --ollvm-probability 80 \
input.c -o outputUn'eccezione Python non gestita diventa NEVERC_STATUS_PLUGIN_EXCEPTION.
Durante un callback session/task attivo, NeverC emette il traceback formattato
come diagnostica strutturata; gli errori di import e activation lo includono
nell'errore del loader. L'interprete embedded è condiviso nel processo e non
viene intenzionalmente finalizzato, mentre gli oggetti del plugin vengono
rilasciati all'unload.
I plugin Python sono estensioni compiler fidate. Vengono eseguiti nel processo, possono importare moduli arbitrari e hanno gli stessi permessi di NeverC. Non è presente una sandbox.
Il binding Python non è un'API ridotta: le definizioni ctypes generate e i
trampoline nativi coprono tutte le 36 tabelle ABI C ufficiali, i record, le
funzioni e le famiglie di callback, incluse mutazioni, interceptor e provider.
Lifetime, transaction e continuation sono verificati. Un esempio OLLVM Python
completo con SUB, BCF e FLA è in pluginsdk/python/examples/ollvm/.
Le definizioni raw sono in neverc_plugin.abi e i descrittori delle tabelle in
neverc_plugin.domains.