• Nenhum resultado encontrado

minor_version e major_version

No documento Máquina virtual Java em FPGA (páginas 47-64)

3.3 Máquina Virtual Java

3.3.1 Ficheiro class

3.3.1.2 minor_version e major_version

Estes valores são os números de versão menor e maior do ficheiro class, e juntos determinam a versão desse ficheiro.

3.3.1.3 constant_pool_counte constant_pool[]

O valor constant_pool_count indica o número de entradas presentes na ta- bela constant_pool mais um. O índice de uma entrada da constant_pool, à exceção das constantes do tipo long e double3, só é considerado válido se for maior que zero e menor que o valor de constant_pool_count, .

A constant_pool é uma tabela de estruturas que representam várias constan- tes de strings, classes, interfaces, campos, entre outros. As instruções da máquina virtual Java não são baseadas no layout de classes, instâncias de classes, inter- faces ou arrays. Em vez disso, as instruções referem-se a informação simbólica presente nesta tabela. Cada entrada da constant_pool é indicada pelo seu primeiro byte, ao qual se dá o nome de tag, que também fornece informação sobre o tipo de constante presente nessa entrada. A estrutura representativa da constant_poolé a seguinte:

cp_info { u1 tag;

u1 info[]; }

O conteúdo do parâmetro info varia de acordo com o valor da tag. A seguir a cada byte indicativo da tag seguem-se dois ou mais bytes de informação sobre o tipo de constante correspondente a essa tag. A tabela 3.1 ilustra os tipos de constantes que podem estar presentes na constant_pool, os valores que a tag pode assumir conforme o tipo de constante e o número de bytes de informação que cada constante terá. A descrição de cada constante é realizada a seguir.

Tabela 3.1: Tipos de constantes presentes na constant_pool.

Tipo de constante Tag Bytes de informação CONSTANT_Utf8 1 2 + x CONSTANT_Integer 3 4 CONSTANT_Float 4 4 CONSTANT_Long 5 4 + 4 CONSTANT_Double 6 4 + 4 CONSTANT_Class 7 2 CONSTANT_String 8 2 CONSTANT_Fieldref 9 2 + 2 CONSTANT_Methodref 10 2 + 2 CONSTANT_InterfaceMethodref 11 2 + 2 CONSTANT_NameAndType 12 2 + 2

x na tabela indica um número variável de bytes.

- CONSTANT_Utf8 - este tipo é usado para representar valores constantes de strings, ou seja, indicam o nome de métodos, nomes de variáveis os bytecodes e Strings. As strings UTF-8 estão codificadas de forma a que sequências de caracteres que contenham caracteres ASCII possam ser representadas usando apenas um byte por caracter. No entanto, podem ser representa- dos caracteres até 16 bits. Este tipo de constante segue a seguinte estrutura:

