تواقيع C والمخازن وإعارة النص
لبات 0.7.0 · الإصدار الحالي
راجع تواقيع C الثابتة وملفات تعريف المحوّلات وعمليات المخزن وفحوص المديات ونتائج الإخفاق الأصلي.
محتويات الصفحة
المضيف وعقد التصريح
المضيف الأصلي فقط، إصدار لبات 0.7.0 المنشور على Linux x86-64 مع glibc وSystem V ABI. ثبّت الأداة الأصلية وافحص متطلبات النظام ثم اتبع دليل C والأمثلة العامة. يرفض المتصفح الاستيرادات الخارجية قبل التنفيذ بالسبب foreign-imports-not-supported حتى إن لم تستخدم.
التصريح الخارجي على المستوى الأعلى ويربط اسم لبات وتوقيعه باسم مكتبة مشتركة حرفي واسم رمز C حرفي وتوقيع ثابت مدعوم أو ملف تعريف محوّل خارجي. يجب أن تكون الأسماء غير فارغة وخالية من NUL. يرفض تكرار زوج المكتبة والرمز. ضع غير_آمن / unsafe على التصريح وكل استدعاء؛ لا توجد كتلة غير آمنة تلغي وسم كل استدعاء. التصريحات الخارجية خاصة افتراضيا ويمكن تصديرها باستخدام شارك / share في وحدات المصدر الأصلية. لا تصبح قيما عادية قابلة للاستدعاء.
مقطع توضيحي
غير_آمن خارجي absolute(value: ص32) -> ص32 = سي("libc.so.6", "abs");
دالة ابدأ_الرئيسية() -> ص64 {
إذا غير_آمن absolute(ص32(-7)) ليس يطابق ص32(7) { أرجع 1; }
أرجع 0;
}على الكاتب مطابقة توقيع C الحقيقي وضمان صلاحية المؤشر وسلوك المكتبة. لا يحلل لبات ترويسات C ولا يستنتج التوقيع من الرمز ولا يفحص errno ولا يحول إخفاقات المكتبة إلى نتائج لبات تلقائيا.
التواقيع الثابتة وملفات التعريف المدعومة
يشتق سي / c التوقيع الثابت الدقيق من أنواع المصدر، من صفر إلى 32 معاملا أصليا. لا تضيف البيانات الوصفية معاملات C. لا توجد تحويلات عددية ضمنية؛ استخدم التحويل الصريح للمعامل ذي العرض المختلف.
| نوع لبات أو وصفه | تمثيل C في هذا الهدف |
|---|---|
منطقي / bool |
_Bool بحجم بايت واحد |
ص8 / i8، ط8 / u8 |
عدد موقع أو غير موقع من 8 بت |
ص16 / i16، ط16 / u16 |
عدد موقع أو غير موقع من 16 بت |
ص32 / i32، ط32 / u32 |
عدد موقع أو غير موقع من 32 بت |
ص64 / i64، ط64 / u64 |
عدد موقع أو غير موقع من 64 بت |
ع32 / f32، ع64 / f64 |
float وdouble |
مؤشر_سي / c_ptr |
مؤشر C معتم قابل لعدم وغير مملوك |
وحدة / unit في النتيجة فقط |
C void |
نص مع نص_سي(parameter) / cstring(parameter) |
إعارة const char * طوال الاستدعاء |
سي::مخزن مع وصف مدى |
مؤشر إلى بايتات يملكها وقت التشغيل |
نوع C char موقع هنا؛ وshort من 16 بت وint من 32 بت وlong وlong long والمؤشرات وsize_t من 64 بت. استخدم النوع الحقيقي الأساسي لـtypedef وenum. لا يوفر مؤشر_سي تحويل عنوان ولا يكشف تخزين مالك مدار كمؤشر خام. تستخدم قيمة المؤشر الفارغ عدم / null.
لا تدعم التواقيع متغيرة المعاملات أو المجاميع بالقيمة في المعامل أو النتيجة أو long double أو الأعداد المركبة أو مؤشرات الدوال الخام أو استيراد متغيرات C العامة. لا تعبر القوائم والسجلات والنتائج والقيم العادية القابلة للاستدعاء كقيم C عامة. يحتاج النص إلى وصف إعارة، والمخزن إلى وصف مدى واحد؛ ولا يصلح أي منهما كنوع نتيجة خارجية عامة.
| ملف تعريف المحوّل الخارجي | توقيع لبات الدقيق | نوع C الدقيق |
|---|---|---|
سي_صحيح__مؤشر_محرف_ثابت / c_int__const_char_ptr |
(نص) -> ص64 / (string) -> i64 |
int (*)(const char *) |
سي_مزدوج__مزدوج / c_double__double |
(ع64) -> ع64 / (f64) -> f64 |
double (*)(double) |
تحتفظ الملفات بتحويلاتها الأصلية. ينسخ الأول نص C ويحول نتيجة C int بالقيمة إلى ص64؛ وتبقى النتيجة السالبة بيانات عادية. يمرر الثاني قيم binary64 ويطبّع NaN المعادة ويستعيد بيئة الحساب العائم. لا يفحص أي منهما أعلام استثناءات الحساب العائم أو errno. لا توسع هذه التحويلات تواقيع c العامة. يختبر مثالا puts وdouble المحوّلين؛ ويختبر المثال العادي التواقيع الثابتة.
إعارة نص C
في سي العام ضع نص_سي(text) / cstring(text) على معامل النص. يقيّم لبات المعاملات ويرفض NUL الداخلي قبل دخول C وينسخ بايتات UTF-8 ويضيف فاصلة NUL. ينفذ المحوّل c_int__const_char_ptr الإعارة نفسها دون وصف صريح. تصح الإعارة طوال الاستدعاء فقط. يجوز لـC قراءتها أثناءه ولا يجوز تعديلها أو الاحتفاظ بمؤشرها بعد العودة. يختلف طولها بالبايتات عن عدد محارف Unicode.
يصبح النص الفارغ بايت النهاية فقط. يسبب NUL الداخلي فخا بالسبب foreign-string-contains-nul في ملف تعريف النص الأصلي وبالسبب invalid-foreign-argument في cstring العام؛ ويعطي فشل التخصيص نتيجة مضيف أو مورد لا رمز إرجاع من المكتبة. لا يمنع فحص العمر C من الاحتفاظ بالمؤشر أو إساءة استخدامه. انهيار الدالة الخارجية خارج ضمانات الفخ المنضبط في لبات.
عمليات المخزن
استورد أساسي::سي أو core::c. تتاح البادئة المكتوبة فقط. النوع مخزن / Buffer وعملياته المقترنة هي:
| العضو الإنجليزي / العربي | التوقيع بأنواع إنجليزية |
|---|---|
buffer / أنشئ_مخزن |
(list<u8>) -> result<Buffer> |
zero_buffer / أنشئ_مخزن_صفري |
(u64) -> result<Buffer> |
capacity / سعة |
(Buffer) -> result<u64> |
bytes / انسخ_بايتات |
(Buffer, u64) -> result<list<u8>> |
close / أغلق |
(Buffer) -> result<unit> |
ينسخ buffer البايتات بما فيها NUL وFF؛ ويخصص zero_buffer بايتات مصفرة. ينسخ bytes البادئة المطلوبة إلى قائمة جديدة ويرفض العدد الأكبر من السعة بالرمز foreign.invalid_argument. تبقى القوائم والتخزين الأصلي مستقلين. تتشارك نسخ المخزن مالكا أصليا واحدا. يبطل إغلاق نسخة كل النسخ؛ وينجح الإغلاق المتكرر. يعيد الوصول إلى مخزن مغلق foreign.closed. قد يعيد الوصول أثناء الاستخدام الأصلي foreign.busy.
قد يرفض الإنشاء السعة المحاسبة التي تتجاوز ميزانية ذاكرة التنفيذ بالرمز foreign.resource_limit. يجب أن تلائم القوائم المستخرجة طولها القابل للتمثيل وحجم التخصيص. للمخزن ذي السعة صفر بايت sentinel واحد محاسب. هذه حالات رفض قابلة للاسترداد؛ لكن فشل التخصيص أو استنفاد الموارد أثناء إنشاء نتيجة قد ينهي التنفيذ. افحص ok قبل الوصول إلى أحد فرعي النتيجة. لا تحتوي result<unit> قيمة value قابلة للقراءة.
يحتفظ الوصول الأصلي بالتخزين المحاسب حتى السكون. تحرر نهاية المراجع وتنظيف التنفيذ المالكين الأصليين، بما في ذلك دورات الملكية غير القابلة للوصول. يشارك الإسناد التخزين الأصلي ولا يستنسخه. يفحص مثال المخزن نسخ البايتات والنسخ المشتركة والاستخراج الأكبر من السعة والإغلاق المتكرر.
مديات البايتات الخارجية
ضع وصفا واحدا لكل معامل مخزن باستخدام إدخال(buffer,count) / input أو إخراج / output أو إدخال_وإخراج / inout. العدد قيمة حرفية غير سالبة أو قيمة معامل من أي نوع عدد صحيح مدعوم، غير سالبة وضمن السعة. هو معامل مصدر موجود إذا احتاجه توقيع C؛ ولا يضيف الوصف معاملا.
يوفر الإدخال بايتات قابلة للقراءة. يصفر الإخراج المدى المحدد قبل دخول C. يحافظ الإدخال والإخراج على البايتات للقراءة والكتابة. لا تتراجع الكتابات عند نتيجة C سالبة. يستخدم المدى الفارغ مؤشر sentinel صالحا. تقبل نسخ القراءة فقط، لكن تمرير مالك مخزن واحد إلى معاملات متعددة يسبب فخا إن كان أي منها قابلا للكتابة، حتى مع مدى فارغ. تسبب الأعداد السالبة أو الزائدة والمخازن المغلقة أو المشغولة والنسخ القابلة للكتابة فخا قبل دخول C. يجوز لـC الوصول إلى المدى المحدد أثناء الاستدعاء ولا يجوز الاحتفاظ بمؤشره بعد العودة. لا تثبت هذه الفحوص التزام C بتلك القواعد.
التحميل والإخفاقات وحدود الإدارة
يفحص check وbuild دون تحميل مكتبات مشتركة. يجهز run وبرنامج ELF المولد كل الاستيرادات قبل دالة البداية، بما فيها غير المستخدمة، بترتيب بايتات المكتبة ثم الرمز ثم معرّف المحوّل. يفتح كل اسم مكتبة حرفي مرة واحدة باستخدام RTLD_NOW | RTLD_LOCAL ثم يحل الرموز بواسطة dlsym وdlerror. تمر الأسماء دون تغيير إلى محمّل glibc. يمنع الفشل الأول البداية ويغلق المقابض المفتوحة بترتيب عكسي. تظل البرامج المبنية محتاجة إلى المكتبات المسماة، رغم عدم حاجتها إلى المترجم أو ملفات المصدر.
| الإخفاق | النتيجة المشاهدة |
|---|---|
| محوّل مجهول أو توقيع غير مطابق أو اسم غير صالح أو هدف مكرر أو غياب وسم عدم الأمان | خطأ مصدر بحالة CLI 1: unknown-foreign-adapter، foreign-signature-mismatch، invalid-foreign-library-name، invalid-foreign-symbol-name، duplicate-foreign-target، unsafe-required-on-foreign-declaration، unsafe-required-on-foreign-call |
| غياب مكتبة أو رمز | فشل تحميل بالحالة 4: foreign-library-open-failed، foreign-symbol-lookup-failed |
| نص NUL أو مدى غير صالح أو مخزن مغلق أو مشغول أو نسخ قابلة للكتابة | فخ بالحالة 5: foreign-string-contains-nul، invalid-foreign-argument، closed-foreign-handle، busy-foreign-buffer، aliased-foreign-buffer |
| رفض أداة مخزن | نتيجة فاشلة: foreign.invalid_argument، foreign.closed، foreign.busy، foreign.resource_limit |
| فشل تخصيص أو ميزانية تنفيذ | نتيجة مضيف أو مورد، لا تحويل تلقائي لنتيجة C إلى نتيجة فاشلة |
الاستدعاءات العادية غير الآمنة متزامنة وقد تحجب التنفيذ ولا تكتسب امتيازات التعليق أو الإلغاء أو الاستدعاءات الراجعة المدارة. تستبعدها معالجات HTTP والاستدعاءات الراجعة المدارة عبر كل مسارات الاستدعاء. تشارك الروابط المراجعة الموردة مع الأداة فقط في قواعد الإدارة؛ وتشمل المكتبات العامة الحالية HTTP وRaylib. لا تستطيع تصريحات المستخدم تسجيل عمليات مدارة ولا توجد ABI عامة مستقلة لتثبيت روابط مدارة. ليست تجهيزات اختبار الاستدعاءات الراجعة الخاصة بالمساهمين أمثلة عامة قابلة للتشغيل. راجع مجموعتي HTTP وRaylib لعقد كل منهما.