Skip to content
Open
Changes from all commits
Commits
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
203 changes: 203 additions & 0 deletions text/0000-تخزين-ساكن-مسمّى-وسمات-التخزين.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
- **عنوان المقترح:** تخزين ساكن مسمّى + سمات التخزين (`@رمز`/`@متطاير`/`@محزوم`) + بيانات مضمَّنة
- **النطاق:** لغة `text/`
- **تاريخ البدء:** 2026-07-21
- **رقم الـ RFC:** (يُترك فارغاً حتى الدمج)
- **الحالة:** مقترَح (PR مفتوح)
- **Issue التتبُّع:** (يُترك فارغاً حتى القبول)

# ملخّص

تمكين برامج ص من تعريف **مخزن ساكن مسمّى برمز رابط مستقرّ ومُصدَّر** يعيش في
`.bss`/`.rodata`، مع سمات تخزين: `@رمز("اسم")` (رمز رابط ثابت مُصدَّر)، تفعيل
`@متطاير` على التصريح (مكسور حاليًّا)، `@محزوم` (رصّ)، وحرفيّة **بيانات مضمَّنة**
(كتلة بايتات ثابتة في `.rodata`). الهدف المباشر: أن تملك نواة النحلة عدّاداتها
وخريطتها البتّيّة وأرشيفها بلغة ص بدل مخازن C، مكمِّلةً مدمج `عنوان_رمز` (اللبنة
3.13) الذي صار يأخذ عناوينها.

# الدافع (Motivation)

بعد اللبنة 3.13 (`عنوان_رمز`) صارت ص تأخذ عنوان رمز رابط خارجيّ، فأُطفئت جالبات
العنونة. لكنّ **المخازن نفسها ما زالت في C**: عدّادات المقاطعات (`bee_probe_hits`
وأخواتها، `volatile`)، الخريطة البتّيّة لمدير الذاكرة (`bee_pmm_bitmap`)، أرشيف
نظام الملفّات وخرائط المفاتيح (`bee_initrd`/`bee_kbd_set1_map`، بيانات جدول في
`.rodata`). حلّل تقرير أميليا أنّ هذه ثاني أكبر رافعة لإطفاء C بعد `عنوان_رمز`.

ص **تملك** تقنيًّا مسار globals (المتغيّر على مستوى الوحدة يصير `GlobalVariable`
حقيقيًّا في `.bss`/`.data`/`.rodata`)، لكن ينقصها الغلاف اللغويّ المستقرّ:

1. **رمز مستقرّ مُصدَّر:** الـglobal اليوم `InternalLinkage` باسم عربيّ خام غير
مستقرّ. النواة تحتاج رمزًا ثابتًا مُصدَّرًا (`ExternalLinkage`) كي:
- يكتبه سياق المقاطعة (أكعاب ISR في C/أسمبلي) بالاسم،
- وتأخذ ص عنوانه عبر `عنوان_رمز("bee_probe_hits")`،
- ويبقى الاسم مطابقًا لعقد ABI المتّفَق عليه.
2. **`@متطاير` معطوبة على التصريح:** العدّادات يكتبها معالج مقاطعة ويقرؤها منطق
الفحص — تلزمها دلالة volatile. السمة موجودة اسميًّا لكنّ علمها يُسقَط ولا يصل
إلى `GlobalVariable::setVolatile`.
3. **`@محزوم` غائبة:** الواصفات الزائفة (نمط `bee_idtr`) وبنى العتاد تحتاج رصًّا
دقيقًا؛ لا كلمة لطلبه.
4. **بيانات مضمَّنة:** لا صياغة لكتلة بايتات ثابتة كبيرة (أرشيف SFA1، خريطة
set-1) برمز مستقرّ في `.rodata`.

حالة استخدام واقعيّة (نهلة، بعد هذا المقترح):

```sad
# عدّاد يكتبه معالج المقاطعة ويقرؤه الفحص — .bss، رمز مُصدَّر، متطاير
@رمز("bee_probe_hits") @متطاير متغير عداد_المسبار = 0

# أرشيف قرص البدء — .rodata، رمز مُصدَّر، بيانات مضمَّنة
@رمز("bee_initrd") ثابت أرشيف = بايتات(0x53، 0x41، 0x44، 0x46، 0x53، 0x31، 0x36)
```

# الشرح التوجيهي (Guide-level explanation)

## `@رمز("اسم")` — رمز رابط مستقرّ مُصدَّر

توجيه يسبق تصريح متغيّر/ثابت على مستوى الوحدة، فيمنح المخزن اسم رمز رابط ثابتًا
بربط خارجيّ (بدل الاسم العربيّ الخام الداخليّ). نظير `دالة خارجية("اسم")` لكن
لجهة **التعريف** (تصدير) لا الاستيراد.

```sad
@رمز("bee_pmm_bitmap") متغير الخريطة_البتية = 0 # رمز عالميّ bee_pmm_bitmap في .bss
```