CONSTANT_Utf8_info { u1 tag;

u2 length;

O parâmetro length indica o número de bytes no array bytes (não o ta- manho da string resultante), que contém a string codificada.

- CONSTANT_Integer e CONSTANT_Float - Estes dois tipos de constan- tes seguem uma estrutura idêntica, estando apenas aqui representada a CONSTANT_Integer:

CONSTANT_Integer_info { u1 tag;

u4 bytes; }

Na CONSTANT_Integer, bytes indica o valor de uma constante do tipo int. Os bytes que representam esse valor estão guardados por ordem big- -endian (byte mais significativo primeiro). Na CONSTANT_Float, o mesmo parâmetro representa o valor de uma constante do tipo float no formato IEEE 754 floating-point single. Os bytes de representação desse valor também estão guardados por ordem big-endian.

- CONSTANT_Long e CONSTANT_Double - representam constantes com ta- manho de 8 bytes. Mais uma vez, estes dois tipos de constantes seguem uma estrutura igual, de modo que só está aqui ilustrada uma delas:

CONSTANT_Long_info { u1 tag;

u4 high_bytes; u4 low_bytes; }

Os parâmetros high_bytes e low_bytes na CONSTANT_Long represen- tam juntos o valor de uma constante do tipo long, seguindo a seguinte fórmula ((long)high_bytes < < 32 + low_bytes, estando também orga- nizados por ordem big-endian. Já na CONSTANT_Double os dois parâmetros indicam um valor do tipo double no formato IEEE 754 floating-point double. Os bytes de cada parâmetro também seguem uma ordem big-endian. Todas as constantes que possuem 8 bytes de informação ocupam duas entradas

na tabela constant_pool do ficheiro class. Se uma destas constantes é o item do índice n da constant_pool, então o próximo item da tabela está localizado no índice n+2.

- CONSTANT_Class - usada para representar uma classe ou interface, tem a seguinte estrutura:

CONSTANT_Class_info { u1 tag;

u2 name_index; }

O item name_index deve ser um índice válido da tabela constant_pool. O conteúdo da entrada correspondente a esse índice deve ser uma estru- tura do tipo CONSTANT_Utf8_info, representando o nome válido de uma classe ou interface.

- CONSTANT_String - representa objetos constantes do tipo String. A sua estrutura é:

CONSTANT_String_info { u1 tag;

u2 string_index; }

O item string_index deve ser um índice da tabela constant_pool vá- lido, cuja entrada deve ser uma estrutura do tipo CONSTANT_Utf8_info representando a sequência de caracteres pela qual o objeto String está para ser inicializado.

- CONSTANT_Fieldref, CONSTANT_InterfaceMethodref e CONSTANT_- Methodref- tal como os nomes indicam, representam campos, métodos de interfaces e métodos, seguindo todas uma estrutura idêntica (aqui está ape- nas ilustrada uma delas):

CONSTANT_Fieldref_info { u1 tag;

u2 class_index;

O campo class_index deve ser um índice da tabela constant_pool válido. A entrada dessa tabela, indicada pelo índice anterior, deve ser uma estrutura do tipo CONSTANT_Class_info, que representa uma classe ou interface que contém a declaração do campo ou método. O class_index deve ser, de acordo com o tipo de constante:

1. Do tipo classe para a estrutura CONSTANT_Methodref_info; 2. Do tipo interface para CONSTANT_InterfaceMethodref_info; 3. Do tipo classe ou interface para CONSTANT_Fieldref_info;

O item name_and_type_index deve indicar um índice válido da tabela constant_pool, cuja entrada deve corresponder a uma estrutura do tipo CONSTANT_NameAndType_info. Esta entrada indica o nome e o descrip- tor4 do campo ou método. O descriptor deve ser um field descriptor, no caso de ser constante do tipo CONSTANT_Fieldref_info, senão deve ser um method descriptor. Se o nome do método presente numa estrutura do tipo CONSTANT_Methodref_info começar pelo símbolo ’<’, então o nome do método será <init>, que representa a instância do método de inicialização. Não deve retornar nenhum valor.

- CONSTANT_NameAndType - usada para representar um campo ou um mé- todo, sem indicar a qual tipo de classe ou interface pertence. A sua estrutura é apresentada a seguir.

CONSTANT_NameAndType_info { u1 tag;

u2 name_index;

u2 descriptor_index; }

O item name_index deve ser um índice válido da tabela constant_pool. A entrada correspondente a esse índice deve ser uma estrutura do tipo 4Um descriptor é uma string que representa o tipo de método ou campo, estando no ficheiro

classsob a forma de uma string do tipo UTF-8. Um field descriptor indica o tipo de uma classe, instância ou variável local. Um method descriptor representa os parâmetros que um método aceita e o valor que ele retorna.

CONSTANT_Utf8_info, que representa tanto o nome de um campo como de um método, guardado como um simple name, isto é, como um identifica- dor único da linguagem de programação Java5 ou como nome do método especial <init>.

O parâmetro descriptor_index deve ser um índice válido da tabela constant_pool, cuja entrada correspondente a esse índice deve ser uma estrutura do tipo CONSTANT_Utf8_info, representando um field descriptor ou method descriptor válido.

3.3.1.4 access_flags

Este valor é uma máscara de flags usada para indicar permissões de acesso, assim como propriedades de uma classe ou interface. A interpretação de cada flag está descrita na tabela 3.2.

Tabela 3.2: Interpretação das access_flags presentes no ficheiro class.

Nome da flag Valor Interpretação

ACC_PUBLIC 0x0001 É declarada public, pode ser acedida a partir do exterior do seu package ACC_FINAL 0x0010 É declarada final, não são permitidas sub-classes

ACC_SUPER 0x0020 Lida com os métodos de super-classes invocados pela instrução invokespecial ACC_INTERFACE 0x0200 O ficheiro class define uma interface, e não uma classe

ACC_ABSTRACT 0x0400 É declarada abstract, pode não estar instanciada

3.3.1.5 this_classe super_class

O item this_class deve ser um índice válido da tabela constant_pool. A en- trada correspondente deve ser uma estrutura do tipo CONSTANT_Class_info, que representa a classe ou interface definida pelo ficheiro class em questão.

5Este identificador é o nome pelo qual está identificada uma entidade num programa Java,

Para uma classe, o item super_class deve corresponder a um índice da tabela constant_pool válido. Se este valor não for igual a 0, a entrada correspon- dente ao índice deve ser uma estrutura do tipo CONSTANT_Class_info, que indica a super-classe direta da classe definida pelo ficheiro class. Nem a super- -classe direta nem alguma das suas super-classes devem ser a classe final. Se o valor de super_class for igual a 0, então o ficheiro class especifica a classe Object, a única classe ou interface que não possui uma super-classe direta. Para uma interface, o valor de super_class deve ser um índice válido da tabela constant_pool, cuja entrada representa a classe Object.

3.3.1.6 interfaces_counte interfaces[]

O valor de interfaces_count é o número de super-interfaces diretas da classe ou interface. Cada valor do array interfaces deve ser um índice válido da ta- bela constant_pool. A correspondente entrada da constant_pool a cada valor de interfaces[i], onde 0 ≤ i < interfaces_count, deve ser uma es- trutura do tipo CONSTANT_Class_info, representando uma interface que é a super-interface direta da classe ou interface.

3.3.1.7 fields_counte fields[]

O item fields_count indica o número de estruturas do tipo field_info pre- sente no array ou tabela fields[]. A estrutura field_info representa todos os campos, tanto variáveis de classes como variáveis de instâncias, declarados pela classe ou interface.

field_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }

Cada valor presente na tabela fields, isto é cada campo, deve ser uma estru- tura field_info, que fornece a descrição completa de um campo nesta classe

ou interface. A tabela fields inclui apenas os campos declarados nesta classe ou interface, não inclui campos que foram herdados de super-classes ou super- interfaces. O nome de um campo e o field descriptor devem ser únicos, não de- vendo haver dois ou mais campos com o mesmo nome e descriptor dentro da mesma classe. Os parâmetros de cada entrada desta tabela definem-se da se- guinte forma:

- access_flags - este valor é uma máscara de flags usada para indicar per- missões de acesso e propriedades de um campo. Cada campo pode ser de- clarado como public, private, protected, static, final, volatile e transient.

- name_index e descriptor_index - em ambos os casos, o valor de cada item deve ser um índice válido da tabela constant_pool, cuja entrada correspondente deve ser uma estrutura do tipo CONSTANT_Utf8_info. No caso de name_index a estrutura representa um nome válido para o campo, guardado como um simple name. Para o descriptor_index, in- dica um field descriptor válido.

- attributes_count - indica o número de atributos adicionais de um cam- po.

- attributes[] - cada valor da tabela attributes deve ser uma estru- tura do tipo attribute, descrita mais à frente neste documento. Um campo pode ter um número qualquer de atributos associados. Segundo a The Java Virtual Machine Specification, os atributos que podem aparecer na tabela attributes da estrutura field_info são: ConstantValue, Synthetice Deprecated. A implementação da máquina virtual deve ser capaz de reconhecer e ler corretamente atributos do tipo ConstantValue presentes na tabela attributes da estrutura field_info, devendo igno- rar todos os atributos presentes que não reconhece. Estes não estão defini- dos e, como tal, não podem afetar a semântica do ficheiro class, podendo apenas fornecer informação adicional.

3.3.1.8 methods_counte methods[]

O valor de methods_count representa o número de estruturas method_info presentes na tabela methods. Cada entrada da dessa tabela é um método, de- vendo portanto ser uma estrutura do tipo method_info. Define-se assim todos os métodos declarados na classe ou interface, incluindo instâncias de métodos, métodos de classes static, métodos de inicialização de instâncias e qualquer outro método de inicialização de classe ou interface. A tabela methods não in- clui métodos que tenham sido herdados de super-classes ou super-interfaces. A estrutura method_info é definida da seguinte forma:

method_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count]; }

