اللغات: English | 简体中文 | 繁體中文 | 日本語 | 한국어 | Français | Deutsch | Español | Italiano | Русский | العربية
← واجهة NeverC الثنائية للإضافات
يستطيع NeverC تحميل ملف مصدر Python بواسطة خيار -fplugin= نفسه المستخدم
للإضافات الأصلية. تفعّل البنية العادية من المصدر إضافات Python وتثبيت بيئة
التشغيل المضمّنة افتراضياً:
cmake -S llvm -B build -C neverc/cmake/caches/NeverC.cmake \
-DCMAKE_INSTALL_PREFIX="$PWD/neverc-install"
cmake --build build --target installتستخدم البنيات الجديدة افتراضياً NEVERC_ENABLE_PYTHON_PLUGINS=ON و
NEVERC_BUNDLE_PYTHON_RUNTIME=ON. يمكن لـ CMake استعمال Python الخاص بالنظام
لتشغيل build scripts، لكن ذلك المفسّر لا يحدد ABI الإضافات. ينزّل NeverC بصورة
منفصلة حزمة development/runtime ثابتة من CPython 3.12.10 ويتحقق منها بواسطة
SHA-256، ثم يربط بها plugin bridge ويضعها في build/python ويثبّت runtime نفسه
في مجلد python/ المجاور. لذلك تشغّل بنيات المصدر العادية والأرشيفات الرسمية
الإضافات على CPython 3.12.10 من دون Python runtime خارجي أو PYTHONHOME أو
PYTHONPATH.
للبناء دون اتصال، استخدم -DNEVERC_MANAGED_PYTHON_ROOT=/path/to/cpython-3.12.10 للإشارة إلى شجرة
development/runtime مفكوكة مسبقاً وبالإصدار الدقيق CPython 3.12.10. يتحقق NeverC
منها وينسخها إلى build من دون تعديل مجلد المصدر المحدد.
على Linux يحتاج bundler الخاص بالتثبيت إلى patchelf ضمن PATH. لأن CMake
يشغّل ABI probe، يجب أن يكون managed Python plugin build حالياً native؛ على
cross build تعطيل Python أو استخدام native packaging stage منفصلة على منصة
target. لبناء compiler من دون Python مرّر
-DNEVERC_ENABLE_PYTHON_PLUGINS=OFF و
-DNEVERC_BUNDLE_PYTHON_RUNTIME=OFF معاً.
ثبّت حزمة التأليف بالأمر python3 -m pip install ./pluginsdk/python، أو أضف
المجلد إلى PYTHONPATH، أو ابنِ وثبّت المكوّن neverc-pluginsdk. يكتشف NeverC
أيضاً نسخة SDK المجهزة في <مجلد 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}حمّلها بواسطة مسار في نظام الملفات:
neverc -fplugin=/absolute/path/to/minimal.py -fsyntax-only input.cيقبل الـ decorator معرّف إضافة قياسياً واسماً غير فارغ وإصداراً دلالياً صارماً. يعلن كل script فئة إضافة واحدة فقط. تمثل الـ scripts وحدات مستقلة ويمكن مزجها مع الإضافات الأصلية.
جميع الـ hooks اختيارية:
- يحيط
on_process_begin(ctx)وon_destroy(ctx)بعملية المصرّف. - يسجل
register(ctx)الخيارات وobservers قبل تجميد مخطط المراحل. - يحيط
on_session_begin(ctx)وon_session_end(ctx)بعملية استدعاء. - يحيط
on_task_begin(ctx)وon_task_end(ctx)بوحدة عمل للمصرّف.
يمكن لـ begin hook إرجاع قيمة Python أو تعيين ctx.state؛ وتتوفر القيمة للـ
end hook المقابل. يجب أن تعيد بقية الـ hooks وobserver callbacks القيمة None.
الوضع الافتراضي هو session-serial وغير قابل لإعادة الدخول، ويمكن لـ @Plugin
اختيار النماذج نفسها المتاحة للإضافة الأصلية.
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 على ثوابت المراحل المدمجة البالغ عددها 130، مولّدة
من مخطط المراحل القياسي. تكشف observer frames بيانات المرحلة والمسار وhandles
معتمة للإدخال والإخراج والخيارات المحللة والتشخيصات وفحص الإلغاء والوسائط الخام
لـ driver.RAW_ARGUMENTS. تتحقق handles الأصلية من مدة حياتها: يرفع استخدام
كائن محتفظ به بعد انتهاء callback الاستثناء RuntimeError.
أنواع الخيار هي flag وjoined وseparate وmulti_arg، وأنواع القيم هي
bool وint وuint وstring وenum وpath، والتكرار هو single أو
last_wins أو append. يمرر خيار enum الخريطة
enum_values={الاسم: عدد صحيح}. يخص argument_count النوع multi_arg فقط.
تعتمد مساعدات دورة الحياة والخيارات وobservers عالية المستوى على واجهة C ABI
العامة الكاملة للإضافات. توفر neverc_plugin.abi تعريفات ctypes المولدة،
وتستعلم وحدات neverc_plugin.domains عن جميع الجداول الرسمية مع التحقق من
الإصدار والحجم. تربط bind_callbacks استدعاءات Python عبر trampolines أصلية
ذات تواقيع مطابقة تمامًا.
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)تتضمن SDK في
pluginsdk/python/examples/ollvm
مثالًا مكتوبًا باستخدام هذا الربط العام فقط، وينفذ بصورة حتمية استبدال
التعليمات (SUB) وتدفق التحكم الزائف (BCF) وتسطيح تدفق التحكم (FLA):
neverc -fplugin=/path/to/ollvm_plugin.py \
--ollvm-sub --ollvm-bcf --ollvm-fla \
--ollvm-seed 42 --ollvm-probability 80 \
input.c -o outputيتحول استثناء Python غير الملتقط إلى NEVERC_STATUS_PLUGIN_EXCEPTION. أثناء
session/task callback نشط، يصدر NeverC الـ traceback المنسق كتشخيص منظم؛ أما
فشل import أو activation فيتضمنه خطأ loader. يشترك كامل process في المفسر
المضمّن ولا يقوم NeverC بإنهائه عمداً، بينما تحرر كائنات كل إضافة عند unload.
إضافات Python امتدادات موثوقة للمصرّف. تعمل داخل العملية، ويمكنها import أي module، ولها صلاحيات الملفات والعملية نفسها التي يملكها NeverC. لا يوجد sandbox.
ربط Python ليس API مصغراً: تغطي تعريفات ctypes المولدة والـ trampolines
الأصلية جميع جداول C ABI الرسمية البالغ عددها 36، وكل records وfunctions
وعائلات callbacks، بما في ذلك mutation وinterceptors وproviders. كما تُفحص
lifetimes وtransactions وcontinuations. يوجد مثال OLLVM كامل بلغة Python ينفذ
SUB وBCF وFLA في pluginsdk/python/examples/ollvm/.
توجد التعريفات الخام في neverc_plugin.abi وواصفات الجداول في
neverc_plugin.domains.