يصبح الرمز مرئيًّا للرابط، فيستطيع كود C/أسمبلي خارجيّ (أكعاب ISR) الإشارة إليه
`extern`، وتأخذ ص عنوانه عبر `عنوان_رمز("bee_pmm_bitmap")`.

## `@متطاير` — دلالة volatile على المخزن (إصلاح)

يجعل كلّ قراءة/كتابة للمخزن `volatile` (لا يحذفها/يعيد ترتيبها المُحسِّن). مطلوب
لأيّ مخزن يشترك فيه سياق مقاطعة ومنطق عاديّ.

```sad
@رمز("bee_pit_ticks") @متطاير متغير نبضات = 0
```

## `@محزوم` — رصّ (packed)

يزيل الحشو بين الحقول (محاذاة 1)، لبنى العتاد/الواصفات ذات التخطيط الدقيق.

## `بايتات(...)` — بيانات مضمَّنة (كتلة `.rodata`)

حرفيّة كتلة بايتات ثابتة تُصدَر كـ`ConstantDataArray` في `.rodata`. مع `ثابت`
و`@رمز` تعطي جدول بيانات نواة مملوكًا لـص.

```sad
@رمز("bee_kbd_set1_map") ثابت خريطة_المفاتيح = بايتات(0، 27، 49، 50، ...)
متغير أوّل = اقرأ_ذاكرة(عنوان_رمز("bee_kbd_set1_map"))
```

# الشرح المرجعي (Reference-level explanation)

## مصدر الحقيقة (`language-truth/`)

- توجيهات جديدة في `directives.yaml`: `@رمز("اسم")` (وسيط سلسلة) و`@محزوم`.
`@متطاير` موجود (سطر 54) — لا إضافة، بل إصلاح توصيل.
- كلمة/مدمج `بايتات` لحرفيّة البايتات (أو صياغة مصفوفة بايتات ثابتة) في
`builtins`/`keywords`.

## المحلل المعجمي/النحوي (Lexer/Parser)

- `@رمز("اسم")`: توجيه بوسيط سلسلة حرفيّة (نمط `@متطاير` + استخراج سلسلة كـ
`دالة خارجية`).
- `@محزوم`: توجيه بلا وسيط.
- `بايتات(...)`: استدعاء يُحلَّل كقائمة ثوابت رقميّة (0–255).

## الشجرة المجردة (AST)

- `VarDeclStmt` يكتسب حقول: `linkSymbol` (اسم `@رمز`)، `isVolatile` (موصول)،
`isPacked`. (الحقل `isVolatile` موجود في `VariableInfo` لكن لا يُملأ من مسار
`@متطاير` — يُوصَل.)
- عقدة `ByteBlobLiteral` (أو إعادة استخدام تمثيل المصفوفة الثابتة).

## المفسّر

- `@رمز`: لا أثر دلاليّ في المفسّر (لا رموز رابط)؛ المخزن يبقى متغيّرًا عاديًّا.
- `@متطاير`: المفسّر أحاديّ الخيط الدلالة ⇒ لا أثر مرئيّ (يُقبَل ويُتجاهَل).
- `بايتات(...)`: تُمثَّل كمصفوفة أرقام عاديّة في المفسّر.

## المترجم (sadc): SIR / LLVM IR codegen

1. **`@رمز`**: في `emitGlobalVariables` (`classes_vtables_ops.cpp`)، إن كان
`linkSymbol` غير فارغ ⇒ استعمله اسمًا للـ`GlobalVariable` مع
`ExternalLinkage` بدل `InternalLinkage` + الاسم الخام.
2. **`@متطاير`**: أصلِح `statement_advanced.cpp` كي ينقل `isVolatile` إلى
`SIRGlobalVariable`، ثمّ في الإصدار اضبط سمة على المخزن ووسم قراءاته/كتاباته
`setVolatile(true)` (البنية قائمة في `llvm_volatile_ops.cpp`).
3. **`@محزوم`**: مرّر `isPacked=true` إلى `StructType::create` (اليوم مقيَّد
`false` في `llvm_type_mapper_composite.cpp:82`) + `Align(1)`.
4. **`بايتات`**: أصدِر `ConstantDataArray::get(...)` في `.rodata` (البنية قائمة،
مستعملة داخليًّا في `arabic_string_pool.cpp`) كمخزن مسمّى.
5. **القسم الصريح (مؤجَّل/ثانويّ):** البنية `LLVMCustomSections::placeGlobal`
قائمة لكن يتيمة؛ يمكن ربط `@قسم(".name")` بها لاحقًا (خارج نطاق هذا المقترح).

## نظام الأخطاء

- خطأ SEM جديد: `@رمز` بوسيط غير ثابت/فارغ (نظير SEM021 لـ`عنوان_رمز`).
- خطأ SEM: `بايتات` بقيمة خارج [0,255].

## الأدوات

- LSP/الإكمال: التوجيهات الجديدة مولَّدة من `directives.yaml`.

## التوافق الخلفي