- access_flags - é uma máscara de flags utilizada para indicar permissões de acesso e propriedades de um método. Cada método pode ser declarado como public, private, protected, static, final, synchronized, native, abstract e strictfp.

- name_index e descriptor_index - os valores destes dois parâmetros devem ser índices válidos da tabela constant_pool, aos quais correspon- dem entradas que devem ser estruturas do tipo CONSTANT_Utf8_info. Para o name_index esta estrutura representa um dos special names de mé- todos, nomeadamente o <init> ou <clinit>6, ou um nome válido de um método da linguagem Java, guardado como um simple name. No caso do descriptor_index, deve estar representado um method descriptor válido. 6Ao nível da máquina virtual Java, cada construtor aparece sob a forma de uma instância do

método de inicialização, que tem o special name <init>. Este método só pode ser invocado den- tro da máquina virtual através da instrução invokespecial e apenas em instâncias de classes que ainda não foram inicializadas. Uma classe ou interface tem no máximo um método de inicia- lização de classe ou interface, com o special name <clinit>, que é inicializado invocando esse método. A invocação deste método é implícita dentro da máquina virtual Java, nunca sendo di- retamente invocado por uma das instruções, mas apenas indiretamente como parte do processo de inicialização da classe.

- attributes_count - indica o número de atributos adicionais de um mé- todo.

