بالنسبة لأولئك الذين لا يتابعون POJ ( Pascal على JVM ) هو مترجم يحول مجموعة فرعية من Pascal إلى JASM (Java Assembly) حتى نتمكن من استخدام JVM كبيئة تنفيذ.
في المنشور الأخير قمنا بتنفيذ دعم لوظائف في Pascal.
في هذا المنشور، هل سنتحدث عن أشياء رائعة؟ ليس كثيرا لول. هذه المرة سنتحدث فقط عن الأخطاء :-)
أثناء قيامنا بالتجميع لـ JVM، من الضروري تفصيل عمل النقاط المختلفة لهذا الجهاز الظاهري المذهل. لذلك، في أوقات مختلفة، قمت بتفصيل الأداء الداخلي لـ JVM بالإضافة إلى بعض تعليماته (رموز التشغيل).
عندما قمت بتنفيذ إعلان المتغير، لم انتبه إلى حقيقة أن المتغير الأول في الوظيفة الرئيسية في JVM هو args، وهو مصفوفة تحتوي على الوسائط التي تم تمريرها إلى البرنامج. لذلك في هذا العلاقات العامة أحتفظ بالمركز الأول ضمنيًا للوسائط.
بما أن برامج باسكال الاختبارية تحتوي فقط على متغيرات عامة، لم ألاحظ خطأً جسيمًا في جيل JASM. في اللحظة التي قمت فيها بإنشاء برامج تحتوي على متغيرات عالمية ومحلية، أدركت أن شيئًا ما لم يكن صحيحًا.
من برنامج باسكال أدناه:
program global_var_declaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
أنشأ POJ JASM التالي:
// Code generated by POJ 0.1 public class global_var_declaration { public static main([java/lang/String)V { ;; globalvar := 123; bipush 123 istore 1 ;; write (globalvar); getstatic java/lang/System.out java/io/PrintStream iload 1 invokevirtual java/io/PrintStream.print(I)V return } }
لمحاولة التعرف على المشكلة، قمت بإنشاء برنامج جافا يعادل برنامج باسكال أعلاه:
public class GlobalVarDeclaration { public static int globalVar; public static void main(String[] args) { globalVar = 123; System.out.println(globalVar); } }
عندما قمت بتفكيك الفصل حصلت على التجميع التالي:
1: public class GlobalVarDeclaration { 2: public static globalVar I 3: 4: public static main([java/lang/String)V { 5: bipush 123 6: putstatic GlobalVarDeclaration.globalVar I 7: 8: getstatic java/lang/System.out java/io/PrintStream 9: getstatic GlobalVarDeclaration.globalVar I 10: invokevirtual java/io/PrintStream.println(I)V 11: 12: return 13: } 14: }
في هذه المرحلة لاحظت الإعلان " public static globalVar I" (السطر 2) والتعليمات putstatic (السطر 6) و getstatic (السطر 9) . ما كان متوقعًا هو التعليمات astore وistore التي يستخدمها POJ حتى الآن. من خلال قراءة وثائق JVM، أدركت أن POJ كان يعلن عن المتغيرات العامة كما لو كانت متغيرات محلية لوظيفة JVM :-D
على أي حال، حتى الآن كان POJ (بشكل خاطئ) يستخدم رموز التشغيل aload/iload/astore/ Istore للمتغيرات العامة، ولكن الخيار الصحيح هو إعلان المتغيرات عامة (كما في السطر 2) واستخدام getstatic/putstatic.
ونتيجة لذلك، تمت إعادة هيكلة التعليمات البرمجية هنا حتى يتمكن جدول الرموز من التعامل مع الإعلانات المحلية والعالمية. وهنا تمت إعادة صياغة الكود بحيث يتمكن جدول الرموز من إنشاء التعليمات الصحيحة للمتغيرات المحلية والعالمية.
تم تغيير إنشاء كود JASM هنا للتعامل مع جدول الرموز الجديد بالإضافة إلى تنظيف الإعلانات المحلية بعد انتهاء وظيفة أو إجراء.
وبهذا من برنامج باسكال أدناه:
program GlobalVarDeclaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
يقوم POJ الآن بإنشاء JASM التالي بشكل صحيح:
// Code generated by POJ 0.1 public class global_var_declaration { public static globalvar I public static main([java/lang/String)V { ;; globalvar := 123; bipush 123 putstatic global_var_declaration.globalvar I ;; write (globalvar); getstatic java/lang/System.out java/io/PrintStream getstatic global_var_declaration.globalvar I invokevirtual java/io/PrintStream.print(I)V return } }
في المقالة القادمة سنتحدث عن السياقات والجمل المتداخلة.
المستودع الذي يحتوي على الكود والوثائق الكاملة للمشروع موجود هنا.
تنصل: جميع الموارد المقدمة هي جزئيًا من الإنترنت. إذا كان هناك أي انتهاك لحقوق الطبع والنشر الخاصة بك أو الحقوق والمصالح الأخرى، فيرجى توضيح الأسباب التفصيلية وتقديم دليل على حقوق الطبع والنشر أو الحقوق والمصالح ثم إرسالها إلى البريد الإلكتروني: [email protected]. سوف نتعامل مع الأمر لك في أقرب وقت ممكن.
Copyright© 2022 湘ICP备2022001581号-3