توجيهات/صياغة جديدة بأسماء غير مستعملة ⇒ **لا كسر**. إصلاح `@متطاير` يغيّر
سلوكًا كان صامتًا (السمة تُتجاهَل اليوم) إلى فعّال — تحسين لا كسر.

# السلبيات (Drawbacks)

- **توسيع سطح اللغة:** أربع سمات/صيغ جديدة دفعةً. يمكن التدرّج (انظر البدائل).
- **`@رمز` يوسّع الربط:** رمز مُصدَّر يفتح احتمال تصادم أسماء عالميّة — مقبول في
سياق نواة/برنامج واحد، لكنّه مسؤوليّة المستخدم.
- **الثبات المحسوب:** ثابت بقيمة محسوبة (لا حرفيّة) يفقد `isConstant` في LLVM
اليوم (يُكتب عبر `__sad_main`) — قيد قائم لا يحلّه هذا المقترح؛ `بايتات`
الحرفيّة تتفاداه.
- **`@محزوم` و`@متطاير` سهلتا إساءة الاستعمال:** الرصّ يكسر المحاذاة على بعض
المعماريّات؛ محصور بحالات العتاد.

# المبرّرات والبدائل (Rationale and alternatives)

**لماذا `@رمز` توجيهًا؟** يحاكي `دالة خارجية("اسم")` (تصدير رمز مسمّى) وأدنى سطح
تغيير: يعيد استخدام مسار globals القائم (يبدّل الاسم والربط فقط). يتكامل مباشرةً
مع `عنوان_رمز` (3.13): ص تعرّف المخزن وتأخذ عنوانه بالاسم نفسه.

**البدائل:**
- **تصريح مخزن مخصَّص جديد (`مخزن ساكن ...`):** أوسع وأبعد عن صياغة ص القائمة؛
`@رمز متغير` يعيد استخدام `متغير`/`ثابت` المألوفين.
- **التدرّج (تقسيم لـRFCات):** يمكن فصل `@رمز` (الرافعة الأساس) عن `@محزوم`/
`بايتات`. لكنّها متلازمة لإطفاء مخازن النواة (العدّادات تحتاج `@رمز`+`@متطاير`،
الجداول تحتاج `@رمز`+`بايتات`)، فجمعها يخدم هدفًا واحدًا متماسكًا. `@محزوم`
أضعفها ترابطًا ويمكن تأجيله.
- **لا فعل شيء:** تبقى مخازن `.bss`/`.rodata` في C، فيتوقّف إطفاء C عند سقف أعلى
بكثير من الأرضيّة الدائمة (~600 سطر).

# أعمال سابقة (Prior art)

- **C:** `static`/`__attribute__((section))`/`volatile`/`__attribute__((packed))`
+ مُهيّئات مصفوفات — بالضبط ما تحتاجه النواة، وهو ما يُهاجَر منه.
- **Rust:** `static X: T = ...` (رمز مُصدَّر عبر `#[no_mangle]`)، `#[repr(packed)]`،
`#[link_section = "..."]`، `read_volatile`/`write_volatile`، `include_bytes!`
للبيانات المضمَّنة. مقترحنا نظير عربيّ مباشر لهذه المجموعة.
- **Zig:** `export var`، `packed struct`، `linksection`، `@embedFile`.

الدرس: تعريف مخزن ساكن مسمّى/مُصدَّر بسمات (volatile/packed/section) وبيانات
مضمَّنة نمط قياسيّ لبرمجة الأنظمة، بلا مكتبة قياسيّة.

# أسئلة غير محسومة (Unresolved questions)

- **صياغة `بايتات`:** مدمج `بايتات(...)` أم صياغة مصفوفة ثابتة (`ثابت س: بايت[] =
[...]`)؟ يُحسم بالنقاش.
- **`@رمز` على المحلّيّ:** هل يُقبَل فقط على مستوى الوحدة (المنطقيّ)، أم داخل
الدوالّ (statics محلّيّة)؟ المقترح: مستوى الوحدة فقط أوّلًا.
- **القسم الصريح `@قسم(".name")`:** خارج نطاق هذا المقترح (البنية يتيمة)؛ يُبنى
لاحقًا فوقه.
- **`@محزوم`:** ضمن هذا المقترح أم يُفصَل؟ (أضعفها ترابطًا بإطفاء المخازن.)
- **الثبات المحسوب الحقيقيّ:** خارج النطاق (قيد `__sad_main` قائم).

# إمكانات مستقبلية (Future possibilities)

- **`@قسم(".name")`**: ربط الصياغة بالبنية القائمة `LLVMCustomSections` لوضع
مخازن في أقسام مخصَّصة (نمط `.multiboot`/`.page_tables`).
- **statics محلّيّة** داخل الدوالّ (رمز مستقرّ لكن نطاق معجميّ محلّيّ).
- **`@محاذاة(n)`**: ضبط محاذاة صريح للمخزن.
- **تهيئة ثابتة محسوبة**: نموذج تهيئة ثابتة حقيقيّة يتجاوز قيد `__sad_main`.
Loading