- attributes[] - cada entrada da tabela attributes deve ser uma es- trutura do tipo attribute. Um método pode ter um número variado de atributos associados. Os atributos que, de acordo com a The Java Vir- tual Machine Specification, podem aparecer na tabela attributes da estru- tura method_info são os atributos: Code, Exceptions, Synthetic e Deprecated. A implementação da máquina virtual Java deve ser capaz de reconhecer e ler correctamente os atributos Code e Exceptions presentes na tabela attributes da estrutura method_info, sendo ignorados todos os atributos presentes que não reconhece (Synthetic e Deprecated). Es- tes não estão definidos na The Java Virtual Machine Specification e, como tal, não podem afetar a semântica do ficheiro class, podendo apenas fornecer informação adicional, tal como na estrutura fields_info.

3.3.1.9 attributes_counte attributes[]

O item attributes_count indica a quantidade de atributos presentes na tabela attributesde uma classe. A cada valor da tabela referida deve corresponder uma estrutura do tipo attribute_info, que tem a seguinte definição:

attribute_info {

u2 attribute_name_index; u4 attribute_length;

u1 info[attribute_length]; }

Os únicos atributos que podem estar presentes, novamente de acordo com a The Java Virtual Machine Specification, na tabela attributes de uma estrutura ClassFile são: o atributo SourceFile e o atributo Deprecated. À seme- lhança de outras estruturas, a implementação da máquina virtual Java deve igno- rar todos os atributos presentes na tabela attributes da estrutura ClassFile que não reconhecer. Estes atributos não têm permissão para afetar a semântica do ficheiro class mas apenas para fornecer informação adicional.

Os atributos estão presentes no ficheiro class nas suas estruturas ClassFile, field_info, method_info e Code_attribute. Para todos os atributos, o

parâmetro attribute_name_index deve ser um índice de 16-bits válido da tabela constant_pool da classe, e a entrada correspondente deve ser uma es- trutura do tipo CONSTANT_Utf8_info. Esta estrutura contém a string que re- presenta o nome do atributo. O valor de attribute_length indica o tamanho da consequente informação em bytes, não incluindo os seis bytes iniciais relativos aos dois primeiros parâmetros desta estrutura.

Alguns atributos estão pré-definidos como parte da The Java Virtual Machine Spe- cification [19], e os seus nomes estão reservados nas estruturas do ficheiro class em que aparecem, sendo eles os atributos:

