Для тех, кто не следит за POJ (Pascal на JVM) — это компилятор, преобразующий подмножество из Pascal в JASM (Java Assembly), чтобы мы могли использовать JVM в качестве среды выполнения.
В последнем посте мы реализовали поддержку функций Pascal.
В этом посте мы поговорим о крутых вещах? Не так уж и лол. На этот раз мы поговорим только об ошибках :-)
Поскольку мы компилируем для JVM, необходимо подробно описать работу различных точек этой невероятной виртуальной машины. Поэтому в разное время я подробно описываю внутреннее функционирование JVM, а также некоторые ее инструкции (коды операций).
Когда я реализовал объявление переменной, я не обратил внимания на то, что в JVM первой переменной в основной функции является args, массив, содержащий аргументы, передаваемые в программу. Поэтому в этом PR я неявно резервирую первую позицию для 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 } }
Чтобы попытаться определить проблему, я создал программу на Java, эквивалентную приведенной выше программе на Паскале:
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