Para quem não está acompanhando o POJ (Pascal on the JVM) é um compilador que transforma um subset de Pascal para JASM (Java Assembly) de forma que possamos usar a JVM como ambiente de execução.
Na última postagem implementamos o suporte às functions do Pascal.
Nesta publicação vamos falar sobre coisas bacanas? Nem tanto rsrsrs. Desta vez só vamos falar de bugs mesmo :-)
Como estamos compilando para a JVM faz-se necessário detalhar o funcionamento de vários pontos desta incrível máquina virtual. Com isso, em vários momentos eu detalho o funcionamento interno da JVM bem como algumas das suas instruções (opcodes).
Quando implementei a declaração de variáveis eu não atentei para o fato de que, na JVM, a primeira variável na função principal é o args, um array que contém os argumentos passados para o programa. Com isso neste PR eu reservo a primeira posição implicitamente para args.
Como os programas em Pascal de teste continham apenas variáveis globais eu não havia notado um erro grave na geração do JASM. No momento em que criei programas que continham variáveis globais e locais percebi que algo de errado não estava certo rsrsrs.
A partir do programa Pascal abaixo:
program global_var_declaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
O POJ gerava o seguinte 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 } }
Para tentar identificar o problema criei um programa em Java equivalente ao programa em Pascal acima:
public class GlobalVarDeclaration { public static int globalVar; public static void main(String[] args) { globalVar = 123; System.out.println(globalVar); } }
Quando desassemblei o class eu obtive o seguinte assembly:
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: }
Neste momento percebi a declaração "public static globalVar I" (linha 2) e as instruções putstatic (linha 6) e getstatic (linha 9). O esperado eram as instruções astore e istore utilizadas pelo POJ até o momento. Lendo a documentação da JVM percebi que o POJ estava declarando as variáveis globais como se fossem variáveis locais de uma função para a JVM :-D
Enfim, até o momento o POJ estava usando (erroneamente) os opcodes aload/iload/astore/istore para variáveis globais, mas o correto seria declarar as variáveis como públicas (como na linha 2) e utilizar o getstatic/putstatic.
Com isso o código foi refatorado aqui para que a tabela de símbolos consiga lidar com declarações locais e globais. E aqui o código foi refatorado para que a tabela de símbolos consiga gerar as instruções corretas para as variáveis locais e globais.
A geração de código JASM foi alterada aqui para lidar com a nova tabela de símbolos bem como limpar as declarações locais após o término de uma função ou procedimento.
Com isso, a partir do programa Pascal abaixo:
program GlobalVarDeclaration; var globalvar : integer; begin globalvar := 123; write (globalvar); end.
O POJ passou a gerar corretamente o seguinte 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 } }
Na próxima publicação vamos falar sobre contextos e sentenças aninhadas.
O repositório com o código completo do projeto e a sua documentação está aqui.
Isenção de responsabilidade: Todos os recursos fornecidos são parcialmente provenientes da Internet. Se houver qualquer violação de seus direitos autorais ou outros direitos e interesses, explique os motivos detalhados e forneça prova de direitos autorais ou direitos e interesses e envie-a para o e-mail: [email protected]. Nós cuidaremos disso para você o mais rápido possível.
Copyright© 2022 湘ICP备2022001581号-3