- SourceFile; - ConstantValue; - Code; - Exceptions; - Synthetic; - InnerClasses; - LineNumberTable; - LocalVariableTable; - Deprecated.

Os atributos InnerClasses e Synthetic devem ser reconhecidos e correta- mente lidos pelo reader do ficheiro class de modo a que sejam implementadas corretamente as bibliotecas de classes das plataformas Java e Java 2. O uso dos restantes atributos pré-definidos (exceto os atributos Code, ConstantValue e Exceptions) é opcional, podendo o reader do ficheiro class usar a informação neles contidos ou simplesmente ignorá-los. Segue-se uma breve descrição dos vários atributos7.

7Os parâmetros attribute_name_index e attribute_length são iguais para todos os

atributos e já foram descritos, de modo que não se repetirá a descrição deles juntamente com a dos vários atributos.

- SourceFile - não pode existir mais do que um atributo SourceFile num ficheiro class, uma vez que o parâmetro sourcefile_index da sua es- trutura é um índice válido da tabela constant_pool, cuja entrada é uma estrutura do tipo CONSTANT_Utf8_info, que indica o nome do ficheiro fonte a partir do qual foi compilado o ficheiro class.

SourceFile_attribute { u2 attribute_name_index; u4 attribute_length; u2 sourcefile_index; }

- ConstantValue - representa o valor de um campo constante que deve ser static. A sua estrutura é:

ConstantValue_attribute { u2 attribute_name_index; u4 attribute_length;

u2 constantvalue_index; }

Sendo assim, o valor de constantvalue_index deve ser um índice vá- lido da tabela constant_pool, cuja entrada correspondente oferece o va- lor representado por este atributo, e deve ser do tipo apropriado ao tipo de campo em questão, como está indicado na tabela 3.3.

Tabela 3.3: Tipos de campos e correspondentes entradas da constant_pool.

Tipo de campo Tipo de entrada int, short, char, byte, boolean CONSTANT_Integer

float CONSTANT_Float long CONSTANT_Long double CONSTANT_Double String CONSTANT_String

- Code - contém as instruções da máquina virtual Java e informação auxiliar de um método. Por esta razão, todas as implementações da máquina virtual Java devem ser capazes de detetar o atributo Code. Se o método for native ou abstract, a sua estrutura method_info não tem o atributo Code. No caso contrário, possui exatamente um atributo desta natureza.

Code_attribute { u2 attribute_name_index; u4 attribute_length; u2 max_stack; u2 max_locals; u4 code_length; u1 code[code_length]; u2 exception_table_length; { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count]; }

• max_stack - é o valor que indica a profundidade máxima da operand stack do método a qualquer momento da sua execução.

• max_locals - fornece o número de variáveis locais no array de va- riáveis locais alocado aquando da invocação do método, incluindo as variáveis locais usadas para passar parâmetros ao método durante a sua invocação.

• code_length e code[] - o primeiro parâmetro dá informação sobre o número de bytes presentes no array code do método, e o seu valor deve ser sempre maior que zero. O array code não deve estar vazio, pois fornece os bytecodes da máquina virtual Java que implementam o método.

• exception_table_length - o item exception_table_length fornece o valor do número de entradas da tabela exception_table.

• exception_table - Cada entrada do array exception_table des- creve um exception handler no array code e tem quatro items, sendo eles start_pc, end_pc, handler_pc e catch_type. Os valores dos dois primeiros items indicam os limites do array code para os quais o exception handler está ativo, enquanto handler_pc indica o início do exception handler. O parâmetro catch_type deve ser um índice vá- lido da tabela constant_pool, cuja entrada deve ser uma estrutura do tipo CONSTANT_Class_info representando uma classe de excep- tions que o exception handler está projetado para apanhar. Esta deve ser a classe Throwable ou uma das suas subclasses.

• attributes_count e attributes[] - à semelhança de outras es- truturas que também têm atributos, o item attributes_count in- dica o número de atributos do atributo Code. Cada valor da tabela attributesdeve ser uma estrutura attributes_info. O atributo

No documento Máquina virtual Java em FPGA (páginas 47-64)

Documentos relacionados